目的:學習和記錄windbg的一些使用。
版本不是最新的,如果需要最新的可以自己在網上搜尋一下,當然還有很多漢化版的(我個人喜好原版)。
1.1關於配置
這個主要就是symbol的問題了,網上一般都會推薦 設定環境變數例如:我的電腦》右鍵選單》屬性》高階選項卡》環境變數》系統變數》新建
變數名: _nt_symbol_path
變數值:srv*f:\websymbols*
"f:\websymbols"這個路徑可以自己設定。
如果不設定環境變數,那麼每次使用的時候記得去新增symbol路徑就行了,ctrl+s開啟windbg符號設定框(或者是file選單下面選擇symbol file path),開啟之後填入
srv*f:\websymbols*
,勾選reload ,也可以在下面的命令中輸入.reload,
有多個symbol路徑中用";"處理。
2.dump檔案的獲得
一種情況是,如果在測試人員那裡發現崩潰,我們就可以使用windbg去抓取dump檔案 。
可以參照這裡。 我把一些內容貼到這裡來
1).看一下任務管理器,如果崩潰的程序還在就可以抓取。
2).開啟windbg,file--attach to a process,選擇崩潰的程序。
3).使用命令.dump /mf d:\testdemo.dmp 生成dmp檔案
具體的命令細節可以參考其他文件或者是網上搜尋。
第二種情況,如果是在客戶手裡,我們不太可能去安裝乙個windbg去抓取dump檔案,所以我們需要程式能夠自動生成,這個網上也有很多原始碼。
這裡面也有, 也有,挺多的。我這裡新增一下我用的(當然我用的也是網上找的,具體位址忘記了)
注意:**都依賴dbghelp.dll和對應的標頭檔案,這個可以在windbg的安裝路徑下面獲取到,需要把對應的dll檔案和你的執行程式放到一起,否則是不能收集到dmp的。
具體到專案的時候,可以修改下面的**自動把dmp檔案通過網路傳送回來,或者是 有問題了叫使用者把對應的dmp檔案直接傳送給你也可以。
c版本minidmp.h
#pragma once
#include #include #include #include #pragma comment(lib, "dbghelp.lib")
#ifdef unicode
#define tsprintf wsprintf
#else
#define tsprintf sprintf
#endif
// 啟動自動生成dump檔案的話,只需要在main函式開始處
// 呼叫該函式(enableautodump)即可
void enableautodump();
// 其它函式
void createdumpfile(lpcwstr lpstrdumpfilepathname, exception_pointers *pexception);
; tchar szdumpfile[max_path] = ;
tchar szmsg[max_path] = ;
systemtime sttime = ;
// 構建dump檔案路徑
getlocaltime(&sttime);
::getcurrentdirectory(max_path, szdumpdir);
tsprintf(szdumpfile, _t("%s\\%04d%02d%02d_%02d%02d%02d.dmp"), szdumpdir,
sttime.wyear, sttime.wmonth, sttime.wday,
sttime.whour, sttime.wminute, sttime.wsecond);
// 建立dump檔案
createdumpfile(szdumpfile, pexception);
// 這裡彈出乙個錯誤對話方塊並退出程式
tsprintf(szmsg, _t("i'm so sorry, but the program crashed.\r\ndump file : %s"), szdumpfile);
return exception_execute_handler;
} void enableautodump()
inline void createdumpfile(lpcwstr lpstrdumpfilepathname, exception_pointers *pexception)
}
使用的時候在main裡面enableautodump();一般是在其他執行之前呼叫。
c++版本
minidumper.h
/*
*/#ifndef include_minidumper_h_
#define include_minidumper_h_
#ifdef _msc_ver
#include #include #include #pragma comment(lib, "dbghelp.lib")
#include #pragma comment(lib, "user32.lib")
#include #pragma comment(lib, "shlwapi.lib")
namespace dbg
~minidumper() {};
private:
minidumper(const minidumper&);
const minidumper& operator=(const minidumper&);
public:
static minidumper* get()
}string getdumpfile() const
private:
static long winapi toplevelexceptionfilter(struct _exception_pointers* ep)
pfnwritedump minidumpwritedump = (pfnwritedump)::getprocaddress(module, "minidumpwritedump");
if (minidumpwritedump != null)
closehandle(file);
}return ret;
}private:
string m_dumpfilepath;
};} // namespace qp
#endif // _msc_ver
#endif // include_minidumper_h_
呼叫方法 dbg::minidumper::get()->init(); 也可以指定路徑和版本。
3.分析定位崩潰
這個可以參考 裡面的,
我這裡說一下我自己的使用步驟。這裡假設程式為testdemo。
1.把testdemo.dmp檔案 和 testdemo.pdb testdemo.exe放在乙個目錄(d:\test)
2.windbg選擇 file->open crash dump選擇你的dmp檔案
3.設定symbol路徑,ctrl+s 輸入:srv*d:\websymbols*
;d:\test 勾選reload
4.設定原始碼路徑ctrl+p 選擇 testdemo 工程路徑
5.在命令裡面輸入: !analyze –v 經過一段時間的等待就會出現 比較精確的崩潰位置
這裡有個前提就是你的**沒有修改,還有對應的exe和客戶那裡的一樣的pdb未更新。所以我們在做專案的時候發乙個版本需要把對應的**備份或者是svn備註一下,否則你的**不一致就會定位不到。
4.其他說明
借助windbg可以幫助我們定位到崩潰的位置和其他的資訊,但是我們在做專案的時候可能**量大,邏輯複雜,導致即便是定位到了崩潰點和觸發資訊,我們修改也是比較難的情況。這個時候就需要**分析能力和**的架構了,如果你**分析能力強,架構清晰,是比較好修改了,如果**結構混亂,這個時候修改很大情況會導致新的問題,並且修改也很難, 所以 前期的模組劃分,框架很重要。
當然最好是沒有bug或者是沒有不能重現的bug,可以多使用一些現有的成熟的框架,**模組劃分一定要多花時間。
windbg除錯C 程式
windbg的安裝與配置 安裝後就可以在開始選單找到windbg了。要先除錯.net的程式,需要使用乙個擴充套件的dll,它在c windows microsoft.net framework v2.0.50727路徑下,檔名是sos.dll。有了它我們才能執行命令 clrstack 拷貝乙份到wi...
windbg除錯驅動程式
不正確之處歡迎指正,高手勿噴 配置windbg路徑 symbol path srv f windows symbolxp3 source path c users bojay desktop first image path c users bojay desktop first objchk wx...
使用windbg分析dmp查詢程式崩潰問題
include pragma comment lib,dbghelp.lib define dmp file path d mydmp long winapi myunhandledexceptfiltercallback struct exception pointers lpexceptioni...