Re[4]: [Gc] Exciting recursive invocation of GC_invoke_finalizers()

Ivan Maidanski ivmai at mail.ru
Fri Jun 19 01:41:53 PDT 2009


Hi!

Bruce Hoult <bruce at hoult.org> wrote:
> 2009/6/19 Ivan Maidanski <ivmai at mail.ru>:
> > Hi!
> >
> > Bruce Hoult <bruce at hoult.org> wrote:
> >> On Fri, Jun 19, 2009 at 7:15 AM, Talbot, George<Gtalbot at locuspharma.com> wrote:
> >> > Attached is a nice zip file of a 264K text file showing a backtrace from my program. ?I've managed to find that one can cause an exciting crash if one allocates memory from a finalization function invoked by the collector.
> >>
> >> There are many things you are not allowed to do in finalizer if you
> >> have GC (any GC) set up to call finalizers synchronously from within a
> >> GC (which means from within some random memory allocation attempt in
> >> the calling program):
> >>
> >> In particular you may not:
> >>
> >> - allocate memory
> >> - do anything that takes a lock
> >
> > Wrong assumptions (both). You are allowed to do it even from a finalizer notifier.
> 
> Allowed by whom? It is a quite serious program bug for a
> synchronously-called finalizer to attempt to take a lock that is held
> by the code that called the GC_malloc() that caused the GC that is
> running the finalizer.

Allowed by the GC implementation. If You know a place where we call finalizers (or notifier) holding alloc lock, please report.

> 
> There are two options:
> 
> - you have non-recursive locks.  You are now deadlocked.
> 
> - you have recursive locks. You are in the same thread that holds the
> lock, so entry is allowed, but there are no guarantees about the state
> and this is likely an unanticipated usage, so corruption of the data
> structure is likely.
> 
> 
> >> If you think you need to do that kind of thing then you should
> >> configure the GC to not run finalizers synchronously, but instead
> >> simply signal a thread (probably a dedicated one) that holds no locks
> >> and is there purely to drain the finalizer queue.
> >
> > This is not always possible, e.g if single-threaded.
> 
> If you are single-threaded then the only way you can ever safely take
> a lock in a finalizer is if the entire code base is guaranteed to be
> written in such a way that GC_malloc() is never called with a lock
> held.

We are miscommunicating a bit. I'm talking about single-threaded world (where we can't have a notifier thread which is guaranteed not to call other finalizers if GC_malloc is called inside a finalizer), not about single-threaded collector in the MT world.

Bye.


More information about the Gc mailing list