2012-10-22 62 views
1

我在應用程序中獲得了核心轉儲,並且當我嘗試分析它時,似乎它已經損壞了堆棧。任何人都可以幫助我解決問題的根源嗎?GDB核心轉儲有損壞的堆棧,顯示「堆棧幀無法訪問地址0x12處的內存」

Program terminated with signal 11, Segmentation fault. 
#0 0x40173f54 in nanosleep() from /lib/libc.so.6 
(gdb) bt 
#0 0x40173f54 in nanosleep() from /lib/libc.so.6 
#1 0x401b2a1c in __libc_enable_asynccancel() from /lib/libc.so.6 
#2 0x0000cdb8 in ??() 
Cannot access memory at address 0x12 



(gdb) info frame 
Stack level 0, frame at 0xbeaedbc0: 
pc = 0x40173f54 in nanosleep; saved pc 0x401b2a1c 
called by frame at 0xbeaedbd8 
Arglist at 0xbeaedbc0, args: 
Locals at 0xbeaedbc0, Previous frame's sp is 0xbeaedbc0 
(gdb) info frame 1 
Stack frame at 0xbeaedbd8: 
pc = 0x401b2a1c in __libc_enable_asynccancel; saved pc 0xcdb8 
called by frame at Cannot access memory at address 0x12 
(gdb) info frame 2 
Stack frame at Cannot access memory at address 0x12 

回答

2

這個堆棧可能會損壞也可能不會損壞,這也可能發生在-fomit-frame-pointer。

對於它的價值,這裏是我目前的策略。我不認爲這是一個最佳策略,只是目前適用於我的一個策略:

  1. 獲取符號。關於代碼的信息越多,您必須通過自己重新創建信息來減輕痛苦。

  2. 我手動重新構建堆棧。爲此,我通常開始將堆棧中找到的指針對齊值發送到'info symbol',以查看我是否可以獲得任何有用的信息。缺少符號,解碼在可能由值指向的存儲器位置處找到的'指令'也是有用的,如果作爲指針被採用,則該位置將接近已知的代碼位置。這可以調用具有符號的位置。

  3. 當我的堆棧增長下降(這裏是這種情況),我發現可以看到哪些候選函數被稱爲最後一個有效函數。

  4. 我嘗試重現該問題。如果我能讓事情失敗,所有事情都會輕鬆一些。

  5. 然後我看看堆棧,並嘗試確定損壞開始時的偏移量。

  6. 我通過程序集爲候選函數獲取有關哪些數據結構出現在哪些偏移量的提示。

  7. 最後,有可能是隨機點擊一段內存(例如,另一個線程吹過了它自己的堆棧,錯過了可能的守護頁並擊中了你的堆棧)。如果你還沒有任何線索,成爲掃描內存指向堆棧損壞部分的指針,然後對您找到的數據結構進行逆向工程的時候。