我正在尝试使用sigaction设置异常处理程序。对于第一个例外,它运作良好。但是在第一个异常之后不会调用sigaction处理程序,并且在第二个信号发生时程序会突然结束。
#include <iostream> #include <signal.h> #include <exception> #include <string.h> typedef void (*SigactionHandlerPointer)(int iSignal, siginfo_t * psSiginfo, void * psContext); using namespace std; void SigactionHookHandler( int iSignal, siginfo_t * psSiginfo, void * psContext ) { cout << "Signal Handler Exception Caught: std::exception -- signal : " << iSignal << " from SigactionHookHandler()" << endl; throw std::exception(); } class A { public: A() {} virtual ~A() {} virtual void fnct1(); virtual void fnct2() { fnct3(); } virtual void fnct3() { fnct4(); } virtual void fnct4(); }; void A::fnct1() { try { fnct2(); } catch( std::exception &ex ) { cerr << "Signal Handler Exception Caught" << endl; } catch (...) { cerr << "Unknow Exception Caught: " << endl; } } void A::fnct4() { *(int *) 0 = 0; // Access violation } int main() { struct sigaction oNewSigAction; struct sigaction oOldSigAction; memset(&oNewSigAction, 0, sizeof oNewSigAction); oNewSigAction.sa_sigaction = SigactionHookHandler; oNewSigAction.sa_flags = SA_SIGINFO; int iResult = sigaction( SIGSEGV, &oNewSigAction, &oOldSigAction ); cout << "sigaction installed handler with status " << iResult << endl; A * pA = new A(); cout << "Next message expected is : <<Signal Handler Exception Caught: std::exception>> to pass this test" << endl; pA->fnct1(); // Second exception will never be call the sigaction handler. cout << "Next message expected is : <<Signal Handler Exception Caught: std::exception>> to pass this test" << endl; pA->fnct1(); return 0; }
信号和异常互不相关。您正在使用的内容(从异步信号处理程序引发异常)只能在支持该功能的少数编译器之间移植,例如GCC和Intel C / C ++ with -fnon-call-exceptions。
-fnon-call-exceptions
就是说,您忘记做的是取消阻止信号:执行信号处理程序时,同一信号的传递被阻止,并且当信号处理程序因异常而退出时,它也不会变为未阻止状态。如下更改信号处理程序:
void SigactionHookHandler( int iSignal, siginfo_t * psSiginfo, void * psContext { cout << "Signal Handler Exception Caught: std::exception -- signal : " << iSignal << " from SigactionHookHandler()" << endl; sigset_t x; sigemptyset (&x); sigaddset(&x, SIGSEGV); sigprocmask(SIG_UNBLOCK, &x, NULL); throw std::exception(); }