...
After invoking longjmp()
, non-volatile-qualified local objects should not be accessed if their values could have changed since the invocation of setjmp()
. Their value in this case is considered indeterminate, and accessing them is undefined behavior. (See Undefined Behavior 121, 10.)
The longjmp()
function should never be used to return control to a function that has terminated execution. (See Undefined Behavior 120.)
...
Placing the call to setjmp()
in the if
statement and (, optionally) , comparing it with a constant integer removes the undefined behavior, as shown in this compliant solution.
...
Code Block | ||
---|---|---|
| ||
jmp_buf buf; unsigned char b[] = {0xe5, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}; int main(void) { if (setjmp(buf) == 0) { printf("setjmp() invoked\n"); } else { printf("longjmp() invoked\n"); } do_stuff(); return 0; } void do_stuff(void) { char a[8]; memcpy(a, b, 8); /* ... stuff ... */ longjmp(buf, 1); } void bad(void) { printf("Should not be called!\n"); exit(1); } |
In this compliant solution, there There is no risk of overwriting a return address because the stack frame of main()
(the function that invoked setjmp()
) is still on the stack; so when do_stuff()
is invoked, the two stack frames will not overlap.
Noncompliant Code Example
NonIn this noncompliant example, non-volatile-qualified objects local to the function that invoked the corresponding setjmp()
have indeterminate values after longjmp()
has been executed if their value has been changed since the invocation of setjmp()
.
...