What is weird about setjmp and longjmp wrappers?

I am using setjmp and longjmp for the first time, and I run into a problem that occurs when I wrap setjmp and longjmp. I threw the code back 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 that 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 spend the program in gdb, I see that although mywrap_save () returns 1, the else branch after the return is strangely ignored. Can anyone explain what is happening?

+4
source share
2 answers
  The longjmp() routines may not be called after the routine which called the setjmp() routines returns. 

In other words, you spin your stack.

You can take a look at the assembly to see if you can combine what is actually happening.

+10
source

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

In your code, when returning from mywrap_save() marked point is no longer valid, the stack space around the point was dirty, so you cannot return to the dirty point.

+1
source

Source: https://habr.com/ru/post/1307595/


All Articles