2009-11-23 65 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