首页 > 解决方案 > 发出信号后未捕获异常

问题描述

我尝试在退出之前捕获我的代码的终止信号以编写重新启动文件。我的解决方案是基于这个答案

#include <exception>
#include <csignal>
#include <iostream>


class InterruptException : public std::exception
  {
   public:
    InterruptException(int _s) : signal_(_s) { }
    int signal() const noexcept
    {
      return this->signal_;
    }

   private:
    int signal_;
  };

  /// method to throw exception at signal interrupt
  void sig_to_exception(int s)
  {
    throw InterruptException(s);
  }

int main()
{
  // activate signal handling
  struct sigaction sigIntHandler;
  sigIntHandler.sa_handler = sig_to_exception;
  sigemptyset(&sigIntHandler.sa_mask);
  sigIntHandler.sa_flags = 0;
  sigaction(SIGINT, &sigIntHandler, NULL);

  try
  {
    for (std::size_t i = 0; i < 100000000; ++i)
    {
      std::cout  << i << std::endl;
    }
  }
  catch (const InterruptException& e)
  {
    std::cout << "Received signal " << e.signal() << std::endl;
    std::exit(1);
  }
  catch(...)
  {
    std::cout << "Other catch!" << std::endl;
  }
}

异常被很好地抛出,但是,我的 catch 块没有捕获它。程序以未捕获的异常终止InterruptException。我在 MacOS 上尝试了 clang 和 gcc。知道为什么没有正确捕获异常吗?

谢谢

使用 g++ 7.3.0 编译时的输出:

terminate called after throwing an instance of 'InterruptException'
   what():  std::exception
Abort trap: 6

使用 Apple LLVM 9.0.0 编译时的输出

libc++abi.dylib: terminating with uncaught exception of type InterruptException: std::exception

PS:当我使用 Apple LLVM 编译时,似乎有时会捕获异常,但并非总是如此,这使得这更加奇怪。

标签: c++exceptionexception-handlingsignals

解决方案


您可以在信号处理程序中可靠地做的事情很少。特别是,您不能抛出异常。问题中的代码(以及它链接到的“答案”)充其量依赖于编译器/操作系统特定的行为。有关您可以在信号处理程序中执行的操作的限制,请参阅

请注意,上面的链接指的signal是标准 C。sigaction不是标准 C,它是 POSIX,并且 C++ 语言定义对使用它的程序没有任何要求。


推荐阅读