带有SIGFPE异常的程序在gdb下的行为有所不同

时间:2013-07-20 19:58:50

标签: c gdb signals sigfpe

我有一个简单的C程序,在使用gdb调试时表现不同,而不是。 该计划是这样的:

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

int main() {
    kill(getpid(), SIGFPE);
    printf("I'm happy.\n");
    return 0;
}

当它自己运行时,我得到了这个非常奇怪的结果:

ezyang@javelin:~$ ./mini
I'm happy.
ezyang@javelin:~$ echo $?
0

没有错误!这并不是说信号没有被解雇,而是:

ezyang@javelin:~$ strace -e signal ./mini
kill(31950, SIGFPE)                     = 0
--- SIGFPE (Floating point exception) @ 0 (0) ---
I'm happy

在GDB中,情况有所不同:

ezyang@javelin:~/Dev/ghc-build-sandbox/libraries/unix/tests/libposix$ gdb ./mini
GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini...(no debugging symbols found)...done.
(gdb) r
Starting program: /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Program received signal SIGFPE, Arithmetic exception.
0x00007ffff7a49317 in kill () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) c
Continuing.

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

要求GDB不停止没有区别

(gdb) handle SIGFPE nostop
Signal        Stop  Print   Pass to program Description
SIGFPE        No    Yes Yes     Arithmetic exception
(gdb) r
Starting program: /srv/code/ghc-build-sandbox/libraries/unix/tests/libposix/mini 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Program received signal SIGFPE, Arithmetic exception.

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

发生了什么事?!首先,为什么SIGFPE没有杀死该计划;第二件事,为什么GDB表现不同?

更新。有人认为子进程正在继承父进程的信号掩码。 然而,正如本抄本所示,情况显然不是这样: 此分析不正确,见下文。

ezyang@javelin:~$ trap - SIGFPE
ezyang@javelin:~$ ./mini
I'm happy.

更新2。我的一位朋友指出陷阱只报告shell本身设置的信号,而不是任何父进程。所以我们跟踪了所有父母的忽略掩码,并且看,rxvt-unicode已经屏蔽了SIGFPE。一位朋友确认他在使用rxvt-unicode运行可执行文件时可以重现。

2 个答案:

答案 0 :(得分:2)

忽略的信号在fork()exec*()上继承:

$ ./mini
Floating point exception (core dumped)
$ trap '' SIGFPE
$ ./mini
I'm happy.
$ trap - SIGFPE
$ ./mini
Floating point exception (core dumped)

我与问题作者私下讨论过这个问题。由于bash从其父进程保存并恢复信号掩码,并且trap内置仅报告在当前shell 中处理或忽略的信号,因此调试变得复杂,即使从父进程继承的被忽略的信号仍然会生效。

事实证明,根本问题是他在urxvt中运行测试,该测试链接了libperl,unconditionally ignores SIGFPE

答案 1 :(得分:0)

SIG_IGN的信号掩码和信号处理由子进程继承。我能想到的唯一可能性是你的shell由于某些原因而被SIGFPE屏蔽或忽略,并且在开始你的程序之前没有清除这个状态。