Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

[Mac OS X 10.5.8 + LDC] recursion in gc.collect on app exit

Moderators: kris

Posted: 10/21/09 15:02:09 Modified: 10/21/09 15:12:24

Hi, Tango Team,

i'm using today's trunks of LLVM, LDC and Tango on Mac Mini (Intel) with Mac OS X 10.5.8. There's a stable segfault on exit of every application, built with that toolchain, and some apps like xfbuild do not even launch.

The problem of infinite recursion is an assertion in runtime/gc/basic/rt/basicgc/gcx.d:3059 in body of gc's invariant() that creates an exception, but allocation of that exception and creating an object for it calls that invariant() too, and such loop allocs more and more memory until there's no more and alloc fails, after that an application segfaults trying to read allocated memory (for new Object of an exception) that is null.

What's the original problem that causes an assertion, i don't know, but i've collected some info on it. Here's the beginning of backtrace of a simplest D console app:

#230578 0x00015821 in _d_assert (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at rt.dmain2.d:60
#230579 0x0000e66e in _D2rt7basicgc3gcx4Pool11__invariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3060
#230580 0x0000e605 in _D2rt7basicgc3gcx4Pool9InvariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3045
#230581 0x0000b342 in _D2rt7basicgc3gcx3Gcx11__invariantMFZv (this=0x100210) at rt.basicgc.gcx.d:1618
#230582 0x0000b0d5 in _D2rt7basicgc3gcx3Gcx16thread_InvariantMFZv (this=0x100210)
#230583 0x0000a102 in _D2rt7basicgc3gcx2GC11__invariantMFZv (this=0x100130) at rt.basicgc.gcx.d:322
#230584 0x00014d61 in _d_invariant (o=0x100130) at rt.invariant_.d:24
#230585 0x00009024 in _D2rt7basicgc3gcx2GC6mallocMFkkZPv (this=0x100130, size=36, bits=1) at rt.basicgc.gcx.d:482
#230586 0x0000767c in gc_malloc (sz=36, ba=1) at rt.basicgc.gc.d:156
#230587 0x0000fa3d in _d_allocclass (ci=0x3f100) at rt.lifetime.d:127
#230588 0x00002ad4 in onAssertError (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at tango.core.Exception.d:442
#230589 0x00015821 in _d_assert (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at rt.dmain2.d:60
#230590 0x0000e66e in _D2rt7basicgc3gcx4Pool11__invariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3060
#230591 0x0000e605 in _D2rt7basicgc3gcx4Pool9InvariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3045
#230592 0x0000b342 in _D2rt7basicgc3gcx3Gcx11__invariantMFZv (this=0x100210) at rt.basicgc.gcx.d:1618
#230593 0x0000b0d5 in _D2rt7basicgc3gcx3Gcx16thread_InvariantMFZv (this=0x100210)
#230594 0x0000a102 in _D2rt7basicgc3gcx2GC11__invariantMFZv (this=0x100130) at rt.basicgc.gcx.d:322
#230595 0x00014d61 in _d_invariant (o=0x100130) at rt.invariant_.d:24
#230596 0x00009024 in _D2rt7basicgc3gcx2GC6mallocMFkkZPv (this=0x100130, size=36, bits=1) at rt.basicgc.gcx.d:482
#230597 0x0000767c in gc_malloc (sz=36, ba=1) at rt.basicgc.gc.d:156
#230598 0x0000fa3d in _d_allocclass (ci=0x3f100) at rt.lifetime.d:127
#230599 0x00002ad4 in onAssertError (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at tango.core.Exception.d:442
#230600 0x00015821 in _d_assert (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at rt.dmain2.d:60
#230601 0x0000e66e in _D2rt7basicgc3gcx4Pool11__invariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3060
#230602 0x0000e605 in _D2rt7basicgc3gcx4Pool9InvariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3045
#230603 0x0000b342 in _D2rt7basicgc3gcx3Gcx11__invariantMFZv (this=0x100210) at rt.basicgc.gcx.d:1618
#230604 0x0000b0d5 in _D2rt7basicgc3gcx3Gcx16thread_InvariantMFZv (this=0x100210)
#230605 0x0000a102 in _D2rt7basicgc3gcx2GC11__invariantMFZv (this=0x100130) at rt.basicgc.gcx.d:322
#230606 0x00014d61 in _d_invariant (o=0x100130) at rt.invariant_.d:24
#230607 0x00009024 in _D2rt7basicgc3gcx2GC6mallocMFkkZPv (this=0x100130, size=36, bits=1) at rt.basicgc.gcx.d:482
#230608 0x0000767c in gc_malloc (sz=36, ba=1) at rt.basicgc.gc.d:156
#230609 0x0000fa3d in _d_allocclass (ci=0x3f100) at rt.lifetime.d:127
#230610 0x00002ad4 in onAssertError (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at tango.core.Exception.d:442
#230611 0x00015821 in _d_assert (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at rt.dmain2.d:60
#230612 0x0000e66e in _D2rt7basicgc3gcx4Pool11__invariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3060
#230613 0x0000e605 in _D2rt7basicgc3gcx4Pool9InvariantMFZv (this=0x1002c0) at rt.basicgc.gcx.d:3045
#230614 0x0000b342 in _D2rt7basicgc3gcx3Gcx11__invariantMFZv (this=0x100210) at rt.basicgc.gcx.d:1618
#230615 0x0000ba7b in _D2rt7basicgc3gcx3Gcx8findPoolMFPvZPS2rt7basicgc3gcx4Pool (this=0x100210, p=0x203fc0) at rt.basicgc.gcx.d:1763
#230616 0x0000ceca in _D2rt7basicgc3gcx3Gcx11fullcollectMFPvZk (this=0x100210, stackTop=0xbffff710) at rt.basicgc.gcx.d:2418
#230617 0x0000cd4a in _D2rt7basicgc3gcx3Gcx16fullcollectshellMFZk (this=0x100210) at rt.basicgc.gcx.d:2365
#230618 0x00009d7f in _D2rt7basicgc3gcx2GC11fullCollectMFZv (this=0x100130) at rt.basicgc.gcx.d:1325
#230619 0x000074fd in gc_term () at rt.basicgc.gc.d:113
#230620 0x00015ceb in _D2rt6dmain24mainUiPPaPPaZi6runAllMFZv () at rt.dmain2.d:272
#230621 0x00015bcb in _D2rt6dmain24mainUiPPaPPaZi7tryExecMFDFZvZv () at rt.dmain2.d:227
#230622 0x00015b5f in main (argc=1, argv=0xbffff874, env=0xbffff87c) at rt.dmain2.d:275

There are 3 same pars here, they are same in backtrace log until the segfault:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0xbf7fffec
0x0000b0d0 in _D2rt7basicgc3gcx3Gcx16thread_InvariantMFZv (this=0x100210)
(gdb) bt
#0  0x0000b0d0 in _D2rt7basicgc3gcx3Gcx16thread_InvariantMFZv (this=0x100210)
#1  0x0000a102 in _D2rt7basicgc3gcx2GC11__invariantMFZv (this=0x100130) at rt.basicgc.gcx.d:322
#2  0x00014d61 in _d_invariant (o=0x100130) at rt.invariant_.d:24
#3  0x00009024 in _D2rt7basicgc3gcx2GC6mallocMFkkZPv (this=0x100130, size=36, bits=1) at rt.basicgc.gcx.d:482
#4  0x0000767c in gc_malloc (sz=36, ba=1) at rt.basicgc.gc.d:156
#5  0x0000fa3d in _d_allocclass (ci=0x3f100) at rt.lifetime.d:127
#6  0x00002ad4 in onAssertError (file={length = 95, ptr = 0x2adc0 "/Users/ezheleznikov/Documents/d/src/tango/build/runtime/../../runtime/gc/basic/rt/basicgc/gcx.d"}, line=3060) at tango.core.Exception.d:442

Here's the code that asserts (gcx.d:3059):

invariant
    {
        //mark.Invariant();
        //scan.Invariant();
        //freebits.Invariant();
        //finals.Invariant();
        //noscan.Invariant();

        if (baseAddr)
        {
            if (baseAddr + npages * PAGESIZE != topAddr)
                printf("baseAddr = %p, npages = %d, pagesize = %d, topAddr = %p\n", baseAddr, npages, PAGESIZE, topAddr);

            assert(baseAddr + npages * PAGESIZE == topAddr);  '''<== that fails'''
            assert(ncommitted <= npages);
        }

        for (size_t i = 0; i < npages; i++)
        {   Bins bin = cast(Bins)pagetable[i];

            assert(bin < B_MAX);
        }
    }

I've uncommented printf logging and got at runtime the same string for a couple of thousand times:

baseAddr = 0x200001, npages = 256, pagesize = 4096, topAddr = 0x300000

256 * 4096 == 0x100000, and the sum is 0x300001, that's why it asserts every time (in an infinite loop until alloc fails). So, the reason is 0x000001 odd.

I hope you'll find a way to fix it or at least will give me some hints on it.

Author Message

Posted: 10/21/09 15:42:18

It's Pool's invariant, but in its initialize func (line 2974) everything is ok:

poolSize is 1048576, baseAddr is 0x200000, topAddr is 0x300000

Posted: 10/26/09 09:57:43

The problem exists with llvm2.6/ldc trunk, too (mac 10.5.8 intel 32bit).