2017-03-29 91 views
1

雖然試圖分析廣發行核心轉儲(過程由斷言SIGABRT拋棄)我得到以下輸出回溯:內核轉儲GDB「回溯停止:框架未保存PC」

(gdb) bt 
#0 0x76d6bc54 in raise() from ./lib/libc.so.1 
#1 0x76d63bb8 in abort() from ./lib/libc.so.1 
Backtrace stopped: frame did not save the PC 
(gdb) thread apply all bt 

的二進制文件是用「-g」編譯的,因此除了工具鏈中的鏈接庫(例如libc甚至沒有符號),我都無法確定它是如何構建的。

這是堆棧損壞或者是它的libc的結果被用類似「fomit幀指針」編譯。

彷彿未捕獲的異常從運行鏈接庫和庫發生一般性的問題沒有得到調試建會發生什麼情況,即可以將信息轉儲仍然包含有用的信息?

由於

改善回溯其包括從共享對象功能而不調試符號

回答

0

一種方法是安裝調試符號,其中的gdb可以看到它們。如何做的細節取決於你的環境。例如,如果libc.so.6libc6軟件包在Debian系統上提供,則安裝libc6-dbg軟件包會在/usr/lib/debug/.build-idlibc6軟件包,除libc.so.6之外,提供許多其他剝離的共享對象)下放置多個符號表。如果您使用的是調試環境非本地核心(由./lib/libc.so.1領先.所建議的),你可能會提取這樣的包,而不是安裝它(Debian系統dpkg -x上是這樣做的一種方式)。

除了調試符號的問題,在某些情況下,您可以通過確保gdb看到的共享對象(剝離或其他方式)正確對應於轉儲過程中使用的共享對象來改善回溯核心。一種檢查方法是比較file命令報告的構建ID(在典型的Linux系統上)。如果您可以可靠地確定在覈心轉儲時使用哪些共享對象,並且它假設您的共享對象是以包含構建ID的方式構建的,則這隻會有所幫助。

在某些情況下可執行的和生成的ID的所有相關的共享對象可以被可靠地從核心文件本身提取。在Linux系統上,這需要在覈心中存在文件註釋,並且需要存在可執行文件的第一頁和每個共享對象。最近配置了典型默認值的Linux內核包括所有這些內核。

https://github.com/wackrat/structer提供,其提取從建立滿足其假設一個核心文件ID Python代碼。根據核心文件的大小,最好使用64位系統,即使核心本身來自32位系統也是如此。

如果事實證明gdb正在爲該內核使用正確的共享對象(或者如果沒有可行的方法來確認或反駁),另一種可能是反彙編由gdb報告的兩個堆棧幀中的代碼。如果gdb看到的共享庫不適合這個核心,反彙編很可能是神祕的,因爲gdb依賴於共享對象的內容,它在覈心文件時使用該內容與該位置的內容對齊被轉儲(只讀段通常被排除在覈心文件之外,除了提供每個構建ID的第一頁之外)。根據我的經驗,gdb通常可以在沒有調試符號的情況下提供連貫的回溯,即使沒有幀指針,但是如果使用了錯誤的共享對象,gdb可能會根據與該位置的正確內容不相對應的指令進行回溯。

+0

Thanky Erik。我不知道你可以從coredump恢復共享對象,這意味着堆也被傾倒?我嘗試運行structer,但由於某種原因,我遇到了[例外](https://hastebin.com/wudewixoko.sql) – Serj

+0

結構代碼中的異常是由於核心文件的auxv中無法識別的段類型造成的; structer.elf.enums.PType需要更改以處理它,並且在異常處理代碼中還有改進的空間。 –

0

我認爲罪魁禍首是應用程序加載的libc。它可能編譯了一些使coredump無用的選項。我所做的是創建一個自定義工具鏈(使用從buildroot編譯的工具鏈),並使用該工具鏈編譯和運行應用程序。然後我能夠成功讀取coredump。