信号后未捕获异常
Exception not caught after signal
我尝试在退出之前捕获终止信号以写入我的代码以写入重新启动文件。我的解决方案基于这个答案。
#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;
}
}
异常被抛出很好,但是,我的捕获块没有捕获它。程序终止,并出现未捕获的异常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 编译时,有时会捕获异常,但并非一直如此,这使得这更加奇怪。
在信号处理程序中,您几乎无法可靠地执行任何操作。特别是,不能引发异常。问题中的代码(以及它链接到的"答案"(充其量依赖于特定于编译器/操作系统的行为。有关可以在信号处理程序中执行的操作的限制,请参阅此处。
请注意,上面的链接指的是signal
,这是标准 C。sigaction
不是标准的C,而是POSIX,C++语言定义不会对使用它的程序施加任何要求。
在大多数系统上,信号处理程序使用的堆栈帧不是编译器为函数调用定义的标准函数堆栈帧。
因此,不支持抛出 sig 处理程序。
Linux 内核中用于信号处理的堆栈帧
从链接问题中的讨论来看,在 linux 系统上,他们甚至没有对堆栈帧使用相同的堆栈,并且返回需要跳回到系统函数以恢复原始用户堆栈。
除非操作系统专门设计用于处理异常,否则这将不起作用。
信号处理程序的经验法则是在信号处理程序中尽可能少地执行操作。设置一个普通代码可以检测到的全局标志,然后在正常代码中定期检查该标志,以查看信号何时发生。
相关文章:
- 当类定义不可见时捕获异常
- 来自 Android 应用程序内部的 boost 类型的 boost::wrapexcept<boost::system::system_error> 的未捕获异常
- C++函数包装器来捕获某些信号
- 如何通过 pybind11 从 python 中的C++中捕获异常?
- 信号后未捕获异常
- 捕获异常后如何退出程序执行
- C++ 捕获异常后进行清理的标准方法是什么?
- 使用模板类引发和捕获异常
- E/libc++abi:终止于类型为google::protobuf::FatalException的未捕获异常
- 如果在生成 std::thread 后引发,则未捕获异常
- C++ 未捕获异常,程序将终止并中止
- C++程序在第一次尝试时会给出垃圾,但如果它捕获异常并重试,则会给出适当的值
- 仅捕获异常就可以检测所有二进制文件在C 中读取错误是否足够
- 以Qt格式捕获音频信号
- 如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)
- 为什么捕获异常播放允许尾括号
- throw() 函数应该总是在异常时展开堆栈并允许捕获异常还是必须调用 std::terminate ?
- 寻求与类型为 std::invalid_argument 的未捕获异常相关的运行时错误的建议: stoi:无转换
- 如何从调用函数中捕获异常
- 捕获 Segfault 或任何其他错误/异常/信号C++例如在 Java 中捕获异常