我们有一个处理错误报告许多方面的库。我的任务是将此库移植到 Linux。通过我的小测试套件运行时,其中一个测试失败了。测试的简化版本如下所示。
// 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 处理程序。
有几个关于 SO 的问题似乎相关。 我发现了一些相关的谷歌页面。 “智慧”似乎可以归结为。
- 你不能从信号处理程序中抛出异常,导致信号 处理程序使用自己的堆栈运行,因此没有定义处理程序。
- 你可以从信号处理程序中抛出异常,只是重建一个假的 堆栈上的框架,你很高兴。
- 是的,我们一直都这样做。它适用于 X 平台
是的,它曾经可用于 gcc,但似乎不起作用 更多的。试试 -fnon-call-exceptions 选项,也许会起作用
代码在我们的 AIX/TRU64/MSVC 编译器/环境中按预期工作。它在我们的 Linux 环境中失败。
我正在寻找帮助解决此问题的建议,以便 Linux 上的库行为与我的其他平台相匹配,或者可以实现相同功能的某种类型或解决方法。
让程序核心转储信号,不是一个可行的选择。
最佳答案
信号与 C++ 异常完全不同。您不能使用 C++ try/catch block 来处理信号。具体来说,信号是 POSIX 概念,而不是 C++ 语言概念。信号由内核异步传递给您的应用程序,而 C++ 异常是由 C++ 标准定义的同步事件。
您可以在 POSIX 信号处理程序中进行可移植的操作非常有限。一个常见的策略是有一个 sig_atomic_t
类型的全局标志,它将在信号处理程序中设置为 1,然后可能将 longjmp
设置为适当的执行路径。
见 here帮助编写正确的信号处理程序。
关于c++ - 从信号处理程序中引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1717991/