[Gc] GC_init from non-main thread fails with segfault

Boehm, Hans hans.boehm at hp.com
Tue Jan 10 11:11:43 PST 2006

The GC should be intercepting all calls to pthread_create.  Normally
this should be done by defining GC_THREADS and including gc.h in files
that make any pthread calls (other than simple synchronization calls
like pthread_mutex...).

The theory is that since pthread_create calls should really be turned
into GC_pthread_create calls, and GC_pthread_create should call
GC_init(), the first GC_init() call has to come from the main thread,
and thus this scenario should be impossible.

It is understood that this is a bad answer if you load a dynamic library
containing the GC after the fact, or don't have control over the code
that creates the threads.  That's being worked on.  If you need
something that has a better chance of working in such a context, you
might try the gc7 CVS version, which somewhat supports registering
threads after the fact.  I think that both gcj and Mono are currently
running into this problem.


> -----Original Message-----
> From: gc-bounces at napali.hpl.hp.com 
> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of Reiterer, Horst
> Sent: Tuesday, January 10, 2006 5:48 AM
> To: gc at napali.hpl.hp.com
> Subject: [Gc] GC_init from non-main thread fails with segfault
> Hi,
> If the GC is initialized (GC_init) in a thread other than the 
> process main thread on a Linux platform (RHEL4, NPTL), the 
> implementation causes a segmentation fault because 
> GC_push_all_stacks IMHO wrongly assumes that the initiator 
> thread equals the process main thread and sets the stack 
> bottom accordingly before calling GC_push_all_stack.
> The stack trace is as follows:
>   /usr/lib/libmono.so.0(GC_push_all_eager+0x50)[0x939bd00]
>   /usr/lib/libmono.so.0(GC_push_all_stack+0x4c)[0x939bd7c]
>   /usr/lib/libmono.so.0[0x93a3ec4]
>   /usr/lib/libmono.so.0(GC_push_all_stacks+0x1f)[0x93a3f5f]
>   /usr/lib/libmono.so.0(GC_default_push_other_roots+0x19)[0x939f1a9]
>   /usr/lib/libmono.so.0(GC_push_roots+0xd9)[0x939cfb9]
>   /usr/lib/libmono.so.0(GC_mark_some+0xd6)[0x939aac6]
>   /usr/lib/libmono.so.0(GC_stopped_mark+0xb5)[0x9393c95]
>   /usr/lib/libmono.so.0(GC_try_to_collect_inner+0xa4)[0x9393894]
>   /usr/lib/libmono.so.0(GC_init_inner+0x336)[0x939d926]
>   /usr/lib/libmono.so.0(GC_init+0x2e)[0x939d4ee]
> The fault occurs while tracing the stack and accessing 
> unmapped memory as a result of the incorrect stack bottom - 
> the current thread's stack bottom should IMHO be passed to 
> the function, not the main thread's stack bottom.
> The issue can be fixed by reading the stack address via 
> pthread_getattr_np and pthread_attr_getstackaddr and falling 
> back to GC_stackbottom if the current thread in 
> GC_push_all_stacks is the process main thread. Would this be 
> a legitimate fix to consider for inclusion? The problem here 
> is identifying the main thread, I'm currently doing that by 
> comparing the results of getpid() and gettid() but that 
> obviously would not work in non-NPTL environments.
> I guess that this case isn't currently being handled because 
> the GC is usually initialized right in the main thread. Or am 
> I missing something?
> Cheers,
> Horst.
> _______________________________________________
> Gc mailing list
> Gc at linux.hpl.hp.com 
> https://www.hpl.hp.com/hosted/linux/mail-archives/gc/

More information about the Gc mailing list