#include <iostream> #include <signal.h> #include <fenv.h> #include <string.h> void signal_handler(int sig,siginfo_t *siginfo,void* context) { std::cout << " signal_handler " << fetestexcept(FE_ALL_EXCEPT) << std::endl; throw "exception"; } void divide() { float a = 1000.,b = 0.,c,f = 1e-300; c = a / b; std::cout << c << " and f = " << f << std::endl; } void init_sig_hanlder() { feenableexcept(FE_ALL_EXCEPT); struct sigaction sa,initial_sa; sa.sa_sigaction = &signal_handler ; sigemptyset( &sa.sa_mask ) ; sa.sa_flags = SA_SIGINFO; // man sigaction(3) // allows for void(*)(int,siginfo_t*,void*) handler sigaction(SIGFPE,&sa,&initial_sa); } int main(int argc,char** argv) { init_sig_hanlder(); while(true) { try { sleep(1); divide(); } catch(const char * a) { std::cout << "Exception in catch: " << a << std::endl; } catch(...) { std::cout << "Exception in ..." << std::endl; } } return 0; }
在Linux / g ++ 4.2上产生以下结果:
signal_handler 0
捕获exception:exception
inf和f = 0
inf和f = 0
inf和f = 0
inf和f = 0
所以,信号处理程序是第一次执行,但下一个fpexception不会再次触发处理程序。 我错在哪里?
如何处理在Python中编写的Windows服务信号?
Windows:如何从命令行发送信号(SIGNINT或SIGBREAK)到进程
WEXITSTATUS(状态)返回什么?
如何在Windows上使用Python检索附近无线LANnetworking的信号强度?
如果在UNIX中的信号处理过程中发生同样的信号发送到程序会发生什么?
Linux信号掩码 – 它们是什么意思?
在线程之间发送信号
Perl:closures信号处理程序中的subprocesspipe道挂起?
在Windows上相当于SIGWINCH?
Linux:窥探一个信号,而不是为随后的核心转储废弃寄存器?
我不认为在信号处理程序中抛出一个异常是很好的做法。 操作系统期望信号处理程序return ,因为在处理程序被调用时信号被阻塞。 通过抛出异常,可以防止系统解锁信号。
我记得,信号处理程序必须被声明为“extern”C“”,因为库/内核将使用C调用约定,而不是C ++调用约定。 但是extern“C”的函数不能抛出异常,所以至少在形式上你的代码不是“正确的”
在这种情况下,我猜想Linux中的信号传递代码没有机会重置或清除信号掩码,因为您从未将控制权交还给运行时和内核。
你应该像这样使用sigsetjmp / siglongjmp代码,而不是例外。
在这里使用异常是错误的,jmp的改变应该是排除奇怪平台特定行为的第一步(尤其是因为C ++标准允许使用信号传递机制来实现异常)。
然而,我很好奇,如果SIGFPE的失败与fe * except()状态有关。
问题:在你最初的零分之前和之后,这个状态会发生什么? 也许有一个期望,当你再次尝试这个时,需要feclearexcept()来获得另一个SIGFPE。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。