【问题标题】:Floating Point Exception Core Dump浮点异常核心转储
【发布时间】:2011-10-01 12:27:18
【问题描述】:

我是 Linux 信号的新手,请帮助。 以下代码在 Linux 2.6 gcc 中运行时获取核心转储。

$ ./a.out
浮点异常(核心转储)

问题:
1、既然安装了进程信号掩码,那么第40行volatile int z = x/y;生成的“SIGFGE”不应该被屏蔽吗?
2.如果它没有被阻塞,既然已经安装了信号处理程序,那么信号处理程序不应该捕获“SIGFPE”,而不是核心转储吗?
3. 如果我注释掉第 40volatile int z = x/y; 行,并改用第 42 行raise(SIGFPE);,那么一切都按我的预期进行。这里的 x/0 和 raise SIGFPE 有什么区别?

代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>

    void sig_handler(int signum)
    {
       printf("sig_handler() received signal %d\n", signum);
    }


    int main(int argc, char * argv[])
    {

       // setup signal mask, block all signals
       sigset_t set;
       sigfillset(&set);

       if(sigprocmask(SIG_BLOCK, &set, NULL)<0)
       {
          perror("failed to set sigmask");
          return -1;
       }

       // install signal handler for SIGFPE
       struct sigaction act;
       act.sa_handler = sig_handler;
       act.sa_mask = set;
       act.sa_flags = 0;
       if(sigaction( SIGFPE, &act, NULL)<0)
       {
          perror("sigaction failed");
          exit(-1);
       }

       volatile int x =1;
       volatile int y =0;
       volatile int z = x/y; //line 40

       //raise(SIGFPE); //line 42

       printf("point 1000\n");

       return 0;
    }

【问题讨论】:

    标签: c linux signals sigfpe


    【解决方案1】:

    man signal

    根据 POSIX,在忽略不是由 kill(2) 或 raise(3) 生成的 SIGFPE、SIGILL 或 SIGSEGV 信号后,进程的行为是不确定的。整数除以零有未定义的结果。

    在某些架构上,它会生成 SIGFPE 信号。 (同样将最大负整数除以 -1 可能会生成 SIGFPE)。忽略此信号可能会导致无限循环。

    我在试图找出为什么负/正无穷大是由零除后发现的:IEEE 754, division by zero

    这是一个你永远不想去的地方:

    void divZeroHdlr(int sig) {
      printf("div by zero: %d\n",sig)
      exit(1);}
    
    int main(int argc, char *argv[]) {
      signal(SIGFPE, divZeroHdlr)
      int n = 1/0}
    

    【讨论】:

      【解决方案2】:

      在信号被阻塞时由硬件陷阱引起的任何 SIGFPE 都会导致未定义的行为:

      如果任何 SIGFPE、SIGILL、SIGSEGV 或 SIGBUS 信号在被阻塞时生成,则结果未定义,除非该信号是由 kill() 函数、sigqueue() 函数或 raise( ) 函数。

      (来自sigprocmask specification

      【讨论】:

      • +1。虽然最新的规范是Issue 7。 :-)
      • @Nemo:谢谢。规则仍然存在,但措辞略有变化,所以我更新了答案。
      • 感谢您的回答。我讨厌“未定义”。
      猜你喜欢
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多