2010-12-08 27 views
2

我指的文章在http://www.wintoolzone.com/articles/AuthoringStackWalkerForX86.pdf製作堆棧沃克工程中的應用與優化啓用

我使用VC++ 2008年。我意識到,當我把優化「最大速度(/ O2)」,連我設置將「忽略幀指針」顯式指定爲否,獲取函數返回地址將無法通過堆棧幀指針正確工作。

在文章中,它提到:

「要求堆棧幀指針是 存在於所產生的碼 優化代碼,其中堆棧幀 指針不存在將不會被該代碼被踩踏 。它的左邊是練習 ,供讀者通過 來實現這個代碼庫。「

我想知道,你們中的任何一個人都有一種可移植的方式,可以通過優化和非優化代碼,而不需要假設堆棧幀指針的可用性?

目前,每一個功能由具有

push  ebp 
mov   ebp,esp 

作爲函數的代碼的第一行上述堆步行者例如正在假設。

我曾經試過RtlCaptureStackBackTrace,但其侷限性高達62幀不爲我的目的。

回答

1

我想它的主要假設是不圖案

push  ebp 
mov   ebp,esp 

而是ebp始終用作幀指針的假設。這允許簡單的堆棧展開:ebp指向上次保存的堆棧幀,其上面的所有數據都是本地數據,堆棧中的下一個值是調用者的返回地址。簡單。

對於一個複雜的問題,你應該literaly「轉儲」堆棧,想告訴儘可能多的關於每個值。它只是一個價值嗎?返回地址?函數的參數?或者一個字符串?

要檢查一個DWORD是一個返回地址,你可以enumarate所有加載的模塊,並獲得他們的部分與執行權的地址範圍。 (也許VirtualQuery也可以做到)。

通過每個模塊上執行的「庫存」,你可以得到所有導出的符號列表。這會給你至少一些名字。

0

堆棧行走應該工作得很好,但有些函數調用可能已完全優化,如內聯和尾調用消除,所以當然,他們不會在調用堆棧顯示出來。

+0

但我的測試結果顯示事實並非如此。看到我更新的評論。 – 2010-12-08 03:59:48