Netjans cygwin Windows XP下的setjmp longjmp崩溃

时间:2014-04-23 00:56:17

标签: c crash segmentation-fault cygwin longjmp

以下是Purdue University CS课程中给出的示例代码。出于调试目的,我对原始版本做了很少的更改。您可以在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()的调用将采用程序状态&amp;执行到setjmp,这是另一个函数。这个函数a(),应该返回3到main。因此,main()中的if条件为TRUE,我应该看到打印输出说&#34;在main中:a()返回非零&#34;。我没想到打印输出&#34;在主要:结束&#34;因为根据我对setjmp / longjmp的理解,控制永远不会到达那里。

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

这种行为的原因是什么?在第一种情况下(当printf出现在函数a()中时),segfault的原因是什么?堆栈是否以指针&#39; str&#39;搞砸了?为什么?如果有人有权访问UNIX机器,我希望看到该系统的输出和程序行为。感谢您的评论。

1 个答案:

答案 0 :(得分:0)

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

  

7.13.2.1 longjmp函数

     

2 longjmp功能可以恢复最多保存的环境   最近在同一个调用中调用了setjmp宏   程序与相应的jmp_buf参数...如果函数包含setjmp的调用   宏已暂时终止执行......行为未定义。

由于a()已终止执行,longjmp()b()的使用是错误的,因此C标准没有规定任何行为要求,程序可以崩溃。