为什么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++异常并打印出调用堆栈?
谢谢!
您可以安装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);
}
OP想要捕获未处理的C++异常。 –
为什么要用C函数处理C++异常? –
我不知道......我只注意到他为SIGSEGV安装了一个处理程序,并假定他想要在处理程序中结束。因此提出SIGSEGV – Rik
罚球剂量抓与抓'(...)的' –
可能的复制[从未处理的异常的c + +堆栈跟踪?](http://stackoverflow.com/questions/3355683/c-stack-trace-from-unhandled-exception)+异常不是分段违规(分段错误)。 – user1810087
你为什么期望信号处理程序能够捕捉到这个问题? – juanchopanza