2012-04-26 39 views
2

我有一個像循環運行的程序的shell;它接受幾個命令並執行所需的功能。 僅當調用「getout」命令時,程序纔會退出。使用siglongjmp有效

讓我們假設如果發生分段故障信號,我只是處理清理我的程序,而不是退出程序,我只是想留在裏面。 我可以使用siglongjmp()調用來實現這個功能。

我的問題:當我在恢復功能中再次運行我的shell程序,並且現在發生任何分段故障時,我的信號不會被清除,程序退出時會出現分段錯誤。

請提出一個解決方案:

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <setjmp.h> 
sigjmp_buf mark; 

void myhandler(int signo) 
{ 
my_action(); 
siglongjmp(mark,-1); 
} 

recover() 
{ 
my_program_loop(); 
} 

my_program_loop() 
{ 
/* accept some commands and do some functionality*/ 
/*some part of the code may cause segfault*/ 
} 


main() 
{ 
    if (sigsetjmp(mark,0) != 0) 
    { 
     printf("siglongjmp() is called\n"); 
     recover(); 
     exit(1); 
    } 

    struct sigaction myhandle; 
    myhandle.sa_handler = myhandler; 
    sigemptyset(&myhandle.sa_mask); 
    myhandle.sa_flags = 0; 
    sigaction(SEGSEGV, &myhandle, NULL); 

    my_program_loop(); 

} 

請幫助。

+2

避免在第一時間得到'SIGSEGV'。用'gcc -Wall -g'編譯你的代碼並用'gdb'調試它。也許使用'valgrind'來追蹤內存錯誤。 – 2012-04-26 09:20:37

+0

大聲笑,得到了解決辦法。在匆忙的事情中,我沒有保存當前的信號掩碼。當使用sigsetjmp(sigjmp_buf env,int savemask)時,如果savemask參數的值不是0,sigsetjmp()也會將調用線程的當前信號掩碼保存爲調用環境的一部分。如果sigsetjmp(mark,0)應該修改爲sigsetjmp(mark,1),並且它的工作原理很好,那麼 – user1225606 2012-04-26 09:27:57

回答

2

你應該有你的«my_program_loop»一個問題,我可以用這個代碼趕上很好的信號:

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

sigjmp_buf mark; 

void myhandler(int signo) { 
    printf("Sig caught\n"); 
    siglongjmp(mark, -1); 
} 

void my_program_loop(void) { 
    char *p = NULL; 
    *p = 5; 
} 

void recover(void) { 
    my_program_loop(); 
} 

int main(void) { 
    struct sigaction myhandle; 

    if (sigsetjmp(mark, 0) == -1) { 
     recover(); 
     exit(1); 
    } 

    myhandle.sa_handler = myhandler; 
    sigemptyset(&myhandle.sa_mask); 
    myhandle.sa_flags = 0; 
    sigaction(SIGSEGV, &myhandle, NULL); 

    my_program_loop(); 

    return 0; 
} 
+0

我可以知道你是否可以每次都捕獲它?在上面的代碼中,在main()中, – user1225606 2012-04-26 12:00:12