我不明白为什么在函数 middleFunc()
中,当 entry_point(arg)
在 if ( setjmp(中间) )
语句。
#include <stdio.h>
#include <setjmp.h>
jmp_buf start,middle,end;
void finalFunc(void *v)
{
printf("hello\n");
return ;
}
void middleFunc(void (*entry_point)(void *), void *arg)
{
//just debug : this does not cause segmentation fault
entry_point(arg);
if ( setjmp(middle) ){
//this casues the segmentation fault
entry_point(arg);
//once the entry point (finalFunc) is executed go to jmp_buffer end
longjmp(end,1);
}
else {
longjmp(start,1);
}
}
int main(){
if (setjmp(end)){
//exit since finalFunc has been executed
return 0;
}
if (setjmp(start)){
//the middleFunc has previously set the jmp_buffer middle
longjmp(middle,1);
}
else{
int x = 1;
middleFunc(finalFunc,(void*)&x);
}
}
最佳答案
在您的代码中,行为未定义。在 middleFunc
完成执行后(通过正常完成或通过另一个 longjmp
),您不允许长跳转到 middle
。
7.13.2.1 The longjmp function
2 The
longjmp
function restores the environment saved by the most recent invocation of thesetjmp
macro in the same invocation of the program with the correspondingjmp_buf
argument. If there has been no such invocation, [...] or if the function containing the invocation of thesetjmp
macro has terminated execution248) in the interim [...] the behavior is undefined.248) For example, by executing a
return
statement or because anotherlongjmp
call has caused a transfer to asetjmp
invocation in a function earlier in the set of nested calls.
在你的代码中 middleFunc
设置了 middle
然后通过执行 longjmp(start,1)< 立即退出到
。之后跳转 main
/middle
不再有效。您不再被允许从任何地方跳转到 middle
。 setjmp/longjmp
机制只支持向上跳转调用栈。你不能做侧跳或下跳。仅支持向上跳跃。
从实际的角度来看,您正试图跳入“死”函数调用并以某种方式期望函数参数值仍然有效(例如,从上一次调用中保留下来或其他)。但他们不是。 setjmp/longjmp
不保留/恢复参数值。 entry_point
在该“死”调用中的值可能是 some garbage .当您尝试通过 entry_point
进行调用时,代码核心转储。
附言确实,有时使用 setjmp/longjmp
进行侧跳来实现协程。但是,这种用法超出了标准库规范的范围。在任何情况下,这种用法都不会期望保留参数值。
关于c - 为什么调用 setjmp() 中的函数会发生段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51545566/