[Gc] Exciting recursive invocation of GC_invoke_finalizers()...

Bruce Hoult bruce at hoult.org
Fri Jun 19 01:07:38 PDT 2009

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.

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

More information about the Gc mailing list