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

时间:2009-11-23 02:04:20

标签: linux unix gdb

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

(gdb) c
...
[New Thread 47513671297344 (LWP 15279)]
[New Thread 47513667103040 (LWP 15280)]
[New Thread 47513662908736 (LWP 15281)]

Program exited with code 0177.
(gdb)

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

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

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

3 个答案:

答案 0 :(得分:26)

_exit断点“错过”有两个常见原因 - GDB未将断点设置在正确的位置,或者程序执行(道德等同于){{ 1}}

syscall(SYS_exit, ...)info break说什么?

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

ix86

更新:
您的注释表明_exit断点设置正确,因此您的流程可能不会执行(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和另一种可能性(我以前错过了):所有执行syscall(SYS_exit, ...)的线程。您可能还希望在pthread_exit上设置断点(并在每次点击时执行pthread_exit - 最后一个要执行info thread的线程将导致进程终止。

修改

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

pthread_exit

答案 1 :(得分:1)

在_exit上设置断点是个好主意。

您也可以尝试静态链接,只是为了从表中获取一堆潜在的gdb复杂功能。

0177可疑等待状态 wait(2)返回已停止的孩子,但gdb正在打印退出状态,是另一回事,所以这可能是一个真正的退出论点。

答案 2 :(得分:1)

可能是您在加载到进程中的某些共享库中有一些未解析的惰性引用。我有完全相同的情况,“有人在某处”退出过程,似乎是未解决的参考。

使用“ldd -r”选项检查您的流程。

看起来像ld.so或者懒惰解析某些符号以统一退出函数(应该是中止恕我直言)。

我的情况:

$ ldd ./program
undefined symbol: XXXX  (/usr/lib/libYYY.so)

$./program
program: started! 
...
<program is running regardless of undefined references>

当我调用一些使用未定义函数的场景时,现在退出了。它始终以exitcode = 127退出,gdb报告为0177。