开发者

Why float "division-by-zero" exception wasn't caught in a function even handler was set?

开发者 https://www.devze.com 2023-01-05 00:22 出处:网络
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 fun

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
    {
        prin开发者_运维问答tf("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 );
0

精彩评论

暂无评论...
验证码 换一张
取 消