[Gc] Valgrind/gc: failure in GC_malloc ?

Paolo Molaro lupus at ximian.com
Sun Jan 21 01:51:15 PST 2007


On 01/20/07 Marnix Klooster wrote:
> Been there, done that, asked the same question in the same place, got a 
> --how shall I put it-- very clear answer that no-one in their right mind 
> would want to use valgrind+gc since gc has its own nice memory usage 
> tracing options thankyouverymuch.

The built-in memory debugging features have only limited use: valgrind
is much more powerful (and of course slower, but it's invaluable).
I'm sorry if I didn't post my solution sooner, I meant
to but forgot to post it.

The interaction issue between valgrind and the GC is as follows:
the GC gets the main stack boundaries from /proc (GC_stackbottom),
but it assumes it is initialized in the main thread. Now, when running
under valgrind (or when the GC is loaded from a shared module or
otherwise initialized from a non-main thread) the boundary info is
incorrect and what usually happens is that when tracing the stack
the GC will hit some unmapped page (or the stack sentinel page)
between the thread stack and the main thread stack.

 GC_stackbottom ->      |
                        | main() thread stack (or valgrind stack)
                        |
                        # sentinel page
 correct stackbottom -> |
                        | GC_init () stack
                        |
                        | GC_collect () stack frame


What we did in mono is to explicitly set GC_stackbottom in the
initialization thread (which can be the main thread too from the point
of view of an app running in valgrind) with one of the following,
depending on the architecture:
1) pthread_getattr_np/pthread_attr_getstack
2) pthread_get_stackaddr_np
3) guessing that we are close to the top of the stack and rounding up

Note that pthread_attr_getstack() can fail without error and return a
NULL stack start.

This hasn't been submitted for inclusion because it is sort of an hack.
I guess changing the GC method of checking GC_stackbottom to always use
pthread_getattr_np/pthread_attr_getstack or pthread_get_stackaddr_np
if they are available and only if not using the other methods makes
sense. Instead of 3 one could try to parse the equivalent of
/proc/self/maps, but I guess that the architecture that provide the maps
feature already provides the pthread calls, too.

lupus

-- 
-----------------------------------------------------------------
lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better


More information about the Gc mailing list