Почему мой обработчик сигнала (который генерирует исключение) не срабатывает более одного раза? - PullRequest
2 голосов
/ 02 мая 2011

Я пытаюсь настроить обработчик исключений, используя sigaction.Это хорошо работает для первого исключения.Но обработчик sigaction не вызывается после 1-го исключения, и программа внезапно завершается, когда появляется второй сигнал.

#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;
}

Ответы [ 2 ]

8 голосов
/ 02 мая 2011

Сигналы и исключения не связаны друг с другом.То, что вы используете (генерируете исключения из асинхронных обработчиков сигналов), переносимо только между несколькими компиляторами, которые его поддерживают, такими как GCC и Intel C / C ++ с -fnon-call-exceptions.

Тем не менее, то, что вы забылиdo разблокирует сигнал: когда выполняется обработчик сигнала, доставка того же сигнала блокируется, и он не блокируется при выходе из обработчика сигнала через исключение.Измените обработчик сигнала следующим образом:

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();
}
2 голосов
/ 02 мая 2011

Стандарт C ++ ничего не говорит о сигналах или о том, как они взаимодействуют с исключениями. То, что вы пытаетесь сделать, будет полностью зависеть от используемой платформы ОС и, возможно, от конкретного компилятора, с которым вы компилируете свой код.

...