Bug 22778 – druntime: infinite loop in gc_term if an object destructor throws

Status
NEW
Severity
critical
Priority
P2
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-02-16T09:59:28Z
Last change time
2024-12-07T13:41:51Z
Assigned to
No Owner
Creator
Iain Buclaw
Moved to GitHub: dmd#17440 →

Comments

Comment #0 by ibuclaw — 2022-02-16T09:59:28Z
--- struct S8 { int b; ~this() { assert(b == 7); } } void main() { S8 *s = new S8(9); } --- Backtrace --- #0 0x00007ffff7e4f9da in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7fffffffd3c0, rem=0x7fffffffd3d0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78 #1 0x00007ffff7e54957 in __GI___nanosleep (req=<optimised out>, rem=<optimised out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25 #2 0x000055555560361c in core.thread.osthread.Thread.sleep(core.time.Duration) () #3 0x0000555555605ca8 in core.internal.spinlock.SpinLock.yield(ulong) shared () #4 0x0000555555605c52 in core.internal.spinlock.SpinLock.lock() shared () #5 0x000055555560f073 in core.internal.gc.impl.conservative.gc.ConservativeGC.runLocked!(core.internal.gc.impl.conservative.gc.ConservativeGC.mallocNoSync(ulong, uint, ref ulong, const(TypeInfo)), core.in ternal.gc.impl.conservative.gc.mallocTime, core.internal.gc.impl.conservative.gc.numMallocs, ulong, uint, ulong, const(TypeInfo)).runLocked(ref ulong, ref uint, ref ulong, ref const(TypeInfo)) () #6 0x000055555560699a in core.internal.gc.impl.conservative.gc.ConservativeGC.malloc(ulong, uint, const(TypeInfo)) () #7 0x00005555555f234b in gc_malloc () #8 0x00005555555e9639 in _d_newclass () #9 0x00005555555f8231 in core.runtime.defaultTraceHandler(void*) () #10 0x00005555555f3cf2 in _d_traceContext () #11 0x00005555555f3ae2 in _d_createTrace () #12 0x00005555555e898e in _d_throwdwarf () #13 0x000055555560b385 in core.internal.gc.impl.conservative.gc.Gcx.fullcollect(bool, bool, bool) () #14 0x000055555560fb84 in core.internal.gc.impl.conservative.gc.ConservativeGC.runLocked!(core.internal.gc.impl.conservative.gc.ConservativeGC.fullCollectNoStack().go(core.internal.gc.impl.conservative.gc. Gcx*), core.internal.gc.impl.conservative.gc.Gcx*).runLocked(ref core.internal.gc.impl.conservative.gc.Gcx*) () #15 0x0000555555607d68 in core.internal.gc.impl.conservative.gc.ConservativeGC.fullCollectNoStack() () #16 0x0000555555607cf6 in core.internal.gc.impl.conservative.gc.ConservativeGC.collectNoStack() () #17 0x00005555555fed93 in gc_term () #18 0x00005555555f3c1b in rt_term () --- To highlight more specifically --- ... #8 0x00005555555e9639 in _d_newclass () # <--- #9 0x00005555555f8231 in core.runtime.defaultTraceHandler(void*) () #10 0x00005555555f3cf2 in _d_traceContext () #11 0x00005555555f3ae2 in _d_createTrace () #12 0x00005555555e898e in _d_throwdwarf () ... #17 0x00005555555fed93 in gc_term () #18 0x00005555555f3c1b in rt_term () --- D runtime should not be using `_d_newclass` here.
Comment #1 by ibuclaw — 2022-02-16T10:07:40Z
There's already this guard in defaultTraceHandler: --- // avoid recursive GC calls in finalizer import core.memory : GC; if (GC.inFinalizer) return null; --- So if the GC cannot be avoided entirely in allocating, there would need to be a similar check for when GC.collect() is running.
Comment #2 by schveiguy — 2024-04-21T02:04:35Z
I think this can be closed. The behavior doesn't happen anymore, and I think we've fixed a few of these chicken-and-egg problems that were there before.
Comment #3 by robert.schadek — 2024-12-07T13:41:51Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17440 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB