以下是普渡大學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機器,我希望看到該系統和程序行爲的輸出。感謝您的意見。