[Date Prev][Date Next] [Chronological] [Thread] [Top]

forcing valgrind dumps



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);