From 38dfa59855e3fe116b0c7e99ec9b725598a3d7f3 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 13 May 2011 11:38:28 +0100 Subject: [PATCH 6/7] DBusServer: optionally trace refs, unrefs --- dbus/dbus-server-debug-pipe.c | 3 +- dbus/dbus-server-protected.h | 9 ++++ dbus/dbus-server-socket.c | 1 + dbus/dbus-server.c | 90 ++++++++++++++++++++++++++++++++++------- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c index e18cad7..419db5c 100644 --- a/dbus/dbus-server-debug-pipe.c +++ b/dbus/dbus-server-debug-pipe.c @@ -177,7 +177,8 @@ _dbus_server_debug_pipe_new (const char *server_name, _dbus_string_free (&address); /* server keeps the pipe hash ref */ - + + _dbus_server_trace_ref (&debug_server->base, 0, 1, "debug_pipe_new"); return (DBusServer *)debug_server; nomem_4: diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h index 31976e3..3500f0f 100644 --- a/dbus/dbus-server-protected.h +++ b/dbus/dbus-server-protected.h @@ -126,6 +126,15 @@ DBusServerListenResult _dbus_server_listen_platform_specific (DBusAddressEntry DBusServer **server_p, DBusError *error); +#ifdef DBUS_ENABLE_VERBOSE_MODE +void _dbus_server_trace_ref (DBusServer *server, + int old_refcount, + int new_refcount, + const char *why); +#else +#define _dbus_server_trace_ref(s,o,n,w) do {} while (0) +#endif + #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(server) #define RELEASING_LOCK_CHECK(server) diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c index e8a24e4..ff4ebbe 100644 --- a/dbus/dbus-server-socket.c +++ b/dbus/dbus-server-socket.c @@ -344,6 +344,7 @@ _dbus_server_new_for_socket (int *fds, SERVER_UNLOCK (server); + _dbus_server_trace_ref (&socket_server->base, 0, 1, "new_for_socket"); return (DBusServer*) socket_server; failed_2: diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 60d14b3..4b77934 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -31,6 +31,7 @@ #endif #include "dbus-address.h" #include "dbus-protocol.h" +#include "dbus-valgrind-internal.h" /** * @defgroup DBusServer DBusServer @@ -53,6 +54,45 @@ * @{ */ +#ifndef _dbus_server_trace_ref +void +_dbus_server_trace_ref (DBusServer *server, + int old_refcount, + int new_refcount, + const char *why) +{ + static int enabled = -1; + + if (enabled < 0) + { + const char *s = _dbus_getenv ("DBUS_SERVER_TRACE"); + + enabled = FALSE; + + if (s && *s) + { + if (*s == '0') + enabled = FALSE; + else if (*s == '1') + enabled = TRUE; + else + _dbus_warn ("DBUS_SERVER_TRACE should be 0 or 1 if set, not '%s'", + s); + } + } + + if (enabled) + { + if (RUNNING_ON_VALGRIND) + VALGRIND_PRINTF_BACKTRACE ("DBusServer %p %d -> %d refs (%s)", + server, old_refcount, new_refcount, why); + else + _dbus_verbose ("DBusServer %p %d -> %d refs (%s)", + server, old_refcount, new_refcount, why); + } +} +#endif + /* this is a little fragile since it assumes the address doesn't * already have a guid, but it shouldn't */ @@ -433,18 +473,26 @@ _dbus_server_toggle_timeout (DBusServer *server, void _dbus_server_ref_unlocked (DBusServer *server) { + dbus_int32_t old_refcount; + _dbus_assert (server != NULL); _dbus_assert (server->refcount.value > 0); HAVE_LOCK_CHECK (server); #ifdef DBUS_HAVE_ATOMIC_INT - _dbus_atomic_inc (&server->refcount); + old_refcount = _dbus_atomic_inc (&server->refcount); #else - _dbus_assert (server->refcount.value > 0); + old_refcount = server->refcount.value; + _dbus_assert (old_refcount > 0); server->refcount.value += 1; #endif + + _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, + "ref_unlocked"); + /* might be unused if we're not verbose */ + (void) old_refcount; } /** @@ -455,7 +503,7 @@ _dbus_server_ref_unlocked (DBusServer *server) void _dbus_server_unref_unlocked (DBusServer *server) { - dbus_bool_t last_unref; + dbus_int32_t old_refcount; /* Keep this in sync with dbus_server_unref */ @@ -465,15 +513,18 @@ _dbus_server_unref_unlocked (DBusServer *server) HAVE_LOCK_CHECK (server); #ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&server->refcount) == 1); + old_refcount = _dbus_atomic_dec (&server->refcount); #else - _dbus_assert (server->refcount.value > 0); + old_refcount = server->refcount.value; + _dbus_assert (old_refcount > 0); server->refcount.value -= 1; - last_unref = (server->refcount.value == 0); #endif - - if (last_unref) + + _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, + "unref_unlocked"); + + if (old_refcount == 1) { _dbus_assert (server->disconnected); @@ -679,19 +730,26 @@ dbus_server_listen (const char *address, DBusServer * dbus_server_ref (DBusServer *server) { + dbus_int32_t old_refcount; + _dbus_return_val_if_fail (server != NULL, NULL); _dbus_return_val_if_fail (server->refcount.value > 0, NULL); #ifdef DBUS_HAVE_ATOMIC_INT - _dbus_atomic_inc (&server->refcount); + old_refcount = _dbus_atomic_inc (&server->refcount); #else SERVER_LOCK (server); - _dbus_assert (server->refcount.value > 0); + old_refcount = server->refcount.value; + _dbus_assert (old_refcount > 0); server->refcount.value += 1; SERVER_UNLOCK (server); #endif + _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, "ref"); + /* might be unused if we're not verbose */ + (void) old_refcount; + return server; } @@ -706,7 +764,7 @@ dbus_server_ref (DBusServer *server) void dbus_server_unref (DBusServer *server) { - dbus_bool_t last_unref; + dbus_int32_t old_refcount; /* keep this in sync with unref_unlocked */ @@ -714,19 +772,21 @@ dbus_server_unref (DBusServer *server) _dbus_return_if_fail (server->refcount.value > 0); #ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&server->refcount) == 1); + old_refcount = _dbus_atomic_dec (&server->refcount); #else SERVER_LOCK (server); _dbus_assert (server->refcount.value > 0); + old_refcount = server->refcount.value; server->refcount.value -= 1; - last_unref = (server->refcount.value == 0); SERVER_UNLOCK (server); #endif - - if (last_unref) + + _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, "unref"); + + if (old_refcount == 1) { /* lock not held! */ _dbus_assert (server->disconnected); -- 1.7.5.1