Windbg找出memory leak的一種笨辦法

2022-07-05 08:36:12 字數 1268 閱讀 2327

以下內容是**

以前做專案碰到過乙個問題,在客戶的站點上面發現有嚴重的記憶體洩漏。幸運的是我們找到了重現的步驟,一輪下來大概有幾十兆的洩漏,但是以下常規方法卻沒啥用。

專案有幾百萬行**,但是我們認為可能發生大記憶體洩漏的就幾個點。把那幾個點的**都找了一遍,沒有任何結果。左尋右找,終於找到了一種比較笨但是卻很管用的方法。

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...