开发者

Problem with setjmp/longjmp

The code below is just not working. Can anybody point out wh开发者_StackOverflowy

#define STACK_SIZE 1524

static void mt_allocate_stack(struct thread_struct *mythrd)

{

    unsigned int sp = 0;
    void *stck;

    stck = (void *)malloc(STACK_SIZE);

    sp = (unsigned int)&((stck));
    sp = sp + STACK_SIZE;
    while((sp % 8) != 0)
    sp--;

#ifdef linux

    (mythrd->saved_state[0]).__jmpbuf[JB_BP] = (int)sp;
    (mythrd->saved_state[0]).__jmpbuf[JB_SP] = (int)sp-500;
#endif

}

void mt_sched()

{

    fprintf(stdout,"\n Inside the mt_sched");
    fflush(stdout);

    if ( current_thread->state == NEW )
     {
         if ( setjmp(current_thread->saved_state) == 0 )
         {
            mt_allocate_stack(current_thread);

            fprintf(stdout,"\n Jumping to thread = %u",current_thread->thread_id);
            fflush(stdout);
            longjmp(current_thread->saved_state, 2);
         }
         else
         {
            new_fns();
         }
      }
}

All I am trying to do is to run the new_fns() on a new stack. But is is showing segmentation fault at new_fns().

Can anybody point me out what's wrong.


Apart all other considerations, you are using "&stck" instead ok "stck" as stack! &stck points to the cell containing the POINTER TO the allocated stack

Then, some observations:

1) setjmp is not intended for this purpose: this code may work only on some systems, and perhaps only with som runtime library versions.

2) I think that BP should be evaluated in some other way. I suggest to check how you compiled composes a stack frame. I.e., on x86 platforms EBP points to the base of the local context, and at *EBP you can find the address of the base of the calling context. ESP points to EBP-SIZE_OF_LOCAL_CONTEXT, different compilers usually compute that size in a different way.

As far as I can see, you are implementig some sort of "fibers". If you are working on Win32, there is aready a set of function that implements in a safe way this functionality (see "fibers"). On linux I suggest you to have a look to "libfiber".

Regards

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜