---
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