首页 > 解决方案 > gdbserver 无法中断“SOME”进程,gdbserver 调用的kill(pid,2) 没有向进程发送 SIGINT,这是怎么回事?

问题描述

环境是:

目标:x86_64 客户端,运行条带化的程序

主机:x86_64 服务器,有代码,工具链,条带程序,用于调试的符号文件

在目标上运行 gdbserver:

%gdbserver --multi :1234 /pathtolog/gdb.log

在目标上运行程序:

./someprogram &

[1] PID

在主机上运行 gdb:

%gdb

(gdb)target 扩展远程 TARGETIP:1234

(gdb)file someprogram

(gdb)setrootfs pathtorootfs

(gdb)...//设置库路径等

(gdb) 附加 PID

...//正常加载所有内容

...//停在某处

(gdb)c

^C^C目标没有响应中断请求。

停止调试吗?(是或否)

试图找到根本原因:

在目标上:

gdb 附加到 gdbserver(是的,我现在可以在目标上使用 gdb,但是目标机器应该在没有 gdb、符号等的情况下发布)。

(gdb) b 杀死

0xf760afb0 处的断点 1

(gdb) c

继续。

从主机 gdb 按 ctrl+c 时,gdbserver 将进入断点

断点 1, 0xf760afb0 in kill() from /lib/libc.so.6

(gdb)

我检查了寄存器,%esp 寄存器显示如下:

(gdb) x /32wx 0xffee8070

0xffee8070: 0xffffffe0c 0x00000002 0x00000001 0x00000000

0xffffffe0c = -PID 0x00000002 = SIGINT

当 gdbserver 继续时,某些程序会收到信号。所以,kill() 对“某些程序”有好处,不是全部。

我在 gdb/gdbserver 之间使用 tcpdump 监控数据。如果 kill() 有效(对于“GOOD”程序),gdbserver 将向 gdb 发送一个数据包。

我试过sigmonitor,发现在这种情况下 gdbserver 没有向“BAD program”发送任何信号。但我可以调用 kill(pid,2) int gdbserver 调试 gdb 进程

(gdb) 调用 kill(PID,2)

然后 dmesg 像这样显示

[11902.060722] ==========send_signal===========

          SIG 2 to 6141[a.out], tgid=6141

...

          SIG 19 to 6142[a.out], tgid=6141

[11902.111135] 6142 的任务树 = {

...

有任何想法吗?

标签: linuxdebugginggdbgdbserver

解决方案


发现gdbserver 可能的匹配错误。gdbserver 调用的 kill() 参数是 -PID,而不是 PID。

gdbserver 不向进程发送 SIGINT,而是向进程组 (-signal_pid) 发送 SIGINT。但附加的进程并不总是进程组的领导者。如果没有,“kill (-signal_pid, SIGINT)”返回错误并且无法中断附加的进程。

static void linux_request_interrupt (void)
{
  /* Send a SIGINT to the process group.  This acts just like the user
     typed a ^C on the controlling terminal.  */
-  kill (-signal_pid, SIGINT);
+  kill (signal_pid, SIGINT);
}

这个问题在gdb-8.1中仍然存在,不知道为什么他们不认为这是一个问题。


推荐阅读