From f2d7e09d3da45ab8fd9b7d2724dbb21fd4d17aac 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 | 96 ++++++++++++++++++++++++++++++----------- 4 files changed, 82 insertions(+), 27 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 5383a66..589a8b3 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 */ @@ -442,18 +482,17 @@ _dbus_server_toggle_timeout (DBusServer *server, void _dbus_server_ref_unlocked (DBusServer *server) { + dbus_int32_t old_refcount; + _dbus_assert (server != NULL); HAVE_LOCK_CHECK (server); -#ifdef DBUS_DISABLE_ASSERT - _dbus_atomic_inc (&server->refcount); -#else - { - dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount); - - _dbus_assert (old_refcount > 0); - } -#endif + old_refcount = _dbus_atomic_inc (&server->refcount); + _dbus_assert (old_refcount > 0); + _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, + "ref_unlocked"); + /* unused if we're neither verbose nor asserting */ + (void) old_refcount; } /** @@ -475,6 +514,9 @@ _dbus_server_unref_unlocked (DBusServer *server) old_refcount = _dbus_atomic_dec (&server->refcount); _dbus_assert (old_refcount > 0); + _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, + "unref_unlocked"); + if (old_refcount == 1) { _dbus_assert (server->disconnected); @@ -681,29 +723,29 @@ dbus_server_listen (const char *address, DBusServer * dbus_server_ref (DBusServer *server) { - _dbus_return_val_if_fail (server != NULL, NULL); + dbus_int32_t old_refcount; -#ifdef DBUS_DISABLE_CHECKS - _dbus_atomic_inc (&server->refcount); -#else - { - dbus_int32_t old_refcount; + _dbus_return_val_if_fail (server != NULL, NULL); - /* can't get the refcount without a side-effect */ - old_refcount = _dbus_atomic_inc (&server->refcount); + /* can't get the refcount without a side-effect */ + old_refcount = _dbus_atomic_inc (&server->refcount); - if (_DBUS_UNLIKELY (old_refcount <= 0)) - { - /* undo side-effect first */ - _dbus_atomic_dec (&server->refcount); - _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, - _DBUS_FUNCTION_NAME, "old_refcount > 0", - __FILE__, __LINE__); - return NULL; - } +#ifndef DBUS_DISABLE_CHECKS + if (_DBUS_UNLIKELY (old_refcount <= 0)) + { + /* undo side-effect first */ + _dbus_atomic_dec (&server->refcount); + _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, + _DBUS_FUNCTION_NAME, "old_refcount > 0", + __FILE__, __LINE__); + return NULL; } #endif + _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, "ref"); + /* unused if we're neither verbose nor checking */ + (void) old_refcount; + return server; } @@ -739,6 +781,8 @@ dbus_server_unref (DBusServer *server) } #endif + _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, "unref"); + if (old_refcount == 1) { /* lock not held! */ -- 1.7.5.4