[除錯]_[初級]_[Windbg使用教程-2]
場景
1.我們開發C++程式時, 釋出給客戶用的是Release模式, 並新增崩潰報告,在程式崩潰退出時,可以通過使用WinDbg來除錯崩潰產生的dmp檔案.
2.我們也可以用來除錯程式, 加斷點, 看區域性變數,只是這裡主要還是講除錯dmp的.
說明
1.Windbg並不是系統標配的, 需要通過SDK下載安裝. Debugging Tools for Windows . WinDbg, 一個獨立的圖形Debug工具, 可以除錯使用者模式和核心模式. 相當於vs的偵錯程式獨立版本,或者說是linux裡的gdb. 如果配合Windows SDK的C++編譯工具, 甚至不需要VS都可以用SDK自帶的編譯工具和WinDbg開發程式.
2.獲取Windows dll pdb檔案可以通過兩種方式:
– 方式1: 啟動windbg後,在[Symbol Search Path] 對話方塊中加入下面的路徑:
srv*D:\SystemSymbols*http://msdl.microsoft.com/download/symbols
這種方式就是在除錯過程中,windbg偵錯程式會從符號表伺服器自動下載除錯所需的PDB檔案.
– 方式2: 預先下載PDB檔案,這樣能減少除錯的等待時間.
"C:\Program Files\Debugging Tools for Windows (x86)\symchk.exe"
c:\windows \system32\user32.dll /s
SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols //下載user32.dll的pdb到
c:\symbols目錄中
"C:\Program Files\Debugging Tools for Windows (x86)\symchk.exe" c:\windows\system32\ /s
SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols //下載system32下所有dll的pdb到
c:\symbols目錄中
"C:\Program Files\Debugging Tools for Windows (x86)\symchk.exe" /r c:\windows\system32\
/s SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols //遞迴子目錄下載system32下
所有dll的pdb到c:\symbols目錄中
3.設定 _NT_SYMBOL_PATH
環境變數, 值就是pdb的放置目錄. 這樣vs和windbg可以通過這個配置變數查詢系統的PDB檔案.
4.Debugging工具目錄還有其他輔助debug工具, 可以參考自帶的chm官方檔案看使用說明.
C:\Program Files\Debugging Tools for Windows (x64)
比如使用 ntsd.exe 來結束頑固的程序. ntsd -c q -p 6948
A user-mode debugger with a console interface. CDB and NTSD are virtually identical.
In this documentation, whenever a reference is made to "CDB",
it applies to both CDB and NTSD. When these two debuggers differ,
it is noted. (See CDB and NTSD for details.)
例子
分析一個dmp檔案, 把dmp檔案拖放到windbg窗口裡. 接著設定 File->Symbol File Path…設定當前程式的PDB檔案所在的目錄. 之後勾選 reload, 確認.
1.在命令視窗輸入 .ecxr 回車, 這個命令顯示當前異常所在的上下文記錄,還有當前上下文的暫存器的值. 之後WinDbg會把異常上下文當成暫存器上下文. 並且這時可以查詢很多資料, 比如堆疊資訊, 本地變數值.
當前異常的上下文記錄, mov dl,byte ptr [ecx]
這個就是造成崩潰的原因:
0:007> .ecxr
eax=00000000 ebx=0941f6c4 ecx=00000000 edx=00000000 esi=00000001 edi=0941f524
eip=6785bd90 esp=0941f404 ebp=0941f474 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
libComm!FilePacketUtil::ConvertJsonToFileHeader+0x80:
6785bd90 8a11 mov dl,byte ptr [ecx] ds:002b:00000000=??
檢視異常的呼叫棧
0:007> kn
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
00 0941f474 678a60d9 libComm!FilePacketUtil::ConvertJsonToFileHeader+0x80 [d:\software\47.android\projects\gui\libcomm\src\common\file\file_packet_util.cpp @ 54]
01 0941f7a4 67886cfd libComm!ModuleFile::RecvTaskFileExport+0x999 [d:\software\47.android\projects\gui\libcomm\src\module\module_file.cpp @ 133]
02 0941fbb8 68e64697 libComm!RecvServerPacket+0x132d [d:\software\47.android\projects\gui\libcomm\src\libcomm.cpp @ 712]
檢視第0幀,通過kn反饋的的最左邊的數值表明了幀數.
0:007> .frame 0
00 0941f474 678a60d9 libComm!FilePacketUtil::ConvertJsonToFileHeader+0x80 [d:\software\47.android\projects\gui\libcomm\src\common\file\file_packet_util.cpp @ 54]
檢視本地變數, 這裡顯示有些錯誤,比如 fh是引用, 怎麼可能是0?所以也搞不懂.
0:007> dv /v
Unable to find processor type for C:\Program Files (x86)\Android\Plugins\Comm\libComm.dll, using default
@ecx fh = 0x00000000
@edx value = 0x00000000
0941f444 fbs = 0x0941f6c4
0941f414 fb = class FileBlock
其他:
1.選單 Help->Contents 可以開啟官方的 chm格式文件幫助查閱文件.
2.選單 View->Locals 或者 Registers 或者 Call stack也是視覺化的查閱方式,也相當方便.
3.如何生成崩潰報告, 轉到這裡 Release程式的崩潰報告minidump解決方案
參考
Windbg的官方文件 Debugging tools for Windows
術語
ChildEBP: the base pointer for the stack frame
RetAddr: return address
Callee-BSP: a pointer to the function
Return-RA: return address
Addrs displays various frame-related addresses. On an x86-based processor,
this display includes the base pointer for the stack frame ("ChildEBP") and
the return address ("RetAddr"). On an Itanium-based processor,
this display includes a pointer to the function that is being called ("Callee-BSP") and
the return address ("Return-RA"), unless both the Args and
Nonvolatile regs buttons are turned on as well.