Evi*_*ach 22 c++ signals exception
我们有一个库,可以处理错误报告的许多方面.我的任务是将此库移植到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;
}
Run Code Online (Sandbox Code Playgroud)
我的期望是将显示Caught exception:消息.实际发生的是程序终止,因为抛出的int似乎没有出现catch处理程序.
关于SO的一些问题似乎有关.我找到了许多相关的Google网页."智慧"似乎归结为.
雅,曾经可以使用gcc,但似乎不再工作了.尝试-fnon-call-exceptions选项,也许这样可行
代码在AIX/TRU64/MSVC编译器/环境中按预期工作.它在我们的Linux环境中失败了.
我正在寻找有助于解决此问题的建议,因此Linux上的库行为将与我的其他平台或可能实现相同功能的某种类型或解决方法相匹配.
让程序核心转储信号,不是一个可行的选择.
Cha*_*via 14
信号与C++异常完全不同.您不能使用C++ try/catch块来处理信号.具体来说,信号是POSIX概念,而不是C++语言概念.信号由内核异步传递给您的应用程序,而C++异常是由C++标准定义的同步事件.
您在POSIX信号处理程序中可以移植的内容非常有限.一种常见的策略是使用一个全局标志类型sig_atomic_t,它将在信号处理程序中设置为1,然后可能longjmp设置为适当的执行路径.
请参阅此处以获取有关编写正确信号处理程
Evi*_*ach 10
此代码演示了一种将异常抛出信号处理程序的技术.感谢Charles的想法.
#include <iostream>
#include <csignal>
#include <csetjmp>
using namespace std;
jmp_buf gBuffer; // A buffer to hold info on where to jump to
void catch_signal(int signalNumber)
{
//signal(SIGINT, SIG_DFL); // Switch to default handling
signal(SIGINT, catch_signal); // Reactivate this handler.
longjmp // Jump back into the normal flow of the program
(
gBuffer, // using this context to say where to jump to
signalNumber // and passing back the value of the signal.
);
}
int test_signal()
{
signal(SIGINT, catch_signal);
try
{
int sig;
if ((sig = setjmp(gBuffer)) == 0)
{
cout << "before raise\n";
raise(SIGINT);
cout << "after raise\n";
}
else
{
// This path implies that a signal was thrown, and
// that the setjmp function returned the signal
// which puts use at this point.
// Now that we are out of the signal handler it is
// normally safe to throw what ever sort of exception we want.
throw(sig);
}
}
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;
}
Run Code Online (Sandbox Code Playgroud)
我将屏蔽每个线程中的所有信号,除了一个等待信号的信号sigwait
().该线程可以无限制地处理信号,例如抛出异常或使用其他通信机制.
| 归档时间: |
|
| 查看次数: |
15206 次 |
| 最近记录: |