我读到这个,因为GDB决定向我的下级进程发送一个kill信号。 GDB在什么情况下会这样做?
这不是SIGSEGV(即使si_signo会建议它),因为si_code为0并且设置了si_pid和si_uid)。我的下级是一个多线程C ++应用程序,它有一个自定义信号处理程序来处理GPF,当应用程序遇到我设置的内存屏障以保护某些内存范围时。当我在GDB下运行时,我设置了
handle SIGSEGV noprint
确保GDB将与内存屏障相关的SIGSEGV信号传递给我的应用程序进行处理。这部分似乎工作正常 - 在siginfo_t结构中使用非零si_code的SIGSEGV被正确处理(在验证siginfo-> _sifields.si_addr中的错误地址在受保护的内存范围内之后)。
但是,siScode为零的SIGSEGV表示下层被杀,据我所知,覆盖_sifields._sigfault字段的_sifields._kill字段支持这种解释:GDB正在杀死我的下级进程。
我只是不明白是什么原因导致GDB这样做。
对此的更新:看起来GDB正在向下级发送SIGSTOP。如果我在失败时查看$ _siginfo,我会看到:
(gdb) p $_siginfo
$2 = {
si_signo = 5,
si_errno = 0,
si_code = 128,
_sifields = {
_pad = {0, 0, -1054653696, 57, 97635496, 0, 5344160, 0, 47838328, 0, -154686444, 32767, 47838328, 0, 4514687, 0, 0, 0, 49642032, 0, 50016832, 0, 49599376, 1, 0, 0, 92410096, 0},
_kill = {
si_pid = 0,
si_uid = 0
},
_timer = {
si_tid = 0,
si_overrun = 0,
si_sigval = {
sival_int = -1054653696,
sival_ptr = 0x39c1234300
}
},
_rt = {
si_pid = 0,
si_uid = 0,
si_sigval = {
sival_int = -1054653696,
sival_ptr = 0x39c1234300
}
},
_sigchld = {
si_pid = 0,
si_uid = 0,
si_status = -1054653696,
si_utime = 419341262248738873,
si_stime = 22952992424591360
},
_sigfault = {
si_addr = 0x0
},
_sigpoll = {
si_band = 0,
si_fd = -1054653696
}
}
}
但是我的信号处理程序看到了这个(有点模糊 * - 我在洁净室环境中工作):
(gdb) bt
#0 ***SignalHandler (signal=11, sigInfo=0x7fff280083f0, contextInfo=0x7fff280082c0) at ***signal.c:***
...
(gdb) setsig 0x7fff280083f0
[signo=11; code=0; addr=0xbb900007022] ((siginfo_t*) 0x7fff280083f0)
...
(gdb) p *((siginfo_t*) 0x7fff280083f0)
$4 = {
si_signo = 11,
si_errno = 0,
si_code = 0,
_sifields = {
_pad = {28706, 3001, -515511096, 32767, -233916640, 32767, -228999566, 32767, 671122824, 32767, -468452105, 1927272, 1, 0, -515510808, 32767, 0, 32767, 37011703, 0, -515511024, 32767, 37011703, 32767, 2, 32767, 1000000000, 0},
_kill = {
si_pid = 28706,
si_uid = 3001
},
_timer = {
si_tid = 28706,
si_overrun = 3001,
si_sigval = {
sival_int = -515511096,
sival_ptr = 0x7fffe145ecc8
}
},
_rt = {
si_pid = 28706,
si_uid = 3001,
si_sigval = {
sival_int = -515511096,
sival_ptr = 0x7fffe145ecc8
}
},
_sigchld = {
si_pid = 28706,
si_uid = 3001,
si_status = -515511096,
si_utime = 140737254438688,
si_stime = 140737259355762
},
_sigfault = {
si_addr = 0xbb900007022
},
_sigpoll = {
si_band = 12889196884002,
si_fd = -515511096
}
}
}
(gdb) shell ps -ef | grep gdb
*** 28706 28704 0 Jun26 pts/17 00:00:02 /usr/bin/gdb -q ***
(gdb) shell echo $UID
3001
所以我的信号处理程序看到一个带有si_signo 11(SIGSEGV),si_code = 0(kill),si_pid = 28706(gdb)和si_user = 3001(me)的siginfo_t结构。并且GDB使用si_signo = 5(SIGSTOP)报告siginfo_t。
可能是劣质过程正在执行原始SIGSTOP的一些低级处理,并将其作为一个kill发送到链。但它是我不理解/想要消除的原始SIGSTOP。
我应该补充一点,我在启动下级之前设置了以下指令(并且是否设置了句柄SIGSTOP指令没有区别):
handle SIGSEGV noprint
handle SIGSTOP nostop print ignore
这是否解决了这个问题?这让我很难过。此外,如果没有这里的见解,任何人都可以建议其他可能有助于发布此论坛的论坛吗?
(gdb) show version
GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6_0.1)
Copyright (C) 2010 Free Software Foundation, Inc.
我在1.8GHz 16 Core / 32 Thread Xeon,4x E7520,基于Nehalem的服务器上运行。无论是启用还是禁用超线程,我都会得到相同的结果。
答案 0 :(得分:0)
在Linux下, si_signo = 11 表示这是传播 SIGSEGV 的GDB。有关信号编号,请参阅signal(7)。
尝试:
(gdb) handle SIGSEGV nopass
Signal Stop Print Pass to program Description
SIGSEGV Yes Yes No Segmentation fault
尝试将您使用 sigaction()注册的信号处理函数的第三个参数转换为(ucontext *)并转储CPU寄存器。特别是指令指针可以提供一些线索:
#include <ucontext.h>
int my_sigsegv_handler(int signo, siginfo_t *info, void *context)
{
ucontext *u = (ucontext *)context;
/* dump u->uc_mtext.gregs[REG_RIP] o REG_EIP */
}
然后将指令指针传递给GDB中的 info addr 。
要真正了解正在发生的事情,我会尝试确定:
答案 1 :(得分:0)
我在使用gdb 7.4的不同程序上遇到了完全相同的问题。我升级到gdb 7.9 ---相同的机器和内核版本---问题消失了。在另一台机器上,gdb 7.7也可以工作。我的猜测是这个问题在gdb 7.5-7.7中修复了。