[Gc] Boehm GC interaction with other libraries

Boehm, Hans hans_boehm@hp.com
Mon, 1 Dec 2003 15:18:47 -0800


It occurs to me that there is one other possibility: If the native library
ends up deallocating GC allocated memory with free() as opposed to GC_free(),
things will clearly fail.  They may fail in subtle ways, since many free()
implementations assume that there is a header word before the actual object.
For objects in the GC heap, that's not true.

It is of course also possible that if the native code accesses an object in
the GC heap directly, and writes past its end (or beginning), you will see
interesting failures.

I would debug this by:

1) Determine whether the corruption is caused by premature deallocation.
To do this, you have to debug the failure sufficiently to determine which
object was corrupted.  Assume it has address p.  If GC_find_header(p) is
not NULL, then the object is in the garbage collected heap.  (GC_base(p)
can also be used for this test.  For GC heap objects you should get GC_base(p)==p;
for everything outside the GC heap, GC_base(p) == 0).  If the object at
the point of failure looks like a pointer followed by zeros, it was probably
reclaimed.  You should also check that GC_is_marked(p) == 0.
If only the first or last word of an object was overwritten, I would suspect
an out of bounds access somewhere in your code.

2) If the problem is caused by premature deallocation, there are general debugging
suggestions near the end of http://www.hpl.hp.com/personal/Hans_Boehm/gc/debugging.html .

Hans

> -----Original Message-----
> From: eric lindvall [mailto:eric@5stops.com]
> Sent: Wednesday, November 26, 2003 10:35 PM
> To: Boehm, Hans
> Cc: gc@napali.hpl.hp.com; mono-devel-list@lists.ximian.com
> Subject: Re: [Gc] Boehm GC interaction with other libraries
> 
> 
> So there isn't anything in the calls I listed that would strike you as
> possibly leading to memory leaks/corruption?
> 
> Are there any defines I can use to help track down where the 
> corruption is
> coming from?
> 
> e.
> 
> 
> On Wed, 26 Nov 2003, Boehm, Hans wrote:
> 
> > > From: gc-admin@napali.hpl.hp.com 
> [mailto:gc-admin@napali.hpl.hp.com] On Behalf Of eric lindvall
> > > Sent: Wednesday, November 26, 2003 3:03 PM
> > 
> > > I have a few questions about how code that uses the Boehm 
> GC interacts
> > > with libraries that were not compiled against the Boehm GC
> > > library/headers.
> > > 
> > > I am seeing some odd behaviour when using Platform Invoke 
> > > (P/Invoke) in
> > > Mono to invoke native libraries from Mono. From what I can 
> > > see, it seems
> > > like there is some sort of memory corruption going on.
> > > 
> > > The native library makes use of:
> > >  - malloc(), free()
> > >  - pthread_create()
> > >  - pthread_cond_init(), pthread_cond_signal(), pthread_cond_wait()
> > >  - sem_init(), sem_wait(), sem_post()
> > >  - msgsnd(), msgrcv()
> > > 
> > > The questions I have are:
> > > 
> > > 1. Is memory that I allocate with malloc() in libraries 
> that were not
> > > compiled against boehm seen by the garbage collector? 
> (will it ever be
> > > collected out from under me?)
> > Assuming the GC library was not compiled with -DREDIRECT_MALLOC,
> > memory allocated with malloc is neither collected nor traced.  The
> > malloced objects should not disappear out from under you.  
> The collectable
> > objects they refer to may.  (The collector tries not to 
> trace malloced
> > memory.  Under win32, it sometimes ends up tracing it 
> anyway, which is
> > benign for correctness, but not performance.  It can
> > never collect memory allocated through the system malloc.)
> > > 
> > > 2. Will boehm just "ignore" any threads that were created by
> > > a version of pthread_create() that was not wrapped by boehm?
> > I believe that's correct (for the collector, not me 
> personally :-) ),
> > provided the collector is initialized from the main thread,
> > and you are not on a platform on which the collector can enuumerate
> > all threads.  (Currently that happens for win32 with the collector
> > in its own dll.)  The collector currently needs to know about the
> > main thread.  (It currently has no way to find the stack base of
> > an arbitrary thread, and hence "knows" that it is 
> initialized from the
> > main thread, so that it can register the initializing thread.)
> > 
> > Note that if the ignored threads change pointers in/to the 
> garbage-collected
> > heap, all bets are off.
> > > 
> > > 3. Will anything bad happen if the libraries that I invoke use
> > > pthread_cond_wait()?
> > If the collector knows about it, I suspect that the 
> pthread_cond_wait() call may
> > terminate after the collector stops and restarts the 
> thread.  But that's OK, since
> > the pthread spec allows that behavior anyway.
> > 
> > Hans
>