简体   繁体   English

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

[英]Program with SIGFPE exception behaves differently under gdb

I have a simple C program which behaves differently when debugged with gdb and not. 我有一个简单的C程序,在使用gdb调试时表现不同,而不是。 The program is this: 该计划是这样的:

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

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

When run by itself, I get this very strange result: 当它自己运行时,我得到了这个非常奇怪的结果:

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

No error! 没错! That is not to say that the signal is not being fired, it is: 这并不是说信号没有被触发,它是:

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

When in GDB, things proceed differently: 在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.

Asking GDB to not stop makes no difference 要求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.

What's going on?! 这是怎么回事?! For one thing, why isn't the SIGFPE killing the program; 首先,为什么SIGFPE没有杀死该计划; for the second thing, why is GDB behaving differently? 第二件事,为什么GDB表现不同?

Update. 更新。 One thought is that the child process is inheriting the signal masks of the parent. 一种想法是子进程继承父进程的信号掩码。 However, as can be seen in this transcript, that clearly is not the case: This analysis was not correct, see below. 但是,从本抄本中可以看出,情况显然不是这样: 这种分析不正确,见下文。

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

Update 2. A friend of mine points out that trap only reports signals as set by the shell itself, and not by any parent processes. 更新2.我的一位朋友指出陷阱仅报告由shell本身设置的信号,而不是任何父进程。 So we tracked down the ignore masks of all the parents, and lo and behold, rxvt-unicode had SIGFPE masked. 所以我们跟踪了所有父母的忽略掩码,并且看,rxvt-unicode已经屏蔽了SIGFPE。 A friend confirmed he could reproduce when he ran the executable using rxvt-unicode. 一位朋友确认他可以在使用rxvt-unicode运行可执行文件时重现。

Ignored signals are inherited across fork() and exec*() : 忽略的信号通过fork()exec*()继承:

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

I discussed this privately with the question author. 我与问题作者私下讨论过这个问题。 Debugging was complicated by the fact that bash saves and restores the signal mask from its parent process, and that the trap builtin only reports signals that were handled or ignored in the current shell , even though ignored signals inherited from the parent process will still take effect. 由于bash从其父进程保存并恢复信号掩码,并且内置trap仅报告当前shell中处理或忽略信号,即使从父进程继承的忽略信号仍然生效,调试也变得复杂。 。

It turns out the root problem was that he was running the test inside urxvt, which links libperl, which unconditionally ignores SIGFPE . 事实证明,根本问题是他在urxvt中运行测试,它连接了libperl, 无条件地忽略了SIGFPE

Signal masks and signal dispositions of SIG_IGN are inherited by child processes. SIG_IGN信号掩码和信号处置由子进程继承。 The only possibility I can think of is that your shell has SIGFPE masked or ignored for some reason and is not clearing this status before starting your program. 我能想到的唯一可能性是你的shell由于某些原因而屏蔽或忽略了SIGFPE ,并且在启动程序之前没有清除此状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM