Garbage Collection, Untraceable Errors...

cy via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 13 01:26:34 PDT 2016


Most people complain about garbage collection slowing things 
down, or causing moments of program hang, but lately D's 
performance has been pretty awesome in that regard, IMO. No, the 
problem I have with garbage collection is untraceable errors...

GC.collect() is just this opaque... black box thing, that you 
have to trust to magically find all the garbage and collect it. 
When it does, it's awesome. But when it doesn't... you're just 
screwed. You can't trace through garbage collection, can't debug 
it, can't examine its inner structures, see what objects are 
being destructed, or anything as far as I can tell.

So I get something like the following output:
All unit tests have been run successfully.
finalize
core.exception.InvalidMemoryOperationError at src/core/exception.d(693): Invalid memory operation
----------------

...and the program exits with status 1. No stack trace, no error 
reported. Somewhere I've got a null dereference or something, 
some failure of everything to initialize in the expected order. 
But I have no way of finding it outside of staring at the code 
for another 2 hours trying to see anything funny looking.

Trying to break on "exit" with gdb doesn't work either, since D 
unwinds the stack before exiting in a GC error. Tracing through 
finalization, the deepest I can get is something called rt_term 
before there is no more debugging information (despite 
BUILD=debug being specified). Reading the source in rt/dmain.d 
myself, I can divine that rt_term calls gc_term, and in gc_term 
the error is raised. But what functions gc_term calls, you can't 
even set a breakpoint for. GC.fullCollect() just isn't available. 
(And gdb doesn't let you do tab completion in D, so I can't list 
all possible functions similar to that one.)

So... that's my complaint about the D garbage collection. It's 
frustratingly opaque, impossible to debug, and provides no help 
whatsoever in its error messages to understanding what went 
wrong. Garbage collection causes errors after the program has 
entirely finished, and calling GC.collect() inside a destructor 
will not only cause the error, it'll completely terminate the 
program before it finishes the destructor. Speed is great, but 
debugging with garbage collection is pretty much an endless fount 
of misery and frustration for me.


More information about the Digitalmars-d mailing list