2012-05-02 155 views
2

我對堆棧軌跡的理解基本上是基於What is exactly the base pointer and stack pointer? To what do they point?如果EBP幀指針爲NULL,堆棧是否損壞?

我一直在幫助開發多年的程序在崩潰時吐出堆棧轉儲,並且我習慣於評估這些堆棧跟蹤,與C++編譯器生成的.map文件相對應。有很多次,我已經成功地走過堆棧並調試問題。

但是,有時堆棧跟蹤有一個NULL EBP(幀)指針。下面是從這樣的樣品堆棧轉儲相關片段:

Initial EBP pointer value: 04d8fab0 
{at address 04d8fab0: 00000000} 

正如可以看到,在EBP幀指針的值是NULL。所以我不能走棧。

這是一個損壞堆棧的標誌,還是有另一種可能的解釋?

+0

您是否正在構建優化?有時編譯器會使用'%ebp'作爲通用寄存器來給它一個額外的註冊表來處理......這是以使跟蹤堆棧幾乎不可能的代價爲代價的。大多數編譯器也可以選擇禁用這種行爲。 – FatalError

+0

您使用哪種編譯器和編譯標誌? – Neil

+1

在Visual Studio中,「Omit Frame Pointers」選項設置爲「No」(在發行版以及調試模式下)。的確,在許多堆棧軌跡中,幀指針是有效的。是否有可能是幀指針有時是有效的,而忽略幀指針不符合我的期望? –

回答

1

正如您所看到的,EBP幀指針的值爲NULL。因此, 我不能走棧。這是堆棧損壞的標誌,還是有其他可能的解釋嗎?

我認爲另一種解釋,紮根,除了保持當前堆棧幀的地址,EBP寄存器也可用於類似通用寄存器任何其他目的的事實。爲了做到這一點安全,需要兩兩件事:

  1. 存儲其當前內容到堆棧中通過調用

    PUSH EBP

  2. 恢復中普通後的內容通用電話

    POP EBP

所以我在想您所遇到不一定由堆棧損壞引起的情況下,因爲它在技術上可能是已生成轉儲而暫時被用於一般EBP寄存器在過程的代碼中的其他地方使用它,甚至可能不是你編寫的代碼。

+0

有趣的可能性。你知道這樣的行爲是否真的會發生,或者這純粹是一種理論上的可能性,據你所知? –