[英]failure of setjmp/longjmp
一段代码
jmp_buf mark;
int Sub_Func()
{
int be_modify, jmpret;
be_modify = 0;
jmpret = setjmp( mark );
if( jmpret == 0 )
{
// sth else here
}
else
{
// error handle
switch (jmpret)
{
case 1:
printf( "Error 1\n");
break;
case 2:
printf( "Error 2\n");
break;
case 3:
printf( "Error 3\n");
break;
default :
printf( "Unknown Error");
break;
}
printf("after switch\n");
}
return jmpret;
}
void main( void )
{
Sub_Func();
// the longjmp after setjmp
longjmp(mark, 1);
}
结果是:
错误1
切换后
分段故障
我知道原因也许longjmp跳回了以前的堆栈。 但是我不确定细节,“标记”中存储了什么样的价值,有人可以解释吗?
setjmp()
和longjmp()
通过记录堆栈帧位置来工作。 如果将堆栈帧记录在Sub_Func()
但在调用longjmp()
之前从函数返回,则堆栈帧不再有效。 longjmp()
应该与setjmp()
在同一函数中调用(可以的子函数)。
您正在尝试将其跳转回更深层的功能。 您只能将longjmp返回到较浅的函数。
因此,如果A调用setjmp
,然后调用B,则B可以longjmp
返回A。
但是,如果A调用b,B调用setjmp
,则B返回A,而A 不能 longjmp
回B。
通过违反以下内容(7.13.2.1)调用了未定义的行为:
longjmp函数可在与相应的jmp_buf参数相同的程序调用中恢复由setjmp宏的最新调用保存的环境。 如果没有这样的调用,或者包含setjmp宏的调用的函数在此期间终止了执行217),或者setjmp宏的调用在具有可变修改类型的标识符的范围之内并且执行已经结束在此范围内,行为是不确定的。
217)例如,通过执行return语句,或者由于另一个longjmp调用已导致在嵌套调用集中较早的函数中转移到setjmp调用。
简而言之, longjmp
不能用于跳到已经返回的函数中的setjmp
点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.