标签归档:非本地跳转

非本地跳转

摘自《深入理解计算机系统》
C提供一种形式的用户级异常控制流,称为非本地跳转。它可以将控制直接从一个函数转移到另一个当前正在执行的函数。而不需要经过正常的调用-返回序列。在linux c中非本地跳转是通过 setjmp longjmp函数实现。
函数所属头文件 #include < setjmp.h>
函数原型:int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env,int savesigs);
返回值: setjmp 返回 0 ,longjmp返回非零
函数原型:void longjmp(jmp_buf env, int retval);
void siglongjmp(sigjmp_buf env,int retval);
setjmp函数的主要功能是在env缓冲区中保存当前栈的内容,供后面longjmp使用,并返回0。
longjmp函数从env缓冲区恢复栈的内容,然后触发一个从最近一次初始化env的setjmp调用返回,然后setjmp返回,并带用非零的返回值retval。
1 非本地跳转中一个很重要的应用是允许一个深层嵌套的函数调用中立即返回,通常是由检测到某个错误情况引起。如果在一个深层嵌套的函数调用中发现一个错误情况,就可以直接使用本地跳转直接返回到一个普通的本地化的错误处理程序,而不用去调用栈。
例1:
setjmp函数应用

从例1 我们可以看出,当我们在fun1中验证发现系统存在错误时,可以通过longjmp将函数返回至发最近一次调用setjmp的位置 ,图中 应该为返回至setjmp下的printf(“test information success!”);

2 非本地跳转的另一个重要应用是使一个信号处理程序转移到一个特殊的代码位置,而不是返回到被信号到达中断了的指令位置。
sigsetjmp函数应用
从例2中,我们可以看出使用非本地跳转的方式,可以使用改变信号处理函数的跳转至发生中断的位置。

综上所述:非本地跳转的方式,使程序可以不用调用其他函数,直接返回至最近一次设置setjmp的位置重新执行程序。