浮点异常核心转储

发布于 2024-11-19 01:39:31 字数 1377 浏览 6 评论 0原文

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

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

问题:
1. 既然安装了过程信号掩码,那么第 40 行 volatile int z = x/y; 生成的“SIGFPGE”不应该被阻止吗?
2.如果没有被阻塞,既然已经安装了信号处理程序,那么“SIGFPE”不应该被信号处理程序捕获,而不是核心转储吗?
3. 如果我注释掉第 40 行volatile 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;
    }

I am newbie on the Linux signals, please help.
The following code get core dump when run in Linux 2.6 gcc.

$ ./a.out
Floating point exception (core dumped)

The questions:
1. Since a process signal mask is installed, shouldn't the "SIGFPGE" generated by line 40 volatile int z = x/y; be blocked?
2. If it is not blocked, since a signal handler has been installed, shouldn't the "SIGFPE" be captured by the signal handler, instead of a core dump?
3. If I commented out line 40volatile int z = x/y;, and use line 42 raise(SIGFPE); instead, then everything works as I expected. What is the difference between x/0 and raise SIGFPE here?

Here is the code:

    #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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无所谓啦 2024-11-26 01:39:31

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

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

(来自 sigprocmask 规范

Any SIGFPE caused by a hardware trap while the signal is blocked causes undefined behavior:

If any of the SIGFPE, SIGILL, SIGSEGV, or SIGBUS signals are generated while they are blocked, the result is undefined, unless the signal was generated by the kill() function, the sigqueue() function, or the raise() function.

(from sigprocmask specification)

溇涏 2024-11-26 01:39:31

man signal

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

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

我在尝试弄清楚为什么负/正无穷大是由除以零导致的之后发现了这一点: IEEE 754,除以零

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

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}

man signal

According to POSIX, the behavior of a process is undefined after it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(2) or raise(3). Integer division by zero has undefined result.

On some architectures it will generate a SIGFPE signal. (Also dividing the most negative integer by -1 may generate SIGFPE). Ignoring this signal might lead to an endless loop.

I discovered this after trying to work out why negative/positive infinity resulted from a division by zero: IEEE 754, division by zero

This is a place you never want to get:

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}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文