2012-01-19 135 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”

如果你做一个发布版本,那么你没有得到调试弹出的对话框中,你得到的消息,如预期