Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
231 views
in Technique[技术] by (71.8m points)

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

I am trying to set up an exception handler using sigaction. It works well for the first exception. But the sigaction handler is not called after the 1st exception and the program ends abruptly when the second signal happens.

#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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Signals and exceptions are not related to each other. What you're using (throwing exceptions from async signal handlers) is only portable between the few compilers that support it, such as GCC and Intel C/C++ with -fnon-call-exceptions.

That said, what you forgot to do is unblock the signal: when a signal handler is executing, the delivery of the same signal is blocked, and it does not become unblocked when the signal handler is exited through an exception. Change the signal handler as follows:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...