當windows程序出現異常、界面卡頓、無響應情況時,在有工程和源碼的情況下,程序員通常是打開IDE,在DEBUG模式下進行調試。但如果是一個RELEASE程序,且無調試環境,該如何來定位呢。
這里介紹一下通過adplus導出dump文件,用windbg來查看的方法。
windbg
在這之前,先大概了解一下windbg。簡單來說windbg就是Windows下對用戶態/內核態的程序進行調試、分析的工具。不僅提供了圖形界面操作,還有着着強大的調試命令。
adplus是一個Microsoft Product Support Services (PSS) 的工具,可以用來排查任何進程或者應用程序的停止響應(hang),或者崩潰(crash)的錯誤。
windbg和adplus 都隨 Microsoft Debugging Tools for Windows 一起提供。
下載地址: https://developer.microsoft.com/zh-cn/windows/downloads/windows-10-sdk/
安裝的時候可以選擇需要的功能,不用全都裝,不然會比較大。
一個例子
下面通過一個例子來看一下吧。
先模擬一個有問題的界面程序。這里用VC創建一個MFC對話框程序,添加了一按鈕,點擊按鈕會進入死循環。
void CtestDlg::OnBnClickedButtonLoop() { while (true) {} }
點擊“死循環”按鈕,程序出現無響應的情況。
這個時候需要用到adplus了。如果winsdk正常安裝的話,windbg 和 adplus 會存放在“C:\Program Files (x86)\Windows Kits\10\Debuggers\x86”路徑下。
adplus 具有兩種操作模式:
- “Hang”模式用於解決進程掛起、100% CPU 使用率以及不涉及崩潰的其他問題。
- “Crash”模式用於解決崩潰問題,或者用於解決導致程序或服務意外退出的任何其他類型的錯誤。
adplus 的具體使用就不做介紹了,這里僅用到 Hang 模式,用來抓取程序的快照,導出dump文件。
adplus -hang -pn test.exe -quiet -o e:\dumps
在控制台執行上述命令,執行成功的話會有類似如下打印,並在“e:\dumps”目錄下生成dump文件。
接下來,打開windbg,點擊“File”->“Open Crash Dump...”,選擇剛才導出的dump文件。
然后在windbg下方的命令行輸入kb,windbg會打印出當前進程的調用棧。
一般來說,通過查看進程的調用棧,就能大概知道程序出錯的地方了。
如果無法顯示符號名稱,請點擊“File”->“Symbol File Path...”來設置pdb文件的路徑。
windbg的其它命令:
~ 簡潔地顯示當前進程的所有線程,
~* 表示所有線程
~0kp 顯示第一個線程棧
~*kp 顯示所有線程棧