[Gc] valgrind and libgc

Brian Buchanan brian at ncircle.com
Thu May 4 12:27:02 PDT 2006


On Wed, 3 May 2006, Travis Griggs wrote:

> I've never used valgrind before. But I've some memory's getting trashed from 
> somewhere it shouldn't... I thought I'd try to use valgrind to see if it 
> could help me figure out where.
>
> When I run 'valgrind --tool=memcheck sorter' though... I just got a lot of 
> messages about GC_functions(). Can valgrind by used with a libgc linked 
> program? Are there tricks to it?

Travis,

Have you read the guide to debugging garbage-collected applications at 
"http://www.hpl.hp.com/personal/Hans_Boehm/gc/debugging.html"?  I have 
found this document absolutely invaluable.  If you're pretty sure that 
your memory corruption is not related to your use of the garbage 
collector, however, valgrind may be able to help you.

I've successfully used valgrind with libgc on FreeBSD.  I had to slightly 
modify valgrind to make it work, as valgrind relocates the stack of the 
program it's debugging and libgc tries to use the "kern.usrstack" sysctl 
to find it, but that still points to the "real" (i.e. valgrind's) stack.

I haven't tried running a libgc-linked program under valgrind in quite 
some time, but I think I encountered a number of spurious valgrind 
warnings that I put into a suppression file.  Unfortunately, I no longer 
have that file.  If you develop one, I'm sure other libgc users would 
appreciate it if you shared it.

This patch will cause valgrind to intercept the kern.usrstack sysctl on 
FreeBSD and substitute the correct stack address for the valgrind-ized 
process.

Index: coregrind/vg_syscalls.c
===================================================================
--- coregrind/vg_syscalls.c	(revision 333)
+++ coregrind/vg_syscalls.c	(working copy)
@@ -1123,6 +1123,9 @@
  #endif

  #ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
  #define PRE(x)	\
  	static void before_##x(ThreadId tid, ThreadState *tst, UInt *argp)
  #define POST(x)	\
@@ -1920,9 +1923,21 @@

  POST(__sysctl)
  {
-   if (arg3)
+   if (arg3) {
+      int *name = (int *)arg1;
+      u_int namelen = (u_int)arg2;
+
        buf_and_len_post_check( tid, res, arg3, arg4,
  			      "__sysctl(oldlen_out)" );
+
+      /* Intercept the response to kern.usrstack and supply a more
+       * sensible value.
+       */
+      if (namelen == 2 && name[0] == CTL_KERN && name[1] == KERN_USRSTACK) {
+	Addr *sbaddr = (Addr *)arg3;
+	*sbaddr = VG_(clstk_end);
+      }
+   }
     else if (arg4)
        VG_TRACK( post_mem_write, arg4, sizeof(Addr) );
  }

Best Regards,

Brian

-- 
Brian Buchanan <brian at ncircle.com>
Principal Engineer
nCircle Network Security                             http://www.ncircle.com/


More information about the Gc mailing list