当前位置: 首页 > 面试题库 >

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

琴正初
2023-03-14
问题内容

我正在尝试使用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

就是说,您忘记做的是取消阻止信号:执行信号处理程序时,同一信号的传递被阻止,并且当信号处理程序因异常而退出时,它也不会变为未阻止状态。如下更改信号处理程序:

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


 类似资料:
  • 为什么全局异常处理不能处理筛选器中引发的异常? 我的代码现在是这样的:

  • 问题内容: 我为按钮添加了图像,但是当我运行该框架时,将抛出此异常。为什么?请帮助我。 第138行: 第91行: 我使用了此检查不当(建议使用Peter Lang):System.out.println(getClass()。getResource(“ / Images / yahoo_1.gif”)); 它返回null,为什么?请帮我。 问题答案: 这意味着,将返回。 JavaDoc指出,如果

  • 问题内容: 在Java中: 抛出。为什么?为什么在这里投降?我不知道原因。 问题答案: 让我重命名您的班级,以使事情更加清楚。 -> 。 -> 。 仅仅因为你是一个人并不意味着你是一个人。你可能是一个。这就是将A强制转换为A的原因。 另一方面,每个是吗?答案是“是”。这就是为什么您 可以 编写如下代码: 要么 另外值得注意的是,您 可以 执行以下操作: 这样做的原因是您的变量实际上是在引用实例。因

  • 问题内容: 要编译此代码,我可以: 将我的通话置于try / catch块中,或 已经声明它可以抛出一个。 为什么我必须这样做? (示例代码来自Kathy Sierra的SCJP书 。) 我知道引发的异常是已检查的异常,因此我必须处理它,但是在什么情况下需要引发此异常? 问题答案: 如果以一种可以引发检查异常的方式声明方法(不是的子类),则调用该方法的代码必须在一个块中调用它,否则调用者方法必须声

  • 为什么这段代码不抛出?看一看: 我不知道!

  • 获取此语句时出错。deleteEntry(Integer.valueOf); 如果在执行dao.delete项(Integer.valueOf(s))时发生异常;捕捉块不能捕捉异常,因为它捕捉""执行异常"具体而言,因此函数本身应该自动抛出异常,因为它的签名已抛出语句我写的捕捉块是用于处理逻辑处理的,如果我在try捕捉之外写同样的语句,它不会给出任何错误。我想了解这里的行为。请好心帮忙