为什么SIGSEGV的信号处理程序不能捕捉到我的C++抛出异常?

问题描述:

我是想看看是否SIGSEGV信号处理程序可以帮助对付C++的未处理的异常,我尝试它:为什么SIGSEGV的信号处理程序不能捕捉到我的C++抛出异常?

#include <stdio.h> 
#include <execinfo.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <unistd.h> 
void handler(int sig) { 
    void *array[10]; 
    size_t size = backtrace(array, 10); 
    fprintf(stderr, "Error: signal %d:\n", sig); 
    backtrace_symbols_fd(array, size, STDERR_FILENO); 
    exit(1); 
} 
int main() 
{ 
    signal(SIGSEGV, handler); 
    throw 1; 
} 

$ G ++ -g h.cpp -rdynamic & & ./a.out

扔“诠释” 中止(核心转储)

井的一个实例后终止调用,程序不打印崩溃调用堆栈像我期望的那样回溯。我的问题是:

只要它终止,是否通过任何信号像SIGSEGV? 是否有系统调用或posix api可以捕捉C++异常并打印出调用堆栈?

谢谢!

+0

罚球剂量抓与抓'(...)的' –

+0

可能的复制[从未处理的异常的c + +堆栈跟踪?](http://stackoverflow.com/questions/3355683/c-stack-trace-from-unhandled-exception)+异常不是分段违规(分段错误)。 – user1810087

+0

你为什么期望信号处理程序能够捕捉到这个问题? – juanchopanza

您可以安装std::set_terminate的终止处理程序 - 然后将调用已安装的处理程序以处理未处理的异常。没有强有力的保证,但很有可能调用abort导致调用终止处理程序发生在抛出异常的堆栈顶部,因此您仍然可以收集回溯。

此外,您还可以安装一个SIGABRT处理程序,将工作以及:

#include <execinfo.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 

void handler(int sig, siginfo_t*, void*) { 
    void *array[10]; 
    size_t size = backtrace(array, 10); 
    fprintf(stderr, "Error: signal %d:\n", sig); 
    backtrace_symbols_fd(array, size, STDERR_FILENO); 
    exit(1); 
} 

void terminate_handler() 
{ 
} 

int main() 
{ 
    struct sigaction new_sigaction, old_sigaction; 
    new_sigaction.sa_flags = SA_SIGINFO; 
    new_sigaction.sa_sigaction = handler; 
    sigaction(SIGABRT, &new_sigaction, &old_sigaction); 
    throw 1; 
} 

我个人比较喜欢的终止处理程序,因为在这种情况下,你明确知道原因。如果调用SIGABRT处理程序,您必须了解这是因为调用了未处理的异常abort()还是通过其他方式发送了信号。

here

如果在堆栈展开期间调用,异常对象的初始化后和异常处理程序开始前的任何功能,具有异常退出,std::terminate被调用。

总之它说如果没有发现异常std::terminate被调用。 这是不同的赛格。故障

您的程序没有捕捉到异常,因此调用了std::terminate,但这并不会产生sigfault行为。

我认为你需要做的

raise(SIGSEGV) 

,如果你想结束了在你的处理器:

#include <stdio.h> 
#include <execinfo.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <unistd.h> 
void handler(int sig) { 
    void *array[10]; 
    size_t size = backtrace(array, 10); 
    fprintf(stderr, "Error: signal %d:\n", sig); 
    backtrace_symbols_fd(array, size, STDERR_FILENO); 
    exit(1); 
} 
int main() 
{ 
    signal(SIGSEGV, handler); 
    raise(SIGSEGV); 
} 
+0

OP想要捕获未处理的C++异常。 –

+0

为什么要用C函数处理C++异常? –

+0

我不知道......我只注意到他为SIGSEGV安装了一个处理程序,并假定他想要在处理程序中结束。因此提出SIGSEGV – Rik