From 52592769b93a48797d7d92dc2ad71f82cb8cc730 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 13 May 2011 11:44:25 +0100 Subject: [PATCH 7/7] DBusConnection: optionally trace refs/unrefs --- dbus/dbus-connection.c | 99 +++++++++++++++++++++++++++++++++++++---------- 1 files changed, 78 insertions(+), 21 deletions(-) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index d212000..ca847aa 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -43,6 +43,7 @@ #include "dbus-threads-internal.h" #include "dbus-bus.h" #include "dbus-marshal-basic.h" +#include "dbus-valgrind-internal.h" #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -206,6 +207,47 @@ * @{ */ +#ifdef DBUS_ENABLE_VERBOSE_MODE +static void +_dbus_connection_trace_ref (DBusConnection *connection, + int old_refcount, + int new_refcount, + const char *why) +{ + static int enabled = -1; + + if (enabled < 0) + { + const char *s = _dbus_getenv ("DBUS_CONNECTION_TRACE"); + + enabled = FALSE; + + if (s && *s) + { + if (*s == '0') + enabled = FALSE; + else if (*s == '1') + enabled = TRUE; + else + _dbus_warn ("DBUS_CONNECTION_TRACE should be 0 or 1 if set, " + "not '%s'", s); + } + } + + if (enabled) + { + if (RUNNING_ON_VALGRIND) + VALGRIND_PRINTF_BACKTRACE ("DBusConnection %p %d -> %d refs (%s)", + connection, old_refcount, new_refcount, why); + else + _dbus_verbose ("DBusConnection %p %d -> %d refs (%s)", + connection, old_refcount, new_refcount, why); + } +} +#else +#define _dbus_connection_trace_ref(c,o,n,w) do {} while (0) +#endif + /** * Internal struct representing a message filter function */ @@ -1354,7 +1396,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport) _dbus_transport_ref (transport); CONNECTION_UNLOCK (connection); - + + _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport"); return connection; error: @@ -1401,19 +1444,27 @@ _dbus_connection_new_for_transport (DBusTransport *transport) */ DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection) -{ +{ + dbus_int32_t old_refcount; + _dbus_assert (connection != NULL); _dbus_assert (connection->generation == _dbus_current_generation); HAVE_LOCK_CHECK (connection); #ifdef DBUS_HAVE_ATOMIC_INT - _dbus_atomic_inc (&connection->refcount); + old_refcount = _dbus_atomic_inc (&connection->refcount); #else _dbus_assert (connection->refcount.value > 0); + old_refcount = connection->refcount.value; connection->refcount.value += 1; #endif + _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, + "ref_unlocked"); + /* might be unused if not verbose */ + (void) old_refcount; + return connection; } @@ -1426,7 +1477,7 @@ _dbus_connection_ref_unlocked (DBusConnection *connection) void _dbus_connection_unref_unlocked (DBusConnection *connection) { - dbus_bool_t last_unref; + dbus_int32_t old_refcount; HAVE_LOCK_CHECK (connection); @@ -1437,18 +1488,18 @@ _dbus_connection_unref_unlocked (DBusConnection *connection) */ #ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); + old_refcount = _dbus_atomic_dec (&connection->refcount); #else _dbus_assert (connection->refcount.value > 0); + old_refcount = connection->refcount.value; connection->refcount.value -= 1; - last_unref = (connection->refcount.value == 0); -#if 0 - printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value); -#endif #endif - - if (last_unref) + + _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, + "unref_unlocked"); + + if (old_refcount == 1) _dbus_connection_last_unref (connection); } @@ -2637,6 +2688,8 @@ dbus_connection_open_private (const char *address, DBusConnection * dbus_connection_ref (DBusConnection *connection) { + dbus_int32_t old_refcount; + _dbus_return_val_if_fail (connection != NULL, NULL); _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL); @@ -2650,15 +2703,20 @@ dbus_connection_ref (DBusConnection *connection) */ #if 1 - _dbus_atomic_inc (&connection->refcount); + old_refcount = _dbus_atomic_inc (&connection->refcount); #else CONNECTION_LOCK (connection); _dbus_assert (connection->refcount.value > 0); + old_refcount = connection->refcount.value; connection->refcount.value += 1; CONNECTION_UNLOCK (connection); #endif + _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, + "ref"); + (void) old_refcount; + return connection; } @@ -2790,7 +2848,7 @@ _dbus_connection_last_unref (DBusConnection *connection) void dbus_connection_unref (DBusConnection *connection) { - dbus_bool_t last_unref; + dbus_int32_t old_refcount; _dbus_return_if_fail (connection != NULL); _dbus_return_if_fail (connection->generation == _dbus_current_generation); @@ -2805,23 +2863,22 @@ dbus_connection_unref (DBusConnection *connection) */ #if 1 - last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); + old_refcount = _dbus_atomic_dec (&connection->refcount); #else CONNECTION_LOCK (connection); _dbus_assert (connection->refcount.value > 0); + old_refcount = connection->refcount.value; connection->refcount.value -= 1; - last_unref = (connection->refcount.value == 0); -#if 0 - printf ("unref() connection %p count = %d\n", connection, connection->refcount.value); -#endif - CONNECTION_UNLOCK (connection); #endif - - if (last_unref) + + _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, + "unref"); + + if (old_refcount == 1) { #ifndef DBUS_DISABLE_CHECKS if (_dbus_transport_get_is_connected (connection->transport)) -- 1.7.5.1