Here is a patch to force valgrind to dump memory leaks or all allocations while running. Next we need a patch to filter old allocations out from new one, leaving recent allocations.
Dunno if it belongs in the source code or not... IIRC we do have #ifdefs for some external malloc debug stuff already, but I didn't find that now:-(
Index: servers/slapd/daemon.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/daemon.c,v retrieving revision 1.442 diff -u -2 -r1.442 daemon.c --- servers/slapd/daemon.c 13 Nov 2009 22:48:51 -0000 1.442 +++ servers/slapd/daemon.c 18 Nov 2009 23:18:29 -0000 @@ -36,4 +36,22 @@ #include <ac/unistd.h>
+#ifdef USE_VALGRIND +/* + * When running under valgrind, make kill -USR1 force a leak/alloc dump + * to stderr, in addition to its usual "wake listener" function. + * After SIGUSR1 there will also be a dump before shutdown. + * + * Usage: + * valgrind --leak-check=yes --show-reachable=yes slapd -d0 2>slapd.out & + * kill -USR1 <slapd or valgrind process> + * + * For recent leaks/allocs only, do kill -USR1 after startup and again + * sometime later. Then filter out from the 2nd dump the occurrences of + * allocs from the 1st dump. + */ +#include <ac/signal.h> +#include <valgrind/memcheck.h> +#endif /* USE_VALGRIND */ + #include "slap.h" #include "ldap_pvt_thread.h" @@ -664,4 +682,25 @@ #endif /* ! epoll && ! /dev/poll */
+#ifdef USE_VALGRIND +static sig_atomic_t slap_valgrind_requested = 0; +#define slap_valgrind_request() ((void) (slap_valgrind_requested = 2)) +static void +slap_valgrind_check( int when, const char *msg ) +{ + if ( slap_valgrind_requested >= when && RUNNING_ON_VALGRIND ) { + Debug( LDAP_DEBUG_TRACE, "Valgrind dump %s\n", msg, 0, 0 ); + /* Needed for terminator between valgrind -q dumps */ + VALGRIND_PRINTF( "==> Valgrind dump %s\n", msg ); + VALGRIND_DO_LEAK_CHECK; + VALGRIND_PRINTF( "<== Valgrind dump %s\n", msg ); + slap_valgrind_requested = 1; + } +} + +#else /* !USE_VALGRIND */ +#define slap_valgrind_check(when, msg) ((void) 0) +#define slap_valgrind_request() ((void) 0) +#endif /* USE_VALGRIND */ + #ifdef HAVE_SLP /* @@ -2308,4 +2347,6 @@ struct re_s* rtask;
+ slap_valgrind_check( 2, "while running" ); + now = slap_get_time();
@@ -2760,4 +2801,6 @@ }
+ slap_valgrind_check( 1, "before shutdown" ); + if ( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
@@ -2942,4 +2985,6 @@ int save_errno = errno;
+ slap_valgrind_request(); + WAKE_LISTENER(1);
Thanks for the patch. I will be testing with it later this week.
Bill
--On Thursday, November 19, 2009 12:25:30 AM +0100 Hallvard B Furuseth h.b.furuseth@usit.uio.no wrote:
Here is a patch to force valgrind to dump memory leaks or all allocations while running. Next we need a patch to filter old allocations out from new one, leaving recent allocations.
Dunno if it belongs in the source code or not... IIRC we do have #ifdefs for some external malloc debug stuff already, but I didn't find that now:-(
Index: servers/slapd/daemon.c
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/daemon.c,v retrieving revision 1.442 diff -u -2 -r1.442 daemon.c --- servers/slapd/daemon.c 13 Nov 2009 22:48:51 -0000 1.442 +++ servers/slapd/daemon.c 18 Nov 2009 23:18:29 -0000 @@ -36,4 +36,22 @@ #include <ac/unistd.h>
+#ifdef USE_VALGRIND +/*
- When running under valgrind, make kill -USR1 force a leak/alloc dump
- to stderr, in addition to its usual "wake listener" function.
- After SIGUSR1 there will also be a dump before shutdown.
- Usage:
- valgrind --leak-check=yes --show-reachable=yes slapd -d0 2>slapd.out &
- kill -USR1 <slapd or valgrind process>
- For recent leaks/allocs only, do kill -USR1 after startup and again
- sometime later. Then filter out from the 2nd dump the occurrences of
- allocs from the 1st dump.
- */
+#include <ac/signal.h> +#include <valgrind/memcheck.h> +#endif /* USE_VALGRIND */
#include "slap.h" #include "ldap_pvt_thread.h" @@ -664,4 +682,25 @@ #endif /* ! epoll && ! /dev/poll */
+#ifdef USE_VALGRIND +static sig_atomic_t slap_valgrind_requested = 0; +#define slap_valgrind_request() ((void) (slap_valgrind_requested = 2)) +static void +slap_valgrind_check( int when, const char *msg ) +{
- if ( slap_valgrind_requested >= when && RUNNING_ON_VALGRIND ) {
Debug( LDAP_DEBUG_TRACE, "Valgrind dump %s\n", msg, 0, 0 );
/* Needed for terminator between valgrind -q dumps */
VALGRIND_PRINTF( "==> Valgrind dump %s\n", msg );
VALGRIND_DO_LEAK_CHECK;
VALGRIND_PRINTF( "<== Valgrind dump %s\n", msg );
slap_valgrind_requested = 1;
- }
+}
+#else /* !USE_VALGRIND */ +#define slap_valgrind_check(when, msg) ((void) 0) +#define slap_valgrind_request() ((void) 0) +#endif /* USE_VALGRIND */
#ifdef HAVE_SLP /* @@ -2308,4 +2347,6 @@ struct re_s* rtask;
slap_valgrind_check( 2, "while running" );
- now = slap_get_time();
@@ -2760,4 +2801,6 @@ }
- slap_valgrind_check( 1, "before shutdown" );
- if ( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
@@ -2942,4 +2985,6 @@ int save_errno = errno;
- slap_valgrind_request();
- WAKE_LISTENER(1);
I wrote:
Next we need a patch to filter old allocations out from new one, leaving recent allocations.
Like this enhancement to valgrind 3.5.0 for dumping "delta leaks": http://bugs.kde.org/show_bug.cgi?id=206802 Then instead of VALGRIND_DO_LEAK_CHECK in my patch, use VALGRIND_DO_ADDED_LEAK_CHECK or VALGRIND_DO_CHANGED_LEAK_CHECK.
And quoting the author, Philippe Waroquiers: "If you use the patch, it would be nice to give some feedback (how it is working, enhancements/changes you think would be good, ...)."