1. 程式人生 > >利用windbg分析崩潰,控制代碼洩漏,死鎖,CPU高,記憶體洩漏

利用windbg分析崩潰,控制代碼洩漏,死鎖,CPU高,記憶體洩漏

Windbg的一些簡單使用命令

一、崩潰

1、  輸入.ecxr;kbn得到崩潰的堆疊

其中原始碼如下

2、  檢視堆疊和原始碼,發現第0幀導致崩潰,程式碼也是原生代碼

輸入.frame  0,切到第0幀如下

3、  輸入 dv 檢視當前幀的一些變數資訊

         發現變數p =0x00000000

二、控制代碼洩漏

1、  啟動程序

2、  用windbg附加到程序

3、  !htrace  -enable命令開啟控制代碼檢測

4、  !htrace  –snapshot

5、  執行一段時間後

6、  !htrace –diff

得到如下資訊

標紅函式建立了event

7、輸入lsahandleLeak!ThreadProc1+0x00000037

這樣就可以看出程式碼中在不停CreateEvent

補充:

可以在windbg調式中,輸入!handle可以得到當前堆疊的一些控制代碼資訊,可以看出這個堆疊event非常多。


三、死鎖

1、  啟動程序

2、  Windbg附加程序

3、  輸入~*kv, 輸出所有執行緒

4、  輸入!findstackntdll!RtlEnterCriticalSection,查詢哪些執行緒在等待鎖

或者看程式碼某一函式沒執行,對比windbg中的執行緒,找到執行緒id分析


圖1是原始碼,圖2是執行結果, ThreadProc1函式中的 ThreadProc1 lock g_mutex2沒發生

,懷疑是否死鎖了

5windbg中執行緒資訊如下,發現ThreadProc1在等某一把鎖

第三幀是原生代碼對比原始碼發現在等鎖g_mutex2;

第二幀是系統函式在等待鎖,鎖地址為00bf7140

6、輸入!cs 00bf7140,檢視這把鎖資訊

 發現鎖的佔有者是0x00002cc4

7、輸入~~[0x00002cc4],發現對應是3號執行緒


8、切到3號執行緒,並輸出堆疊

發現程式碼27號,也在等一把鎖,鎖地址00bf7158

9、同理輸出鎖資訊

        

10、發現鎖佔有者0x00004c80,切到執行緒0x00004c80,並輸出堆疊

發現是剛才的2號執行緒

 至此分析完成2號執行緒和3號執行緒發生死鎖。

四、CPU高

1、  啟動程序

2、  Windbg附加程序

3、  輸入!runaway

4、  發現2號執行緒cpu最高,切到2號執行緒,並輸出堆疊


5、  可以得到是cpuhigh!ThreadProc1+0x35


 五、記憶體洩漏

5.1、windbg手動分析

1、設定gflags.exe,這工具和windbg在同一目錄

 2、  windbg附加到程序,輸入!heap –s

3、程式執行一段時間之後,再次輸入!heap–s

發現00970000這個堆有增加,其他無變化

4、輸入!heap -stat -h00970000,檢視這個堆狀態


發現這個堆的記憶體主要是被大小為0x224的塊佔用

 5、輸入!heap -flt s 224, 檢視224這些塊被誰在使用

6、輸入!heap -p -a 00971d20,檢視堆疊

7、  已經得到堆疊,本地有原始碼,還可以檢視程式碼,

輸入lsa memoryleak!ThreadProc1+0x00000048

 

 5.2、利用umdh分析

1、同5.1設定gflags配置

2、開啟命令視窗cmd,輸入要定位記憶體洩露的程式gflags.exe /i memoryleak.exe +ust

3、  設定程式的符號表路徑

SET _NT_SYMBOL_PATH=SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols;F:\windbgtest\Debug

4、  啟動memoryleak.exe,利用umdh建立第一次heap快照

輸入umdh-pn:memoryleak.exe -f:memory1.log

5、  執行一段時間後,再次輸入快照,umdh -pn:memoryleak.exe -f:memory2.log

 6、  分析前後2次快照的差異umdh -dmemory1.log memory2.log -f:memoryleak.log

會在當前路徑下面生成memoryleak.log,開啟分析

7、


定位到程式碼,需要具體分析邏輯,檢視是否真的洩漏,還是還沒來得及釋放。