setjmp longjmp在Netbeans cygwin下崩溃Windows XP
以下是普渡大学CS类给出的示例代码。为了调试目的,我对原版做了很少的改动。您可以在https://www.cs.purdue.edu/homes/cs240/lectures/Lecture-19.pdf处看到原始代码。我正面临的问题在代码段下面描述。setjmp longjmp在Netbeans cygwin下崩溃Windows XP
#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()返回非零”。根据我对setjmp/longjmp的理解,我并不期待打印出“In main:end”,因为控制永远不会到达那里。
我怀疑这可能是一个调试器问题,因为当我通过程序(没有函数a()中的printf)时,调试器以预期的方式达到longjmp。当longjmp被执行时,调试器不会停止任何地方 - 它只是打印“In main:end”并终止程序。我在main()中引入了i ++来查看调试器是否会在打印之前停止。但是,在步入longjmp()的时候,Netbeans并没有停在那里,整个程序快速完成。
这种行为的原因是什么?在第一种情况下(当printf存在于函数a())中时,段错误的原因是什么?堆栈展开的方式是指针'str'被搞乱了吗?为什么?如果任何人有权访问UNIX机器,我希望看到该系统和程序行为的输出。感谢您的意见。
©ISO/IEC ISO/IEC 9899:201X 编程语言 - Visual C
7.13.2.1 longjmp函数
2 longjmp函数恢复由最 最近调用保存的环境在调用 程序时使用相应的jmp_buf参数调用setjmp宏...如果包含调用setjmp 宏的函数在此期间终止执行...行为未定义。
由于a()
已经终止执行,在b()
使用longjmp()
是错误的,因此,C标准并没有规定行为要求和它是好的为程序崩溃。