2012-01-19 131 views
5

這裏是我設置我的處理程序的代碼SIGABRT信號,然後我打電話abort()但處理程序不被觸發,而是程序會中止,爲什麼?如何處理SIGABRT信號?

#include <iostream> 
#include <csignal> 
using namespace std; 
void Triger(int x) 
{ 
    cout << "Function triger" << endl; 
} 

int main() 
{ 
    signal(SIGABRT, Triger); 
    abort(); 
    cin.ignore(); 
    return 0; 
} 

程序輸出:

enter image description here

+0

完美的作品在這裏,我包括''後。哪個平臺? –

+0

使用MSVC++ 2010的Windows 7 x64(不需要在visual studio中包含cstdlib) – codekiddy

+1

那麼程序應該被中止,除非信號處理程序執行'longjmp'。如果您希望在此之前打印消息,則可能需要刷新'std :: cout'(或寫入'std :: cerr')。 –

回答

11

正如其他人所說,你不能有abort()返回並允許執行正常繼續。然而,你可以做的是保護一段代碼,可能會被類似於try catch的結構調用中止。代碼的執行將被中止,但程序的其餘部分可以繼續。這裏是一個演示:

#include <csetjmp> 
#include <csignal> 
#include <cstdlib> 
#include <iostream> 

jmp_buf env; 

void on_sigabrt (int signum) 
{ 
    longjmp (env, 1); 
} 

void try_and_catch_abort (void (*func)(void)) 
{ 
    if (setjmp (env) == 0) { 
    signal(SIGABRT, &on_sigabrt); 
    (*func)(); 
    } 
    else { 
    std::cout << "aborted\n"; 
    } 
}  

void do_stuff_aborted() 
{ 
    std::cout << "step 1\n"; 
    abort(); 
    std::cout << "step 2\n"; 
} 

void do_stuff() 
{ 
    std::cout << "step 1\n"; 
    std::cout << "step 2\n"; 
}  

int main() 
{ 
    try_and_catch_abort (&do_stuff_aborted); 
    try_and_catch_abort (&do_stuff); 
} 
+0

似乎這個答案是未完成的。注意: ? – stanm

6

雖然可以更換爲SIGABRTabort()處理程序將注意處理,中止只有當信號處理程序不返回抑制。 C99中的相關報價在7.20.4.1第2段中:

中止函數會導致程序異常終止,除非信號SIGABRT被捕獲且信號處理程序不返回。 ...

您的信號處理程序確實返回,因此程序被中止。

+0

所以你說上面的try_and_catch_abort只能在調試模式下工作,而不能用於發佈的代碼? – Michele

2

你得到那些症狀,即彈出對話框調試,當你有一個調試版本(Windows和視覺工作室 - 我與2012版的測試),因爲它設置一個調試中斷,在abort()的調試實現中)。 如果你選擇「忽略」你得到的消息「功能TRIGER」

如果你做一個發佈版本,那麼你沒有得到調試彈出的對話框中,你得到的消息,如預期