利用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”沒發生
5、windbg中執行緒資訊如下,發現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、
定位到程式碼,需要具體分析邏輯,檢視是否真的洩漏,還是還沒來得及釋放。