2009-11-23 62 views
16

我给自己定的退出和_exit和我的程序断点(多线程应用程序,在Linux上2.6.16.46-0.12 SLES10运行),在某种程度上是一种方式还是离开我找不到设置gdb退出断点不起作用?

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

Program exited with code 0177. 
(gdb) 

出口函数驻留在libc中,因此不存在延迟加载共享库问题。任何人都知道一些其他不可捉摸的神秘的退出触发器?

编辑:问题现在只是学术。我尝试了二进制搜索调试,取消了我的更改的一个子集(问题消失了)。在我再次依次应用它们之后,即使事物恢复到原始状态,我也不能再重现问题。

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

回答

22

有用于_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将导致进程终止)。

编辑:

另外值得一提的是,你可以使用记忆的名字,而不是系统调用号。您还可以同时在多个系统调用添加到捕获列表,像这样:

(gdb) catch syscall exit exit_group 
Catchpoint 2 (syscalls 'exit' [1] 'exit_group' [252]) 
+0

我会尝试构建gdb 7并查看它显示的内容。在*给出了同样的指令地址:

 (gdb) b _exit Breakpoint 2 at 0x2aeea040f250 (gdb) b *&_exit Note: breakpoint 2 also set at pc 0x2aeea040f250. Breakpoint 3 at 0x2aeea040f250 
 0x00002aeea040f250 <_exit+0>: mov %fs:0x0,%r9 ... 0x00002aeea040f275 <_exit+37>: syscall 
(看起来像一个相当标准的系统调用)。 我想我至少已经隔离了导致这个神秘退出的代码改变,只是不明白细节。 – 2009-11-23 04:05:35

+2

最好使用'catch syscall exit'和'catch syscall exit_group'而不是数值。例如,在我的系统中,'exit'是'[1]'不''[60]'。 – Ruslan 2014-05-24 07:23:47

+0

此外,您可以使用'catch syscall exit exit_group'设置两者。事实上,现在编辑它... – 2015-06-10 17:51:19

1

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

你也可以尝试静态链接,只是为了从表格中挖掘一堆潜在的gdb复杂性。

0177是很像的等待状态wait(2)回报孩子停止,但广发行正在打印退出状态,这是一个不同的事情,所以这可能是一个真正的退出的说法。

+0

OP表示他已经有_exit和退出断点。另外,0177是127.你从127到SIGCHLD的世界如何? – 2009-11-23 03:21:16

+0

哦,错过了出口。但我对待等待状态是正确的。我显然不是在谈论信号编号,但状态'wait(2)'返回一个停止的过程。看看这个:$ grep IFSTOPPED /usr/include/bits/waitstatus.h'#define __WIFSTOPPED(status)(((status)&0xff)== 0x7f)',AND,'0x7f == 0177'。但我同意这不是发生在这里。 – DigitalRoss 2009-11-23 03:56:58

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.

+0

这似乎不是这里的情况。我的可执行文件中没有未定义的符号(不是退出,也没有其他)。 – 2010-02-16 21:22:14