2009-10-28 66 views
1

GDB似乎永遠只是爲C程序的工作,但對於C++我經常得到這些神祕的堆棧:調試C++從GDB的核心文件

(gdb) bt 
#0 0x08055fa4 in std::runtime_error::what() 
#1 0x080576c8 in std::runtime_error::what() 
#2 0x08057dda in std::runtime_error::what() 
#3 0x080580d2 in std::runtime_error::what() 
#4 0x08058662 in std::runtime_error::what() 
#5 0x08058725 in std::runtime_error::what() 
#6 0x0806ef7a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>() 
#7 0x00c0adec in __libc_start_main() from /lib/libc.so.6 
#8 0x0804d011 in std::runtime_error::what() 

從而在表面提供絕對沒有線索,問題出在哪裏發生。無論如何,從這樣的核心文件中獲取更多信息 - 或者讓程序轉儲更有用的東西?

+0

只是一些進一步的信息,有問題的Makefile有-g選項,但也有-s,它去除了調試信息... grrrrr。所以希望消除那個愚蠢的旗幟會讓我下一次更好的核心。 – 2009-10-29 02:23:59

回答

5

std::runtime_error::what()的文本實際上不可能覆蓋從回溯建議的從0x0804d011到0x08058725的範圍。這將超過45KB的代碼。

它更可能是正在嘗試符號查找代碼來解決0x08055fa4,0x080576c8等被簡單地定位std::runtime_error::what()因爲之前這些地址的最後一個可用的符號,這往往是剝離可執行文件的結果(因爲你有通過將-s切換到鏈接程序完成)。

我將重點放在堆棧幀#6上。由於這是一個相當簡單的類的ctor,我的SWAG將會是你已經傳入了一個NULL指針或一個指向非NULL終止字符串的指針。

編輯:請注意,如果你只是從重建完全相同的源可執行沒有-s開關,你會從GDB得到一個更有用的堆棧,使用core文件你已經離開。沒有必要等待新建的可執行文件再次轉儲core

2

我一直使用GDB作爲C++,並且通常沒有堆棧回溯問題,當然,這個堆棧並沒有被某些緩衝區溢出所粉碎。

關於C++程序中的堆棧回溯與C程序之間沒有任何內在差異,這會使您更難解釋回溯。你確定:

A)你的程序不是以某種方式粉碎堆棧? B)你正在用-g標誌編譯?

0

首先,確保你已經設置-pg -ggdb編譯器標誌:

g++ -pg -ggdb prog.cpp -o prog

第一個生成gprof的分析信息(你可能需要它),而第二個包含調試的可執行文件的信息。

要檢查覈心文件,使用這樣的:

gdb -quiet -se=prog -c prog.core

這應該始終提供足夠的信息來解決核心轉儲:)
乾杯!