From e40ca9938647c8ad6922f8006bbf35b90229608a 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 | 84 +++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 72 insertions(+), 12 deletions(-) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index c08c70f..541b115 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 */ @@ -1364,7 +1406,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: @@ -1411,13 +1454,19 @@ _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); - _dbus_atomic_inc (&connection->refcount); + old_refcount = _dbus_atomic_inc (&connection->refcount); + _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, + "ref_unlocked"); + /* unused if not verbose */ + (void) old_refcount; return connection; } @@ -1431,15 +1480,18 @@ _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); - + _dbus_assert (connection != NULL); - last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); + old_refcount = _dbus_atomic_dec (&connection->refcount); + + _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, + "unref_unlocked"); - if (last_unref) + if (old_refcount == 1) _dbus_connection_last_unref (connection); } @@ -2640,10 +2692,15 @@ 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); - - _dbus_atomic_inc (&connection->refcount); + old_refcount = _dbus_atomic_inc (&connection->refcount); + _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, + "ref"); + /* unused if not verbose */ + (void) old_refcount; return connection; } @@ -2781,14 +2838,17 @@ _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); - last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); + old_refcount = _dbus_atomic_dec (&connection->refcount); + + _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, + "unref"); - if (last_unref) + if (old_refcount == 1) { #ifndef DBUS_DISABLE_CHECKS if (_dbus_transport_get_is_connected (connection->transport)) -- 1.7.5.4