1

当发现奇怪的行为时,我试图学习 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;
}
4

1 回答 1

3

除非我在打开优化的情况下进行编译,否则它对我有用。例如,如果我从命令行将其编译为cl mysigtest.cpp,则异常按预期工作。但是如果我编译它cl /O1 mysigtest.cpp,那么它不会显示异常。

反汇编代码显示问题:

?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

该部门已被优化出来。尝试关闭优化,或更改bad_func为以下内容。对我来说,它“击败”了优化器:

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

并更改对它的调用:

bad_func( 0.0 );
于 2010-06-23T21:43:10.817 回答