开发者

What is weird about wrapping setjmp and longjmp?

I am using setjmp and longjmp for the first time, and I ran across an issue that comes about when I wrap setjmp and longjmp. I boiled the code down to the following example:

#include <stdio.h>
#include <setjmp.h>

jmp_buf jb;

int mywrap_save()
{
  int i = setjmp(jb);
  return i;
}

int mywrap_call()
{
  longjmp(jb, 1);
  printf("this shouldn't appear\n");
}

void example_wrap()
{
  if (mywrap_save() ==开发者_Go百科 0){
    printf("wrap: try block\n");
    mywrap_call();
  } else {
    printf("wrap: catch block\n");
  }
}

void example_non_wrap()
{
  if (setjmp(jb) == 0){
    printf("non_wrap: try block\n");
    longjmp(jb, 1);
  }  else {
    printf("non_wrap: catch block\n");
  }
}

int main()
{
  example_wrap();
  example_non_wrap();
}

Initially I thought example_wrap() and example_non_wrap() would behave the same. However, the result of running the program (GCC 4.4, Linux):

wrap: try block
non_wrap: try block
non_wrap: catch block

If I trace the program in gdb, I see that even though mywrap_save() returns 1, the else branch after returning is oddly ignored. Can anyone explain what is going on?


 The longjmp() routines may not be called after the routine which called
 the setjmp() routines returns.

In other words, you are screwing up your stack.

You might take a look at the assembly to see if you can piece together what's really happening.


setjmp() will save the current call stack and mark a point. When the call stack grows, no matter how far from the marked point, you can use longjmp() to go to the marked point, like you never left the point.

In your code, when returning from mywrap_save(), the marked point was no longer valid, the stack space around the point was dirty, hence you cannot go back to a dirty point.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜