c - setjmp longjmp 在 Netbeans cygwin Windows XP 下崩溃

标签 c crash segmentation-fault cygwin setjmp

以下是普渡大学计算机科学类(class)中给出的示例代码。出于调试目的,我对原始版本做了很少的更改。原始代码可以在 https://www.cs.purdue.edu/homes/cs240/lectures/Lecture-19.pdf 看到。我面临的问题在代码片段下面进行了描述。

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>

int a(char* str, jmp_buf aenv) {
    int i;
    i = setjmp(aenv);
    // i ++; i--;
    printf("In func a: str = %s, i=%d\n", str, i);      #crash causing printf
    return i;
}
int b(int j, jmp_buf benv) {
    printf("In func b: j= %d\n",j);
    longjmp(benv, j);      # segfault crash happens here, only if printf is present
}
int main(int argc, char** argv) {
    jmp_buf main_env;
    char *arr;
    arr = (char*) malloc(100);
    strcpy(arr, "As if called From main");
    if  ( a(arr, main_env)) {
        printf("In main: a() returned non-zero\n"); 
        exit(EXIT_SUCCESS);
    }
    b(3, main_env);
    int i=1;
    i++;
    printf("In main: end \n");
    return (EXIT_SUCCESS);
}

平台是 Windows XP 中的 Netbeans IDE 7.3 和 cygwin 1.7(最新)。当我运行这个程序时,输出是

      In func a: str = As if called From main, i=0
      In func b: j= 3

当我单步执行调试器时,我看到调用 longjmp() 时发生崩溃。程序运行,但如果我删除函数 a() 中的 printf,则会在调试器中出现意外行为。如果我删除 printf 并运行程序,则不会发生崩溃并且输出为

      In func b: j= 
      In main: end

我在网上阅读了一些有关 setjmp/longjmp 的文档,并且我是专业人士。我的期望是调用 longjmp() 会将程序状态和执行带到 setjmp,它位于另一个函数中。这个函数 a() 应该返回 3 给 main。因此,main() 中的 if 条件为 TRUE,我应该看到打印输出“In main: a() returned non-zero”。我没想到会打印出“In main: end”,因为根据我对 setjmp/longjmp 的理解,控制永远不应该到达那里。

我怀疑这可能是调试器问题,因为当我单步执行程序时(函数 a() 中没有 printf ),调试器以预期方式到达 longjmp 。当执行 longjmp 时,调试器不会在任何地方停止 - 它只是打印“In main: end”并且程序终止。我在 main() 中引入了 i++ 来查看调试器是否会在打印之前停止在该点。但 Netbeans 并没有就此停止,当进入 longjmp() 时,整个程序很快完成。

这种行为的原因是什么?在第一种情况下(当 printf 出现在函数 a() 中时),段错误的原因是什么?堆栈展开是否会导致指针“str”困惑?为什么 ?如果有人可以访问 UNIX 机器,我希望看到该系统的输出和程序行为。感谢您的评论。

最佳答案

©ISO/IEC ISO/IEC 9899:201x 编程语言——C

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 the function containing the invocation of the setjmp macro has terminated execution in the interim... the behavior is undefined.

由于a()已经终止执行,在b()中使用longjmp()是错误的,因此C标准强制没有行为要求,程序崩溃是可以接受的。

关于c - setjmp longjmp 在 Netbeans cygwin Windows XP 下崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23232947/

相关文章:

c - 什么是实现简单的基于 clone() 的多线程库的好方法?

android - Android 应用程序崩溃后向服务器发送日志文件

iphone - 导航时 iPhone OpenGL 应用程序随机崩溃

c++ - 作用域结束后重新分配

c - C中使用Malloc正确分配二维数组

c - 在 HDD 上存储大哈希

C 灵活数组与指针

android - 我的应用程序不断崩溃(致命异常)

c - 访问全局数组会导致段错误

c - 文件描述符是其进程的本地文件描述符还是 Unix 上的全局文件描述符