2008-09-23 374 views
13

這是什麼意思,當它回溯以下輸出?GDB回溯消息「??()中的0x0000000000000000」是什麼意思?

#0 0x00000008009c991c in pthread_testcancel() from /lib/libpthread.so.2 
#1 0x00000008009b8120 in sigaction() from /lib/libpthread.so.2 
#2 0x00000008009c211a in pthread_mutexattr_init() from /lib/libpthread.so.2 
#3 0x0000000000000000 in ??() 

該程序已崩潰與標準信號11,分段故障。 我的應用程序是一個在FreeBSD 6.3上運行的多線程FastCGI C++程序,使用pthread作爲線程庫。

根據信息來源,它已經用-g編譯並且我的源代碼的所有符號表都被加載。

很明顯,我的實際代碼沒有出現在跟蹤中,而是錯誤似乎來自標準pthread庫。特別是,什麼是? ()?

編輯:最終在我的主代碼中將崩潰追蹤到一個標準的無效內存訪問。沒有解釋爲什麼堆棧跟蹤已損壞,但這是另一天的問題:)

回答

9

gdb無法從pthread_mutexattr_init中提取正確的返回地址;它的地址爲0.「??」是在符號表中查找地址0的結果。它找不到符號名稱,因此它會打印默認的「??」

不幸的是,我們不知道爲什麼它不能提取正確的返回地址。

3

確保您使用調試符號進行編譯。 (對於gcc我認爲這是-g選項)。那麼你應該可以從GDB中獲得更多有趣的信息。編譯生產版本時不要忘記關閉它。

0

也許導致崩潰的錯誤已經破壞了堆棧(覆蓋堆棧的一部分)?在這種情況下,回溯可能是無用的;不知道該怎麼辦...

5

你確實導致線程庫崩潰。由於線程庫本身沒有使用調試符號(-g)編譯,因此無法顯示崩潰發生時的源代碼文件或行號。另外,由於它是線程,調用棧不會指向您的文件。不幸的是,這將是一個棘手的錯誤追蹤,你將需要通過你的代碼,並嘗試縮小時發生的崩潰。

2

我可能會錯過一些東西,但這不是指示某人使用NULL作爲函數指針嗎?

#include <stdio.h> 

typedef int (*funcptr)(void); 

int 
func_caller(funcptr f) 
{ 
    return (*f)(); 
} 

int 
main() 
{ 
    return func_caller(NULL); 
} 

,如果你在gdb運行它這將產生一個回溯的相同的風格:

rivendell$ gcc -g -O0 foo.c -o foo 
rivendell$ gdb --quiet foo 
Reading symbols for shared libraries .. done 
(gdb) r 
Starting program: ... 
Reading symbols for shared libraries . done 

Program received signal EXC_BAD_ACCESS, Could not access memory. 
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000 
0x00000000 in ??() 
(gdb) bt 
#0 0x00000000 in ??() 
#1 0x00001f9d in func_caller (f=0) at foo.c:8 
#2 0x00001fb1 in main() at foo.c:14 

這是一個非常奇怪的崩潰,但... pthread_mutexattr_init很少做任何事情超過分配的數據結構和memset吧。我會尋找其他事情。是否有可能存在不匹配的線程庫或其他東西。我的BSD知識有點過時,但過去一直存在這個問題。