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