一尘不染

设置gdb出口断点不起作用?

linux

我已经在exit和_exit和我的程序(多线程应用程序,在linux 2.6.16.46-0.12
sles10上运行)上设置了断点,但仍以某种我无法找到的方式退出

(gdb)c
...
[新线程47513671297344(LWP 15279)]
[新线程47513667103040(LWP 15280)]
[新线程47513662908736(LWP 15281)]

程序退出,代码为0177。
(gdb)

退出函数驻留在libc中,因此没有延迟的负载共享库问题。有人知道其他无法捕获的神秘触发吗?

编辑:问题现在仅是学术性的。我尝试了二进制搜索调试,撤消了部分更改(问题消失了)。再次按顺序应用它们之后,即使恢复到原始状态,我也无法再解决问题。

EDIT2:我最近发现了这种错误的一个原因,这可能是此问题的原始出处。由于历史原因,我们的产品使用了邪恶的链接器标志-
Bsymbolic。这样做的副作用之一是,当一个符号未定义但被调用时,GLIBC运行时链接程序将以这种方式轰炸,您会在调试器中将其视为进程以0177退出。当运行时链接程序以这种方式中止时,我猜想它会使syscall直接调用_exit(而不是使用C运行时库exit()或_exit())。这与我无法通过调试器中的退出断点捕捉到这一事实是一致的。


阅读 355

收藏
2020-06-03

共1个答案

一尘不染

_exit断点“丢失”的常见原因有两个-要么GDB未将断点设置在正确的位置,要么程序执行了(在道德上等效)syscall(SYS_exit, ...)

什么info breakdisassemble _exit怎么说?

您也许可以说服GDB使用正确设置断点break *&_exit。或者,GDB-7.0支持catch syscall。不管程序如何退出,这样的事情都应该起作用(假设Linux/x86_64;请注意,ix86数字会有所不同):

(gdb) catch syscall 60
Catchpoint 3 (syscall 'exit' [60])
(gdb) catch syscall 231
Catchpoint 4 (syscall 'exit_group' [231])
(gdb) c

Catchpoint 4 (call to syscall 'exit_group'), 0x00007ffff7912f3d in _exit () from /lib/libc.so.6

更新:
您的注释表明_exit断点设置正确,因此您的进程很可能没有执行_exit

这留下syscall(SYS_exit, ...)了另一种可能性(我之前没有提到过):所有线程正在执行pthread_exit。您可能还希望在其上设置一个断点pthread_exit(并在info thread每次单击该断点时执行-最后一个线程执行pthread_exit将导致进程终止)。

编辑:

同样值得注意的是,您可以使用助记符名称,而不是syscall号。您还可以同时将多个系统调用添加到捕获列表,如下所示:

(gdb) catch syscall exit exit_group
Catchpoint 2 (syscalls 'exit' [1] 'exit_group' [252])
2020-06-03