为什么浮动“除以零”?即使设置了处理程序,函数也没有捕获异常?
当发现奇怪的行为时,我尝试学习 C 中的信号处理。
当x/=y时;信号处理程序在主函数的上下文中执行。但是,当在某些函数 (bad_func) 处理程序中执行的相同操作被忽略时,SIGFPE 的信号处理程序已经设置。
问:为什么即使调用了 _control87,我的全局信号处理程序也没有在函数中捕获 SIGFPE?
(MS VC 2010):
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <float.h>
jmp_buf g_jb_MainFunc;
void hook_zd (int i)
{
printf("Result :%i\n",i);
longjmp(g_jb_MainFunc, 5);
}
void bad_func(void)
{
double x = 0., y = 0.;
puts("hello1");
//abort();
x /= y;
puts("bye1");
}
int main(int argc, char* argv[])
{
double x = 0., y = 0.;
signal(SIGFPE, hook_zd);
signal(SIGABRT, hook_zd);
puts("hello");
_control87(0, _MCW_EM );
int res;
if (! (res = setjmp(g_jb_MainFunc)))
{
//abort();
//x /= y;
bad_func();
} else
{
printf("Jumped here from: %i\n",res);
}
puts("bye");
return 0;
}
I've tried to learn the signal handling in C, when found strange behaviour.
When x /= y; executed in the context of the main function the signal handler works. But when the same executed in some function (bad_func) handler is ignored however signal handler for SIGFPE is already set.
Q: Why SIGFPE wasn't caught in a function by my global signal handler even _control87 was called?
(MS VC 2010):
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <float.h>
jmp_buf g_jb_MainFunc;
void hook_zd (int i)
{
printf("Result :%i\n",i);
longjmp(g_jb_MainFunc, 5);
}
void bad_func(void)
{
double x = 0., y = 0.;
puts("hello1");
//abort();
x /= y;
puts("bye1");
}
int main(int argc, char* argv[])
{
double x = 0., y = 0.;
signal(SIGFPE, hook_zd);
signal(SIGABRT, hook_zd);
puts("hello");
_control87(0, _MCW_EM );
int res;
if (! (res = setjmp(g_jb_MainFunc)))
{
//abort();
//x /= y;
bad_func();
} else
{
printf("Jumped here from: %i\n",res);
}
puts("bye");
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它对我有用,除非我在打开优化的情况下进行编译。例如,如果我从命令行将其编译为 cl mysigtest.cpp,则异常将按预期工作。但如果我编译它
cl /O1 mysigtest.cpp
,那么它不会显示异常。反汇编代码显示了问题:
除法已被优化掉。尝试关闭优化,或将
bad_func
更改为以下内容。对我来说,它“击败”了优化器:并更改对它的调用:
It works for me unless I compile with optimizations turned on. For example, if I compile it from the command line as
cl mysigtest.cpp
, the exceptions work as expected. But if I compile itcl /O1 mysigtest.cpp
, then it does not show the exception.The disassembled code shows the problem:
The division has been optimized out. Try it with optimizations turned off, or change
bad_func
to the following. For me, it "defeated" the optimizer:And change the call to it: