c - 为什么调用 setjmp() 中的函数会发生段错误?

标签 c multithreading segmentation-fault fiber setjmp

我不明白为什么在函数 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 the setjmp macro in the same invocation of the program with the corresponding jmp_buf argument. If there has been no such invocation, [...] or if the function containing the invocation of the setjmp macro has terminated execution248) in the interim [...] the behavior is undefined.

248) For example, by executing a return statement or because another longjmp call has caused a transfer to a setjmp invocation in a function earlier in the set of nested calls.

在你的代码中 middleFunc 设置了 middle 然后通过执行 longjmp(start,1)< 立即退出到 main/。之后跳转 middle 不再有效。您不再被允许从任何地方跳转到 middlesetjmp/longjmp 机制只支持向上跳转调用栈。你不能做侧跳或下跳。仅支持向上跳跃。

从实际的角度来看,您正试图跳入“死”函数调用并以某种方式期望函数参数值仍然有效(例如,从上一次调用中保留下来或其他)。但他们不是。 setjmp/longjmp 不保留/恢复参数值。 entry_point 在该“死”调用中的值可能是 some garbage .当您尝试通过 entry_point 进行调用时,代码核心转储。

附言确实,有时使用 setjmp/longjmp 进行侧跳来实现协程。但是,这种用法超出了标准库规范的范围。在任何情况下,这种用法都不会期望保留参数值。

关于c - 为什么调用 setjmp() 中的函数会发生段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51545566/

相关文章:

java - 竞争条件是否会出现在下面的代码中

c - 给定的代码有什么问题

c - 未知长度和输入的多重要求

java - 如何获取线程的开始时间和结束时间?

multithreading - iOS4 & 背景 [UIImage setImage :]

c - 为什么我收到段错误 : 11

C 指针,段错误

c - 在编译时验证宏参数大小

c - 在 .h 文件中哪里可以找到这些类型

c - if语句检查里面是否有一个char指针是做什么的