
【基本介紹】
配置WinDbg運行WinDbg->菜單->File->Symbol File Path->按照下面的方法設(shè)置_NT_SYMBOL_PATH變量
在彈出的框中輸入“C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照這樣設(shè)置,WinDbg將先從本地文件夾C:\MyCodesSymbols中查找Symbol,如果找不到,則自動從MS的Symbol Server上下載Symbols)。另一種做法是從這個Symbol下載地址中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下載相應(yīng)操作系統(tǒng)所需要的完整的Symbol安裝包,并進行安裝,例如我將其安裝在D:\WINDOWS\Symbols,在該框中輸入“D:\WINDOWS\Symbols”。(這里要注意下載的Symbols的版本一定要正確,在我的Win2003+Sp1上,我曾經(jīng)以為安裝Win2003+Sp2的Symbols可能會牛×點,但結(jié)果證明我錯了,用WinDbg打開可執(zhí)行文件時,提示“PDB symbol for mscorwks.dll not loaded;Defaulted to export symbols for ntdll.dll”的錯誤,我有重新裝上Win2003+Sp1的Symbols, 現(xiàn)在一切運行正常^_^)
【調(diào)試準(zhǔn)備】
為了測試 WinDbg 中使用 SOS 擴展命令,我創(chuàng)建了應(yīng)用程序 "MemoryLeakApp.exe",Visual Studio 程序選擇為 64 位環(huán)境編譯。

"MemoryLeakApp.exe" 啟動運行后可能占用內(nèi)存600M。


此時,選擇使用 64 位 WinDbg 來調(diào)試程序。我們先通過 Attach Process 方式來調(diào)試。



當(dāng)然,如果我們使用了 32 位的 WinDbg 去 Attach 進程,會直接報錯。

【W(wǎng)inDbg常用命令手冊】
內(nèi)置幫助命令?
? 顯示常規(guī)命令
? /D 通過 DML(Debugging Markup Language) 方式顯示常規(guī)命令
.help
.help 顯示 . 系列命令
.help /D 通過 DML 方式顯示 . 系列命令
.help /D a* 通過 DML 方式顯示所有以 'a' 字母開頭的 . 系列命令

.chain
.chain 列出所有已加載的調(diào)試器擴展
.chain /D 通過 DML 方式列出所有已加載的調(diào)試器擴展

.extmatch
.extmatch /e ExtDLL FunctionFilter 顯示調(diào)試器擴展的所有導(dǎo)出函數(shù)
.extmatch /D /e ExtDLL FunctionFilter 通過 DML 方式顯示調(diào)試器擴展所有導(dǎo)出函數(shù)
.extmatch /D /e uext * 顯示 uext 擴展中的所有導(dǎo)出函數(shù)

.hh
.hh 打開 WinDbg 的幫助文件
.hh Text 打開 WinDbg 的幫助文件,并自動搜索 Text 的內(nèi)容
.hh dt 在 WinDbg 幫助文件中搜索 dt 命令
調(diào)試會話命令
.attach
.attach PID 附加到指定ID的進程
.detach
.detach 結(jié)束調(diào)試會話,被調(diào)試進程仍可繼續(xù)運行

q
q 結(jié)束調(diào)試會話,同時終止被調(diào)試進程的進行
qq 結(jié)束調(diào)試會話,同時終止被調(diào)試進程的進行
.restart
.restart 重啟被調(diào)試應(yīng)用
一般信息命令
version
顯示調(diào)試器版本信息和已加載的調(diào)試器擴展

vercommand
顯示調(diào)試器啟動文件的路徑

vertarget
顯示目標(biāo)機器的版本

CTRL+ALT+V
打開或關(guān)閉 Verbose 模式開關(guān),某些命令在此模式下可以給出更多詳細信息
.formats
.formats Expression 顯示數(shù)字的各種格式信息
.formats 5

.cls
清理屏幕
.last event顯示最新的異常信息或事件信息
.effmach
.effmach 顯示有效作用的機器信息
.effmach .
.effmach #
.effmach x86 | amd64 | ia64 | ebc
.time
顯示系統(tǒng)記錄的各種時間

.echo
.echo String 輸出字符串
.echo "String"
.echo "Hello World"
符號加載命令
ld
ld ModuleName 加載指定模塊的符號
ld * 加載所有模塊的符號

!sym
!sym 獲取符號加載狀態(tài)
!sym noisy 讓調(diào)試器顯示符號搜索詳細信息
!sym quiet 默認項,不顯示符號搜索信息

.sympath
.sympath 顯示和設(shè)置符號搜索路徑
.sympath+ 增加符號搜索路徑
.sympath+ C:\Symbols
.symopt
.symopt 顯示當(dāng)前符號可選項
.symopt+ Flags 添加符號可選項
.symopt- Flags 移除符號可選項
.symfix
.symfix 設(shè)置符號庫路徑
.sym+ DownstreamStore 添加符號庫路徑
x
x [Options] Module!Symbol 模式匹配符號信息
x /t .. 根據(jù)數(shù)據(jù)類型匹配
x /v .. 顯示詳細信息
x /a .. 按照地址排序
x /n .. 按照名稱排序
x /z .. 按照大小排序
x *! 列出所有模塊

x ntdll!* 列出 ntdll 模塊

x /t /v ntdll!* 列出 ntdll 模塊數(shù)據(jù)類型和符號類型

.reload
.reload 重新加載符號信息
.reload [/f | /v] /f 強制立即加載符號 /v 顯示詳細信息
.reload [/f | /v] Module Module 為指定模塊加載符號信息
.reload /f @"ntdll.dll"
.reload /f @"C:\WINNT\System32\verifier.dll"
模塊加載命令
lm
lm[ v | l | k | u | f ] [m Pattern] 顯示已加載的模塊
lm 顯示所有加載和未加載的模塊信息

lmv 顯示已加載模塊的詳細信息
lml 同時顯示加載的符號信息
lmk 顯示內(nèi)核模塊信息
lmu 顯示用戶模塊信息
lmf 顯示鏡像路徑
lmm 匹配模塊名稱
lmD 使用 DML 方式顯示

lmv m kernel32 顯示 kernel32 模塊詳細信息

!dlls
!dlls 列出所有加載的模塊和加載數(shù)量
!dlls -i 根據(jù)初始化順序
!dlls -l 根據(jù)加載順序(默認項)
!dlls -m 根據(jù)內(nèi)存順序
!dlls -v 顯示更多詳細信息
!dlls -c ModuleAddr 僅顯示 ModuleAddr 地址的模塊信息
!dlls -? 顯示幫助
!dlls -v -c kernel32 顯示 kernel32.dll 的信息
!lmi
!lmi Module 顯示模塊的詳細信息,包括加載符號信息
!lmi kernel32 顯示 kernel32.dll 模塊的信息

異常分析命令
!analyze
!analyze -v 顯示當(dāng)前異常的詳細信息
!analyze -hang 診斷線程調(diào)用棧上是否有任何線程阻塞了其他線程
!analyze -f 查看異常分析信息,盡管調(diào)試器并未診斷出異常

進程信息命令
!dml_proc
通過 DML 方式顯示當(dāng)前進程的信息

.tlist
顯示當(dāng)前所有進程

線程信息命令
~
~ 顯示線程信息

~* [Command] 所有線程

~. [Command] 當(dāng)前線程

~# [Command] 引發(fā)當(dāng)前事件或異常的線程
~Number [Command] 顯示指定序號的線程
~~[TID] [Command] 顯示指定線程ID的線程
~Ns 切換到線程 N
~* k 顯示所有線程的調(diào)用棧
~2 f 凍結(jié)2號線程
~# f 凍結(jié)引發(fā)異常的線程
~3 u 解除對3號線程的凍結(jié)
~2 k 顯示2號線程的調(diào)用棧

~e
~* e CommandString 在所有線程上執(zhí)行命令
~. e CommandString 在當(dāng)前線程上執(zhí)行命令
~# e CommandString 在引發(fā)異常的線程上執(zhí)行命令
~Number e CommandString 在指定序號的線程上執(zhí)行命令
~2e r; k; kd 相當(dāng)于 ~2r; ~2k; ~2kd
~*e !gle 顯示所有線程的最后一個錯誤信息

~f
~Thread f 凍結(jié)線程
~u
~Thread u 解除凍結(jié)線程
~n
~Thread n 掛起線程,增加線程掛起數(shù)量
~m
~Thread m 恢復(fù)線程,減少線程掛起數(shù)量
!teb
顯示線程環(huán)境信息

!tls
!tls -1 -1 為顯示當(dāng)前線程所有的 slot 信息
!tls SlotIdx 顯示指定的 slot 信息
!tls [-1 | SlotIdx] TebAddr

.ttime
顯示線程時間信息

!runaway
[Flags: 0 | 1 | 2] 顯示每個線程消耗的時間,用于快速的查找 CPU 時間消耗最多的線程
0 用戶態(tài)時間
1 內(nèi)核態(tài)時間
2 自線程創(chuàng)建起的時間間隔

!gle
!gle 顯示當(dāng)前線程的最后錯誤
!gle -all 顯示所有線程的最后錯誤
!error
!error ErrValue 解析錯誤信息
!error ErrValue 1 將錯誤值作為 NTSTATUS 代碼
堆棧信息命令
k
k [n] [f] [L] [#Frames] 顯示調(diào)用棧信息
kn 調(diào)用棧包含幀號
kf 臨近幀的距離
kL 忽略源代碼
kb ... 最開始的 3 參數(shù)
kp ... 所有的參數(shù),包括參數(shù)類型、名稱和值
kP ... 所有的參數(shù)
kv ... FPO信息
kb 5 顯示最開始的 5 個幀

kd
kd [WordCnt] 顯示原始棧數(shù)據(jù)和可能的符號信息
kM
使用 DML 格式顯示堆棧信息
.kframes
設(shè)置棧長度,默認是20(0x14)
.frame
.frame 顯示當(dāng)前幀
.frame # 指定幀號
.frame /r [#] 顯示寄存器信息
.frame 2 顯示幀號 2 的信息
.frame /r 0d 顯示 0 幀中寄存器信息

!uniqstack
!uniqstack 顯示所有線程的棧信息
!uniqstack [b|v|p] [n] b=前3個參數(shù);v=FPO信息;p=所有參數(shù);n=幀號
!uniqstack -? 顯示幫助

!findstack
!findstack Symbol 找到包含符號或模塊的棧
!findstack Symbol [0|1|2] 0=僅顯示線程ID;1=線程ID和幀;2=全部的線程棧;
!findstack -? 顯示幫助
!findstack clr 2 顯示包含 clr 的所有棧的信息

擴展幫助命令
!Ext.help
常規(guī)擴展命令幫助

!Exts.help

!Uext.help
用戶態(tài)模式擴展命令幫助

!Ntsdexts.help
用戶態(tài)擴展命令幫助(OS相關(guān))

!logexts.help
日志相關(guān)擴展

!clr10\sos.help
調(diào)試托管代碼
!wow64exts.help
wow64調(diào)試器擴展
!Wdfkd.help
內(nèi)核態(tài)驅(qū)動框架擴展
!Gdikdx.help
圖形驅(qū)動擴展
!NAME.help
顯示任何 NAME 名稱的擴展命令的幫助
日志擴展命令
!logexts.help
顯示所有日志擴展命令
!loge
!loge [dir] 打開日志功能,可選配置輸出目錄
!logi
初始化日志功能
!logd
關(guān)閉日志功能
!logo
!logo 列出日志配置信息
!logo [e|d] [d|t|v] 打開或關(guān)閉日志,d=調(diào)試器,t=文本文件,v=詳細信息
!logc
!logc 列出所有日志類型
!logc p # 列出 # 中的日志類型
!logc [e|d] * 打開或關(guān)閉所有日志類型
!logc [e|d] # [#] [#] 打開或關(guān)閉日志類型 #
!logb
!logb p 打印緩沖區(qū)信息至調(diào)試器
!logb f 刷新緩沖區(qū)內(nèi)容之日志文件
!logm
!logm 顯示模塊的包含或屏蔽列表
!logm [i|x] [DLL] [DLL] 指定模塊的包含或屏蔽列表
【使用教程】
接下來我會 step by step 解說 Symbol 的設(shè)定方法
首先這里假設(shè)你已經(jīng)把 WinDBG 安裝好了
一. 啟動 WinDBG 後, 你會在下面命令列看到 Debuggee not connected
好~, 開始建立連結(jié) [File] -> [Kernel Debug] , 之後會出現(xiàn)對話盒
對話盒里面有個 Tab Control, 點選 Local 頁簽, 然後按 [確定]
假如你是第一次啟動, 可能會出現(xiàn)一個對話盒, 會問你要不要儲存 workspace,
按 [Yes], 這樣就完成建立了一個 Debuggee 的連結(jié)
這時你可以輸入 version, 看一下系統(tǒng)的相關(guān)資訊和 Debugger 的版本
二. 接下來要搞定 SymBol 設(shè)定, 這部分很重要, 你一定要了解
從 [File] -> [Symbol File Path], 或者按 Ctrl + S,
之後會出現(xiàn)一個以 Symbol Search Path 為 Title 的對話盒, 開始設(shè)定 SymBol 路徑
輸入 C:\Windows\Symbols;SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols
然後按 [確定]
我先解說這個輸入的用意, 它分成兩部分
一個是 C:\Windows\Symbols
另一個是 SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols
兩個以分號 ";" 隔開的
其用意就是告訴 WinDBG 如果你在 C:\Windows\Symbols 這個目錄下找不到 Symbol,
那麼就到 http://msdl.microsoft.com/download/symbols 這網(wǎng)址去找,
并且把找到的 Symbol File 下載到 C:\Windows\Symbols 目錄底下 (SRV*C:\Windows\Symbols*)
這樣就完成了 Symbol File Path 的設(shè)定了
有時候會有很多其它狀況, 例如 WinDBG 會說找不到呀,
解決方法就是 reload (Reload Module)
在 Symbol File Path 的設(shè)定對話盒下面有個 reload 的 CheckBox,
把它打勾, 然後按 [確定], 讓它自動重新載入
另外, 你也可以使用內(nèi)建指令 .reload , 快速的 Reload Module
三. 教你如何一次性的完整下載所有 Symbol Files
平常我們都只是在查看 Ntdll 的函數(shù), 或者查看 Service Descriptor Table
這樣 WinDBG 只會下載 ntdll.pdb 和 ntkrnlmp.pdb 或者 win32k.pdb 到 C:\Windows\Symbol
但其它的呢, 萬一哪天要用到而 Micro$oft 又停止支援怎辦, 嗯~把它一次通通下載到 C:\Windows\Symbol 好了
啟動 DOS Command Line, 也就是 cmd.exe
[開始] -> [執(zhí)行] -> 輸入 cmd -> 按 [確定] , 會出現(xiàn) DOS 的 Command Line 視窗
先跳進 WinDBG 安裝目錄
在 DOS 視窗輸入 cd C:\Program Files\Debugging Tools for Windows (x86), 按 [Enter]
然後再輸入
symchk.exe /r C:\Windows\system32 /s SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols
按 [Enter] 後它就開始自動掃描和下載 C:\Windows\system32 目錄下的檔案的 Symbol File 到 C:\Windows\Symbols
當(dāng)然你也可以掃描和下載其他目錄下系統(tǒng)檔案的 Symbol Files
例如掃描 .Net 的檔案, 在 DOS 的Command Line 視窗輸入
symchk.exe /r C:\WINDOWS\Microsoft.NET\Framework /s SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols
但不建議放在同一個目錄, 建議改放到 C:\Windows\NetSymbols
指令就變成
symchk.exe /r C:\WINDOWS\Microsoft.NET\Framework /s SRV*C:\Windows\NetSymbols*http://msdl.microsoft.com/download/symbols
WinDBG使用方法入門
首先在本頁下載該軟件并且安裝
安裝成功后,可以我開始菜單,程序中找到并啟動Windbg。

啟動后主界面如圖。

我們可以選擇文件(File)菜單》附加到一個進程。

在打開的列表中選擇你要調(diào)試的進程。

有的進程可能權(quán)限比較高,無法調(diào)試。

我們使用管理員身份運行Windbg。

再選擇進程,附加進程。

還是報錯,這說明此程序有自我保護機制,無法進行調(diào)試。

如果程序沒有自我保護,附加后會顯示如圖所示。






































