1、故事背景
最近同事的**中碰到乙個bug會導致奔潰的bug,從dump上看是由於某個物件的堆記憶體指標被釋放了,但**仍呼叫了該物件指標的虛函式,從而引起記憶體訪問違法崩潰,由於該類被大量使用,無法直接定位到具體哪個類被提前釋放了,從而打算開啟堆頁檢查,跟蹤該物件堆記憶體指標被釋放的**位置,從而揪出元凶。
由於此bug在win7的機器上不易重現,在xp sp3的機器上較容易重現,故準備在xp sp3的機器上開啟堆頁檢查(dhp),跟蹤該物件指標被釋放的**位置和時機,由於未從用過gflag進行堆頁檢查和除錯,故先寫了段小**練練手:
用gflag開啟堆頁檢查:
設好符號檔案後祭出 windbg 走起,崩潰觸發後斷下,輸入 !heap -p -a ecx 指令一舉揪出元凶,但現實卻是如此的骨感:
004010d9 8b11 mov edx,dword ptr [ecx] ds:0023:0161cff0=????????
0:000> !heap -p -a ecx
readmemory error for address eeddccee
use `!address eeddccee' to check validity of the address.
注:此處 ecx = pctest
"mov edx,dword ptr [ecx]"表示取虛表指標
0:000> !address ecx
015d0000 : 0161b000 - 000b5000
type 00020000 mem_private
protect 00000001 page_noaccess
state 00001000 mem_commit
usage regionusagepageheap
handle 015d1000
address命令正確的指示了該位址為私有堆記憶體,但該記憶體頁不可訪問。
難道是堆頁開啟不正確?檢查登錄檔:hkey_local_machine\software\microsoft\windows nt\currentversion\image file execution options,確定已經正確的設定了,嘗試其他多種設定,甚至換工具進行設定,但結依然如此。難道是機器問題?於是在win7 32位機器上重複上述過程,發現是可以正確的列印出堆記憶體指標被釋放的棧回溯的:
驚現「readmemory error for address eeddccee」,且只展示乙個page heap控制代碼了,剩下的未展示完全,但頁堆明明白白的現實已經開啟,也有了準頁堆,但資料卻顯示不出來,說明資料可能被破壞,但測試**如此簡單,而且也被windbg第一時間斷下,不可能去破壞資料,難道是windbg讀取有問題?於是再次對此疑問進行google,果然有個外國朋友也碰到了類似的問題,其在帖子中提出換成6.6.0007.5版即可解決,試了下果然在xp下順利輸出了使用者態棧回溯。那麼為什麼高版本的windbg會出現此問題呢?
我想起在查詢ust資料結構的時候,發現和《軟體除錯》上寫的不一致,當時疑惑了下沒有在意,再次翻出來對比發現:
win7下stacktracedatabase結構
xp下stacktracedatabase結構
win7下的 _stack_trace_database 結構和xp下並不完全相同,關鍵的 buckets(棧回溯記錄)的結構偏移改了,而且原xp下是個陣列,但win7下卻變成了鍊錶,故猜測高版本的windbg在xp下依然使用了win7下的某些資料結構,從而導致windbg解析出了問題,不知道算不算微軟的bug。
由於低版本的windbg已經很難找到了,故這裡也放出我找到的6.6.0007.5版:
widnbg6.6.0007.5.exe
在C Builder中使用XP視覺樣式
在c builder中使用xp視覺樣式 sdragon 2006 12 28 14 53 使用c builder的朋友都知道,c builder是不支援xp視覺樣式的 vision style 以前我為了讓自己寫的程式看起來漂亮一些,拼命的去自繪控制項 我沒有使用過第三方介面控制項,曾經安裝過,但是...
XP下超級終端的使用
超級終端 是乙個程式,使用數據機或一條零調製解調電纜乙太網連線,再呼叫此程式能夠連線到其他計算機 telnet 站點 公告板系統 bbs 聯機服務和主機。我們可以用它來除錯電路是否可行。下面是一些對超級終端常用的操作 通過傳送0x0c 12 即可實現清屏。有時可能傳送乙個沒有接收正確,連續傳送兩次0...
日文XP下,VIM 使用中文幫助
vimcdoc 1.6.0 setup.exe 2,安裝到 vim vimfile目錄下.3,vimrc 屬性設定 setguifont nsimsun h12 sethelplang cn guifont 用來設定介面顯示語言,helplang 用來指定幫助語言的型別,當然也可以設成en 改回原來...