从信号处理程序中引发异常
我们有一个处理错误报告许多方面的库.我的任务是将此库移植到 Linux.通过我的小测试套件运行时,其中一个测试失败了.测试的简化版本如下所示.
We have a library that deals with many aspects of error reporting. I have been tasked to port this library to Linux. When running though my little test suite, one of the tests failed. A simplified version of the test appears below.
// Compiler: 4.1.1 20070105 RedHat 4.1.1-52
// Output: Terminate called after throwing an instance of 'int' abort
#include <iostream>
#include <csignal>
using namespace std;
void catch_signal(int signalNumber)
{
signal(SIGINT, SIG_DFL);
throw(signalNumber);
}
int test_signal()
{
signal(SIGINT, catch_signal);
try
{
raise(SIGINT);
}
catch (int &z)
{
cerr << "Caught exception: " << z << endl;
}
return 0;
}
int main()
{
try
{
test_signal();
}
catch (int &z)
{
cerr << "Caught unexpected exception: " << z << endl;
}
return 0;
}
我的期望是显示 Caught exception: 消息.实际发生的是程序终止,因为抛出的 int 似乎没有 catch 处理程序.
My expectation is that the Caught exception: message will be displayed. What actually happens is that the program terminates as no catch handler appears to be present for the thrown int.
有几个关于 SO 的问题似乎相关.我发现了一些相关的谷歌页面.智慧"似乎可以归结为.
There are a few questions on SO that seem related. I found a number of Google pages that were related. The 'wisdom' seems to boil down to.
- 你不能从信号处理程序中抛出异常,导致信号处理程序使用自己的堆栈运行,因此没有定义处理程序.
- 你可以从信号处理程序中抛出异常,只是重建一个假的堆栈上的框架,你很高兴.
- 是的,我们一直都这样做.它适用于 X 平台
是的,它曾经可用于 gcc,但似乎不起作用更多的.试试 -fnon-call-exceptions 选项,也许会起作用
代码在我们的 AIX/TRU64/MSVC 编译器/环境中按预期工作.它在我们的 Linux 环境中失败.
The code works as expected on our AIX/TRU64/MSVC compiler/environments. It fails in our Linux environment.
我正在寻找帮助解决此问题的建议,以便 Linux 上的库行为与我的其他平台相匹配,或者可以实现相同功能的某种类型或解决方法.
让程序核心转储信号,不是一个可行的选择.
推荐答案
信号与 C++ 异常完全不同.您不能使用 C++ try/catch 块来处理信号.具体来说,信号是 POSIX 概念,而不是 C++ 语言概念.信号由内核异步传递给您的应用程序,而 C++ 异常是由 C++ 标准定义的同步事件.
Signals are totally different than C++ exceptions. You can't use a C++ try/catch block to handle a signal. Specifically, signals are a POSIX concept, not a C++ language concept. Signals are delivered asynchronously to your application by the kernel, whereas C++ exceptions are synchronous events defined by the C++ standard.
您可以在 POSIX 信号处理程序中进行可移植的操作非常有限.一个常见的策略是有一个 sig_atomic_t
类型的全局标志,它将在信号处理程序中设置为 1,然后可能将 longjmp
设置为适当的执行路径.
You are quite limited in what you can do portably in a POSIX signal handler. A common strategy is to have a global flag of type sig_atomic_t
which will be set to 1 in the signal handler, and then possibly longjmp
to the appropriate execution path.
请参阅此处获取帮助编写适当的信号处理程序.
See here for help writing proper signal handlers.
相关文章