介紹
1. 什么是Windbg
- WinDbg是微軟發布的一款相當優秀的源碼級(source-level)調試工具,可以用於Kernel模式調試和用戶模式調試,還可以調試Dump文件。
- WinDbg是微軟很重要的診斷調試工具: 可以查看源代碼、設置斷點、查看變量, 查看調用堆棧及內存情況。
- Dump文件是進程的內存鏡像, 可以把程序的執行狀態通過調試器保存到dump文件中
2. Windbg可以解決以下問題
◆ 內存高
◆ CPU高
◆ 程序異常
◆ 程序Hang死
3. 使用windbg進行調試分析的兩種方式
- 使用windbg調試器attach到需要調試的進程。(會暫停進程的運行)
- 抓取進程的dump文件,使用windbg分析dump
一.准備
1.下載
官網地址:
https://developer.microsoft.com/zh-cn/windows/hardware/windows-driver-kit
選擇對應的工具包下載

2.安裝
- 下載之后點擊安裝,可選擇安裝的工具,我們只選擇windbg就可以。安裝之后在debuggers文件夾下選擇32位或64位程序運行

- 打開windbg之后,需要設置symbol path,可以按快捷鍵Ctrl+S。把下面的路徑粘貼進去保存。系統進行dump解析等操作的時候會自動下載需要的符號表
srvc:\symcachehttp://msdl.microsoft.com/download/symbols;c:\symcache;
3.抓取dump
1. 通過procdump獲取
下載地址:https://technet.microsoft.com/en-us/sysinternals/dd996900
下載之后為壓縮包,將文件解壓。通過dos命令來生成dump文件。下面為一條語句為示例
procdump -ma -c 0 -s 3 -n 2 sqlservr.exe -o E:\dumps\
這條語句的意思為:當sqkservr.exe這個進程運行時間cpu的占用超過0%,時間超過3秒,則在E:\dumps下生成一個dump文件。一直到生成2個為止。下面為命令介紹
- -ma 生成full dump, 即包括進程的所有內存. 默認的dump格式包括線程和句柄信息.
- -c 在CPU使用率到達這個閥值的時候, 生成dump文件.
- -s CPU閥值必須持續多少秒才抓取dump文件.
- -n 在該工具退出之前要抓取多少個dump文件.
- -o dump文件保存目錄.
- Sqlservr.exe可替換為進程的ID
下圖為運行示例(sqlserver等操作需要cmd以管理員權限打開)
2. 任務管理器抓取
可在任務管理器進程右鍵進程,點擊創建轉儲文件,系統會自動抓取和保存,保存完成會彈出對話框提示保存路徑

二.解析
1.解析dump文件
通過windbg的菜單,File—>Open Crash Dump選擇dump文件打開。打開成功界面如下圖所示:

2.命令
1.基本命令
- ? 獲取命令提示
- D 查看內存信息
- K 觀察棧
- ~ 顯示和控制線程 ~number s number為線程id 如:~1s為獲取1號線程的上下文
- Q 退出
- !runaway 查看線程占用cpu時間,可看出哪個線程占用時間最高(所有線程)
- .dump /ma E:/dumps/myapp.dmp 抓取dump
2.元命令
- .help 獲取命令提示
- .cls 清屏
- .ttime 查看線程占用cpu時間,可看出哪個線程占用時間最高(當前線程)
3..擴展命令
- . chain 獲取命令集列表。在已經加載的動態鏈接庫中。
- .load/.unload 加載/卸載命令模塊
- **!模塊名.help **查看某個擴展庫中包含的擴展命令
4..Net程序相關命令
基本
- !peb或!dlls 列出進程已經加載的dll
- **!threadpool ** 查看當前CPU狀況 線程數等等
- !dumpheap –stat 統計堆信息
- !Threads 所有托管線程 -special Crl創建的線程
- !clrstack 看看這個線程再干嘛 執行那些方法
- !clrstack –p addr addr:具體方法的參數值地址
- !do 地址 查看參數值
- !analyze –v 顯示分析的詳細信息
- .reload /i /f 強制重新加載pdb
內存調試
- **!eeheap –gc ** 獲取gc中內存信息
- !eeheap –loader Loader 堆信息
- !dumpheap –stat 統計GC堆的信息,統計GC堆上存活的對象
- !dumpheap -mt <
> 查看該地址上的對象 - !gcroot <<對象地址>> 查看對象根
- **!dumpheap -type <<System.String >> ** 查看string類型在堆中的信息
- !helproot -查看gcroot的幫助
在解析.Net程序時首先要加載運行環境framework版本對應的SOS.DLL:
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.DLL
這里只是寫一些比較常用的命令,想要詳細了解更多命令了以到官網查看
3.高內存占用示例

【讀取文件代碼】

【在代碼執行過程中抓取dump文件打開,並加載sos.dll】


【運行!dumpheap –stat獲取最高內存占用的地址】

【!gcroot address獲取調用函數】
最終,我們找到了高內存的調用入口!
當然如果gc堆上的占用內存較高的對象是自定義的類,那么就可以直接查看相關的調用函數來分析可能的問題了
