It's not working as I hoped.

I'm seeing random crashes in v8 Locker class when I implement a JS thread 
that does some work, then spawns itself just before calling pthread_exit().

On OSX, I see the thread get respawned 15 times and it works like it 
should.  The 16th time, segfault.  I ran it under gdb and see this:

14020 test3 exiting 16
14020 test3 respawn 16
runner
a
b
c

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xfffffffffffffff8
[Switching to process 14020 thread 0x1923]
v8::internal::ExitFrame::GetStateForFramePointer (
    fp=<value temporarily unavailable, due to optimizations>, 
    state=0x105080400) at ../src/frames.cc:556
556 ../src/frames.cc: No such file or directory.
in ../src/frames.cc

However, spawning 1000 threads in the main program still works.

The runner, a, b, c lines are printf() I put in the code to see where it's 
dying.

The runner() function is a wrapper around entering v8 from a newly started 
thread. 

static void *runner(void *p) {
    printf("runner\n");
    ThreadInfo *t = (ThreadInfo *)p;
printf("a\n");    
    pthread_setspecific(tls_key, t);
printf("b\n");    
    pthread_detach(pthread_self());
    {
printf("c\n");    
        Locker loc;
printf("d\n");    
        HandleScope scope;
printf("e\n");    
        Handle<Value>v = t->o->Get(String::New("runHandler"));
printf("f\n");    
        if (v.IsEmpty()) {
printf("g\n");    
            printf("No runHandler\n");
printf("h\n");    
            pthread_exit(NULL);
        }
        else if (!v->IsFunction()) {
printf("i\n");    
            printf("No runHandler (not a function)\n");
printf("j\n");    
            pthread_exit(NULL);
        }
printf("k\n");    
        Handle<Function>func = Handle<Function>::Cast(v);
printf("l\n");    
        Handle<Value>av[1];
printf("m\n");    
        av[0] = t->o;
printf("n\n");    
        // TryCatch tryCatch;
        printf("CALL\n");
        v = func->Call(context->Global(), 1, av);

        // if (v.IsEmpty()) {
            // printf("Exception!");
            // ReportException(&tryCatch);
        // }
    }
    printf("exitx\n");
    pthread_exit(NULL);
}

You can see it's getting a Locker, and dying in the HandleScope creation.

The JS code looks like this:

function test3a() {
    log('test3a alive ' + this.threadId);
    this.on('exit', function() {
        log('test3a respawn ' + this.threadId);
        new Thread(test3);
        // while(1);
    });
    log('test3a sleeping ' + this.threadId);
    // sleep(1);
    log('test3a exiting ' + this.threadId);
}
function test3() {
    log('test3 alive ' + this.threadId);
    this.on('exit', function() {
        log('test3 respawn ' + this.threadId);
        new Thread(test3a);
        // while (1);
    });
    log('test3 sleeping ' + this.threadId);
    // sleep(1);
    log('test3 exiting ' + this.threadId);
}

function main() {
    // for (var i=0; i<1000; i++) {
        // sleep(2);
        // new Thread(test4);
    // }
    new Thread(test3);
    while (1) sleep(1);
}

The pthread create function looks like this:

static JSVAL create(JSARGS args) {
    ThreadInfo *t;
    t = new ThreadInfo;
    t->threadId = nextThreadId++;
    t->o = Persistent<Object>::New(args[0]->ToObject());
    {
        Unlocker ul;
        pthread_create(&t->t, NULL, runner, t);
    }
    return Integer::New(t->threadId);
}


(The source to runner posted above).


Also of note is if I throw an Error() from JS in a thread, it's caught, but 
the TryCatch doesn't seem to have valid data.

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to