以下內容是**
以前做專案碰到過乙個問題,在客戶的站點上面發現有嚴重的記憶體洩漏。幸運的是我們找到了重現的步驟,一輪下來大概有幾十兆的洩漏,但是以下常規方法卻沒啥用。
專案有幾百萬行**,但是我們認為可能發生大記憶體洩漏的就幾個點。把那幾個點的**都找了一遍,沒有任何結果。左尋右找,終於找到了一種比較笨但是卻很管用的方法。
1. 開啟windbg, attach程序。
2. 載入symbol
3. 打斷點 (可以用.logopen c:\memoryleak.txt把log記下來)
bp kernel32!virtualalloc ".printf\"#alloc memory# %lu \\n \",dwo(esp+8);!clrstack;g;"
4. 輸入g然後回車讓程序繼續跑。
5. 將重現步驟跑一遍,然後去review日誌。
接下來的過程比較笨,review日誌的過程中找到比較可疑的申請大塊記憶體的點,注釋**,編譯assembly替換,看記憶體洩漏還在不在。最終還是找到了那個洩漏的地方,乙個remoting的proxy,出了作用域但是其指向的記憶體去沒有被自動釋放。
解決這個問題的最關鍵的就是下面這條命令:
bp kernel32!virtualalloc ".printf\"#alloc memory# %lu \\n \",dwo(esp+8);!clrstack;g;"
它的作用就是在kernel32的virtualalloc函式上面打斷點,當該函式被執行到的時候,就把該函式申請的記憶體數量(在esp+8這個位置,dwo是把這個裡面的值轉成十進位制),以及呼叫該函式的託管棧(clrstack)列印出來,然後讓函式繼續跑(g)。
需要說明的是,這個命令僅對32位程序有效,因為根據32位cpu的calling convention,esp+4是第乙個引數位置,esp+8是第二個,以此類推。64位的程序要去再查一下對應的calling convention看相關引數在哪個位置。
lpvoid winapi virtualalloc(_in_opt_ lpvoid lpaddress,_in_ size_t dwsize,_in_ dword flallocationtype,
_in_ dword flprotect
);
windbg 用WinDbg探索ruby的奧秘
寫這篇文章是受 url 從main.c開始走進ruby 登上除錯ruby之旅 url 的啟發,不同的是該文章用的是gdb,gdb雖然很強大,但是畢竟是命令列,在除錯的時候,可能同時需要檢視許多資訊,比如call statck,彙編 源 等等,命令列就有點力不從心,所以續寫一篇,改gdb為同樣強大的w...
Windbg斷點命令
windbg斷點命令 1 bu bp bm設定軟體斷點 a bp設定位址關聯的斷點 b bu設定符號關聯的斷點 c bm支援設定含萬用字元的斷點,可以一次建立乙個或多個bu或bp bm d 斷點 bp和bu的主要區別 a bp所設斷點和位址關聯,如果模組把該位址的指令移到其它地方,斷點不會隨之移動,...
windbg命令示例
device tree 那的顯示僅僅是個名字而已 它們都是 device object 我還是喜歡 windbg 的原汁原味 0 kd drvobj atapi driver object 89de2b60 is for driver atapi driver extension list id a...