On Tuesday, 13 May 2025 at 10:21:12 UTC, Denis Feklushkin wrote:
I added simple debug(PRINTF)
section exactly after druntime allocator. It throws error if newly allocated memory intersects with already allocated internal bucket List structures. I hope I didn't make a mistake in this code?
auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);
debug(PRINTF)
{
outer:
foreach(List* firstList; gcx.bucket)
{
List* curr = firstList;
while(curr !is null)
{
void* p_end = cast(ubyte*) p + localAllocSize;
void* curr_end = cast(ubyte*) curr + List.sizeof;
const bool notIntersects = ((p < curr && p_end < curr) || (p > curr_end && p_end > curr_end));
if(!notIntersects)
{
printf("%p - allocated into bucket List value, located on %p: firstList.pool=%p curr.pool=%p\n",
p, curr, firstList.pool, curr.pool);
assert(false);
break outer;
}
curr = curr.next;
}
}
}
Druntime was built as debug version with enabled INVARIANT, MEMSTOMP and PRINTF
Then this snippet was used with compiled druntime (do not forget to replace path to new druntime in ldc2.conf):
/+ dub.sdl:
name "issue"
+/
// How to run: dub run --single app.d
class C {}
void main()
{
new C;
}
> dub run --single app.d --compiler=ldc2
Starting Performing "debug" build using ldc2 for x86_64.
Building issue ~master: building configuration [application]
Linking issue
Running issue
_d_newclass(ci = 0x56496398c350, app.C)
0x5649a1312c90.Gcx::addRange(0x564963985940, 0x564963994718)
GC::malloc(gcx = 0x5649a1312c90, size = 16 bits = 2, ti = app.C)
=> p = 0x7fa30e5cb000
0x7fa30e5cb000 - allocated into bucket List value, located on 0x7fa30e5cb010: firstList.pool=0x5649a1313fa0 curr.pool=0x5649a1313fa0
core.exception.AssertError@core/internal/gc/impl/conservative/gc.d(505): Assertion failure
----------------
core/runtime.d:831 [0x564963942d45]
core/lifetime.d:126 [0x56496394234c]
core/runtime.d:753 [0x564963942d0e]
core/runtime.d:773 [0x564963942640]
rt/dmain2.d:241 [0x564963920f30]
rt/deh.d:47 [0x564963949b9e]
rt/dwarfeh.d:347 [0x564963921ac2]
core/exception.d:569 [0x564963936a05]
core/exception.d:808 [0x564963936444]
core/internal/gc/impl/conservative/gc.d:505 [0x5649639502f3]
core/internal/gc/proxy.d:156 [0x56496393cf70]
core/internal/gc/impl/proto/gc.d:101 [0x5649639604fb]
core/internal/gc/proxy.d:156 [0x56496393cf70]
rt/lifetime.d:130 [0x5649639235fe]
app.d:10 [0x56496391a7af]
rt/dmain2.d:520 [0x56496392169c]
rt/dmain2.d:474 [0x5649639214b2]
rt/dmain2.d:520 [0x5649639215ba]
rt/dmain2.d:474 [0x5649639214b2]
rt/dmain2.d:545 [0x564963921372]
rt/dmain2.d:333 [0x564963921040]
/home/denizzz/ldc2_standalone/bin/../import/core/internal/entrypoint.d:42 [0x56496391a7f1]
??:? [0x7fa30e6f6ca7]
??:? __libc_start_main [0x7fa30e6f6d64]
??:? [0x56496391a6d0]
GC.fullCollect()
processing GC Marks, (nil)
rt_finalize2(p = 0x5649a1312c20)
Error Program exited with code 1
Am I making an obvious mistake somewhere?