GDB 正在杀死我的下等人。Inferior 是一个长时间运行(20-30 分钟)的基准测试。GDB和inferior都在我的uid下运行。运行良好一段时间然后我的信号处理程序使用 si_signo = 11、si_errno = 0 和 si_code = 0 的 siginfo_t 实例调用;_sifields._kill.si_pid = ( gdb-pid ),_sifields._kill.si_uid = ( my-uid )。
当 GDB 决定向我的劣质进程发送终止信号时,我读到了这篇文章。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 中的故障地址在受保护的内存范围内之后)。
但是,据我所知,si_code 为零的 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
所以我的信号处理程序看到一个 siginfo_t 结构体,si_signo 11 (SIGSEGV)、si_code = 0 (kill)、si_pid = 28706 (gdb) 和 si_user = 3001 (me)。GDB 报告 si_signo = 5 (SIGSTOP) 的 siginfo_t。
可能是劣质进程正在对原始 SIGSTOP 执行一些低级处理,并将其作为终止发送到链上。但这是我不理解/想要消除的原始 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 核/32 线程 Xeon、4x E7520、基于 Nehalem 的服务器上运行它。无论是启用还是禁用超线程,我都会得到相同的结果。