为什么我的信号处理程序(引发异常)不会多次触发?

Why doesn't my signal handler (which throws an exception) trigger more than once?

本文关键字:异常 信号处理 我的 程序 为什么      更新时间:2023-10-16

我正在尝试使用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和带有-fnon-call-exceptions的Intel C/c++。

也就是说,您忘记做的是解除信号阻塞:当信号处理程序正在执行时,相同信号的传递被阻塞,并且当信号处理程序通过异常退出时,它不会被解除阻塞。按如下方式更改信号处理程序:

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();
}

标准c++没有说明信号,也没有说明它们如何与异常交互。您要做的事情将完全特定于您正在使用的操作系统平台,并且可能是您编译代码的特定编译器。