Nonlocal Jumps
Prev: Signals
TOC: Exceptional Control Flow
- a form of user level exception control flow that transfers control directly from one function to another currently executing function w/o having to go through the normal call and return sequence.
- It's provided by setjmp and longjmp.
#include <setjmp.h>
int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs);
Returns: 0 from setjmp, nonzero from longjmps
- it saves the current calling environment in the env buffer for later use by longjmp and returns 0.
- The calling env includes program counter, stack pointer, gen purpose registers etc.
- And we should not assign the value returned from setjmp to our a variable cuz when coming from longjmp, our registers will be restored to previous value, and having one of the stuff changed (from prev 0 to now something else) could cause crash (not full reason but smthing similar).
- But we can use the expression itself as a test in swtich or condn statement
#include <setjmp.h>
void longjmp(jmp_buf env, int retval);
void siglongjmp(sighmp_buf env, int retval);
Never returns
- longjmp restores the calling environment from the env buffer and then triggers a return from the most recent setjmp call that initialized env.
- the setjmp then returns w non-zero return value retvalue.
- setjmp is called once and can return multiple times (with multiple longjmp calls), but longjmp is called once and never returns.
- A longjmp can only jump down a stack that currently exists and is in the call stack up somewhere, if it hasn't been called yet or worse has been returned the behaviour is undefined.
- siglongjmp and sigsetjmp are signal handling versions of a functions
- Example usage:
#include "csapp.h"
sighmp_buf buf;
void hanlder(int sig){
siglongjmp(buf, 1);
}
int main(){
if(!sigsetjmp(buf, 1)){
Signal(SIGINT, handler);
Sio_put("starting\n");
}
else
Sio_put("restarting\n");
while(1){
sleep(1);
Sio_puts("processing--\n");
}
exit(0);
}
- here to avoid race we put handler AFTER we put sigsetjmp, that way there is no possible of having undefined behaviour where SIGINT leads to siglongjmp to some undefined place.
- note that the second arg to sigsetjmp (which is non existent in setjmp) is to tell the system whether or not to remember the current signal mask.
Prev: Signals
TOC: Exceptional Control Flow