我已经在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())。这与我无法通过调试器中的退出断点捕捉到这一事实是一致的。
_exit断点“丢失”的常见原因有两个-要么GDB未将断点设置在正确的位置,要么程序执行了(在道德上等效)syscall(SYS_exit, ...)
_exit
GDB
syscall(SYS_exit, ...)
什么info break和disassemble _exit怎么说?
info break
disassemble _exit
您也许可以说服GDB使用正确设置断点break *&_exit。或者,GDB-7.0支持catch syscall。不管程序如何退出,这样的事情都应该起作用(假设Linux/x86_64;请注意,ix86数字会有所不同):
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将导致进程终止)。
pthread_exit
info thread
编辑:
同样值得注意的是,您可以使用助记符名称,而不是syscall号。您还可以同时将多个系统调用添加到捕获列表,如下所示:
(gdb) catch syscall exit exit_group Catchpoint 2 (syscalls 'exit' [1] 'exit_group' [252])