Bug 5653 – Allocating in a destructor called during a GC corrupts memory

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-02-25T19:02:00Z
Last change time
2015-06-09T05:11:51Z
Keywords
patch
Assigned to
nobody
Creator
dlang-bugzilla

Attachments

IDFilenameSummaryContent-TypeSize
922gc.patchVery simple patch against D1's gcx.d which throws OutofMemory when allocating during a GC runtext/plain1832
971test_string.dMemory corruption testapplication/octet-stream446
972test_throw.dNaive test for disallowing GC interaction after a finalizer exceptionapplication/octet-stream721

Comments

Comment #0 by dlang-bugzilla — 2011-02-25T19:02:00Z
Created attachment 922 Very simple patch against D1's gcx.d which throws OutofMemory when allocating during a GC run D's current garbage collector is completely unprepared to handle an allocation which is called by a finalizer. Such an allocation puts D's GC into an inconsistent state, which ultimately leads to memory corruption. The GC should either forbid allocating in destructors (by throwing an exception), or properly support it (which may be non-trivial). If the first solution is chosen, it should be noted that there are instances of allocations in destructors in Phobos as well (such as std.zlib).
Comment #1 by dlang-bugzilla — 2011-05-13T04:01:57Z
Created attachment 971 Memory corruption test
Comment #2 by dlang-bugzilla — 2011-05-13T04:03:22Z
Created attachment 972 Naive test for disallowing GC interaction after a finalizer exception
Comment #3 by dlang-bugzilla — 2011-05-13T04:10:06Z
Comment #4 by andrei — 2011-05-25T23:00:17Z
Fixed here: https://github.com/D-Programming-Language/phobos/pull/44 Does that take care of D1 too?
Comment #5 by dlang-bugzilla — 2011-05-26T03:35:29Z
(In reply to comment #4) > Fixed here: https://github.com/D-Programming-Language/phobos/pull/44 Does that > take care of D1 too? The Phobos pull request is for D1, the druntime pull request is for D2. Thanks!
Comment #6 by sean — 2011-06-17T10:54:59Z
Note that this patch will cause all successive allocations by the process to generate an OOME, since gcx.running will be true forever. This may be a good stopgap fix, but ultimately the GC has to support allocations inside a finalizer. The best approach is probably to effectively disable the GC when it's running so an allocating finalizer would simply create a new Pool if no memory was available. It looks like the collect routine still needs to be rewritten with this in mind, however.
Comment #7 by dlang-bugzilla — 2011-06-18T04:39:19Z
(In reply to comment #6) > Note that this patch will cause all successive allocations by the process to > generate an OOME, since gcx.running will be true forever. Yes, this is by design until someone comes up with something better.