我有一个简单的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运行可执行文件时可以重现。
答案 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
屏蔽或忽略,并且在开始你的程序之前没有清除这个状态。