GC collecting "too much"..

simendsjo simendsjo at gmail.com
Thu Mar 29 06:52:28 PDT 2012


On Thu, 29 Mar 2012 14:14:10 +0200, simendsjo <simendsjo at gmail.com> wrote:

> On Mon, 26 Mar 2012 20:15:40 +0200, simendsjo <simendsjo at gmail.com>  
> wrote:
>
>> On Mon, 26 Mar 2012 17:10:34 +0200, Timon Gehr <timon.gehr at gmx.ch>  
>> wrote:
>>
>>> On 03/26/2012 11:55 AM, simendsjo wrote:
>>>> It seems threads created in the c library is totally unknown to D. How
>>>> can I make D aware of these threads when there is no library support  
>>>> for
>>>> it?
>>>
>>> You may be looking for this:
>>> http://dlang.org/phobos/core_thread.html#thread_attachThis
>>
>> Thanks, but I tried that too and couldn't get it to work.
>>
>> I added the following:
>>
>> extern(C) handler()
>> {
>>      synchronized // needed here to avoid the GC to collect while  
>> attaching thread?
>>      {
>>          if(!Thread.getThis()) // thread unknown to D
>>          {
>>              thread_attachThis();
>>              assert(Thread.getThis()); // now D knows about it
>>          }
>>      }
>>      GC.collect(); // still segfaults
>> }
>>
>> Actually, using attachThis segfaults GC.collect() outside the thread  
>> handling code too.

I compiled with a debug build of druntime, and it fails on dereferencing a  
pointer, pbot in gcx.d:2511:

void mark(void *pbot, void *ptop, int nRecurse)
         void **p1 = cast(void **)pbot;
(...)
         for (; p1 < p2; p1++)
         {
             auto p = cast(byte *)(*p1); // segfault!
(...)

gdb) print p1
$10 = (void **) 0xf74fc000
(gdb) print *p1
$11 = (void *) 0x0

Some more dbg info:

(gdb) bt
#0  0x08098753 in gc.gcx.Gcx.mark() (this=0x80df030, nRecurse=64,  
ptop=0xffffd190, pbot=0xf74f4df4) at src/gc/gcx.d:2511
#1  0x080986d6 in gc.gcx.Gcx.mark() (this=0x80df030, ptop=0xffffd190,  
pbot=0xf74f4df4) at src/gc/gcx.d:2494
#2  0x0809ef95 in core.thread.thread_scanAll() (this=0xf74f4cf8,  
p2=0xffffd190, p1=0xf74f4df4, type=<incomplete type>)
     at src/core/thread.d:2743
#3  0x080a6488 in thread_scanAllType (scan=..., curStackTop=0xf74f4df4) at  
src/core/thread.d:2698
#4  0x0809ef68 in thread_scanAll (scan=..., curStackTop=0xf74f4df4) at  
src/core/thread.d:2746
#5  0x08098c34 in gc.gcx.Gcx.fullcollect() (this=0x80df030,  
stackTop=0xf74f4df4) at src/gc/gcx.d:2776
#6  0x080989f9 in gc.gcx.Gcx.fullcollectshell() (this=0x80df030) at  
src/gc/gcx.d:2662
#7  0x08096da1 in gc.gcx.GC.fullCollect() (this=0x80df018) at  
src/gc/gcx.d:1372
#8  0x08086da6 in gc_collect () at src/gc/gc.d:154
#9  0x08085380 in core.memory.GC.collect() () at src/core/memory.d:101
#10 0x08080e2c in c_callback (event=<incomplete type>, conn=0x80ebec0,  
request_info=0x80ebec0) at main.d:54
#11 0xf7fd28c1 in handle_request(mg_connection*) () from ./libmongoose.so
#12 0xf7fd4b7d in worker_thread(mg_context*) () from ./libmongoose.so
#13 0xf7f8dd1a in start_thread (arg=0xf74fbb70) at pthread_create.c:304
#14 0xf7ed5e4e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
Backtrace stopped: Not enough registers or memory available to unwind  
further
(gdb) l 2511
2506            uint changes = 0;
2507
2508            //printf("marking range: %p -> %p\n", pbot, ptop);
2509            for (; p1 < p2; p1++)
2510            {
2511                auto p = cast(byte *)(*p1);
2512
2513                //if (log) debug(PRINTF) printf("\tmark %p\n", p);
2514                if (p >= minAddr && p < maxAddr)
2515                {



> And if I change the code to:
> extern(C) handler()
> {
>      GC.collect();
> }
(snip)
Checking with debug build of druntime, and I see it tries to  
suspend(thread_getThis()). This gives a null reference error as  
thread_getThis() returns null when it's not attached.


More information about the Digitalmars-d-learn mailing list