Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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() == 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?

like image 777
Max Avatar asked Dec 23 '22 03:12

Max


2 Answers

 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.

like image 124
WhirlWind Avatar answered Dec 26 '22 12:12

WhirlWind


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.

like image 20
Jimmy Zhang Avatar answered Dec 26 '22 11:12

Jimmy Zhang