为什么浮动"除法被零"例外情况是不是在一个函数抓到,甚至处理设置? [英] Why float "division-by-zero" exception wasn't caught in a function even handler was set?

查看:141
本文介绍了为什么浮动"除法被零"例外情况是不是在一个函数抓到,甚至处理设置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着学习在C信号处理,发现了奇怪的行为时。

当x / = Y;在主函数的信号处理工作的上下文中执行。但是,当同样的一些功能(bad_func)执行的处理程序但忽略SIGFPE信号处理程序已经设置。

问:为什么SIGFPE不是在一个函数通过我的全球信号处理程序捕获甚至_control87被称为

(MS 2010 VC):

 的#includestdafx.h中
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&signal.h中GT;
#包括LT&;&SETJMP.H GT;
#包括LT&;&FLOAT.H GT;jmp_buf g_jb_MainFunc;无效hook_zd(int i)以
{
    的printf(结果:%I \\ N,I);
    longjmp的(g_jb_MainFunc,5);
}
无效bad_func(无效)
{
    双x = 0的,Y = 0 .;
    卖出期权(hello1);
    //中止();
    X / = Y;
    卖出期权(bye1);
}
INT主(INT ARGC,CHAR *的argv [])
{
    双x = 0的,Y = 0 .;
    信号(SIGFPE,hook_zd);
    信号(SIGABRT,hook_zd);
    看跌期权(你好);
    _control87(0,_MCW_EM);
    中期业绩;
    如果(!(RES =的setjmp(g_jb_MainFunc)))
    {
        //中止();
        // X / = Y;
        bad_func();
    }其他
    {
        的printf(从这里跳下:%I \\ N,RES);
    }
    看跌期权(再见);    返回0;
}


解决方案

它为我,除非我编译优化开启。例如,如果我编译它在命令行 CL mysigtest.cpp ,异常正常工作。但是,如果我编译它 CL / O1 mysigtest.cpp ,那么它不会显示异常。

在拆卸code显示了问题:

  bad_func @@ YAXXZ(无效__cdecl bad_func(无效))?
  00000000:68 00 00 00 00推偏移?_ 3. C @ _06CKBHOFLC @ hello1 $ @ AA
  00000005:E8 00 00 00 00电话_puts
  0000000A:68 00 00 00 00推偏移?_ 3. C @ _04EEFJMNKA @ bye1 $ @ AA
  0000000F:E8 00 00 00 00电话_puts
  00000014:83 08 C4 ADD ESP,8
  00000017:C3 RET

该部门已经优化了。尝试将其与优化关闭,或更改 bad_func 以下内容。对我来说,打败优化:

 双bad_func(双Y)
{
    双X = 0;
    卖出期权(hello1);
    //中止();
    X / = Y;
    卖出期权(bye1);
    返回X;
}

和来电更改它:

  bad_func(0.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;
}

解决方案

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 it cl /O1 mysigtest.cpp, then it does not show the exception.

The disassembled code shows the problem:

?bad_func@@YAXXZ (void __cdecl bad_func(void)):
  00000000: 68 00 00 00 00     push        offset ??_C@_06CKBHOFLC@hello1?$AA@
  00000005: E8 00 00 00 00     call        _puts
  0000000A: 68 00 00 00 00     push        offset ??_C@_04EEFJMNKA@bye1?$AA@
  0000000F: E8 00 00 00 00     call        _puts
  00000014: 83 C4 08           add         esp,8
  00000017: C3                 ret

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:

double bad_func(double y)
{
    double x = 0.; 
    puts("hello1");
    //abort();
    x /= y;
    puts("bye1");
    return x;
}

And change the call to it:

bad_func( 0.0 );

这篇关于为什么浮动&QUOT;除法被零&QUOT;例外情况是不是在一个函数抓到,甚至处理设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆