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、
定位到代碼,需要具體分析邏輯,查看是否真的泄漏,還是還沒來得及釋放。