[Gc] incremental collection and fork()

Sean Middleditch smiddle@twp.ypsilanti.mi.us
Wed, 15 Oct 2003 16:43:26 -0400


Hi all,

 I'm getting a crash in the collector, only when incremental mode is
enabled, in my application.  I'm a bit new to using this collector, so
I'm not exactly sure what could cause it.

 System is Linux x86 (kernel 2.4.21), collector version 6.2alpha6,
compiled with --enable-cplusplus.  The application works fine with
incremental collection turned off, even when I explicitly invoke a full
collection every "loop" (app is a network game server, a MUD).

 The bison/flex code used (as seen in the backtrace) has had their
malloc/free calls overridden wtih GC_MALLOC and GC_FREE (not
GC_MALLOC_ATOMIC, I've not spent time to identify if that would be safe
or not yet).  It does look like bison/flex may be causing the problem
(perhaps by holding pointers to collected memory in non tracable places)
- is there any known "trick" to bison/flex besides overriding malloc and
free?

 Many objects have finalizers registered with
gc_register_finalizer_ignore_order() to call destructors - most of my
objects have at least some explicitly managed memory still, so I need
the destructors to free it.  The normal C++ gc_cleanup class, according
to the docs, doesn't handle cyclic references, of which there are a lot
of in various places.  All any of the destructors do is call destructors
on C++ containers or strings - *some* of those containers have the
gc_alloc specifier, as they hold pointers (or objects w/ pointers) to
collected objects - could that be a cause?  does gc_alloc make the
container's memory collected as well as traced?  Am I just a raging
idiot for trying to let destructors be called this way?

 For kicks, I ran the app under Valgrind (a nifty x86 memory debugger) -
it stops crashing then, but the collector causes it to spit out many
warnings; not surprising, as I assume the collector pulls tricks
Valgrind doesn't expect/like.  ~,^

 Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1084561024 (LWP 18936)]
GC_clear_fl_marks (q=0x89e9fc0
"ayer.recalc();\n\tplayer.set_hp(player.get_maxhp());\n\n\t// display ")
at alloc.c:601
601        for (p = q; p != 0; p = obj_link(p)){
Current language:  auto; currently c
(gdb) bt
#0  GC_clear_fl_marks (q=0x89e9fc0
"ayer.recalc();\n\tplayer.set_hp(player.get_maxhp());\n\n\t// display ")
at alloc.c:601
#1  0x002d65da in GC_finish_collection () at alloc.c:690
#2  0x002d5dba in GC_maybe_gc () at alloc.c:296
#3  0x002d60ed in GC_collect_a_little_inner (n=1) at alloc.c:436
#4  0x002d6dc0 in GC_allocobj (sz=16, kind=1) at alloc.c:1042
#5  0x002da93a in GC_generic_malloc_inner (lb=56, k=1) at malloc.c:134
#6  0x002daa37 in GC_generic_malloc (lb=56, k=1) at malloc.c:190
#7  0x002dacd9 in GC_malloc (lb=56) at malloc.c:295
#8  0x00859e78 in yyparse() () at gc_cpp.h:268
#9  0x0085a637 in Scriptix::System::LoadFile(char const*)
(this=0x89c7ed8, file=0x899ccbc "scripts/50.creation.sx")
    at grammar.yy:296
#10 0x08053dca in AweScript::init() (this=0x89c7ed8) at
basic_string.h:717
#11 0x080bad75 in Server::init(int, char**) (this=0x81084e0, argc=1,
argv=0x12) at server.cc:174
#12 0x080a1a17 in main (argc=1, argv=0xbfe728c4) at main.cc:41