一、 生成Dump文件方式
1.1任務管理器
在程序崩潰後,先不關閉程序,在任務管理器中找到該程序對應的進程。右鍵—>創建轉儲文件。
此時會在默認的目錄下創建出一個dump文件。
可以看出,此種方法只適用於程序崩潰但沒有立即自行退出的情況。倘若程序故障後自行退出,則此方法就難以應用。不過,我們可以在註冊表中添加如下信息已確保系統在程序崩潰後自行保存一個dump文件:
在註冊表中找到
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\WindowsError Reporting\LocalDumps
添加項如下圖:
其中DumpType代表的含義是:
0 = Create a custom dump
1 = Mini dump
2 = Full dump
如此一來,一旦程序崩潰,系統會在C:\CrashDump下生成一個dump文件。
1.2WinDbg抓取
程序運行崩潰後,先不關閉程序,將WinDbg附加到改進程上。
執行命令:.dump –ma Test.dmp ,則會產生一個Test.dmp的轉儲文件。
1.3程序中加入存儲Dump的代碼
通過SetUnhandledExceptionFilter設置捕獲dump的入口,然後通過MiniDumpWriteDump生成dump文件。
如下程序在程序異常時會自行轉儲一個名爲Test.dmp的dump文件。
[cpp] view plain copy
- #include<Windows.h>
- #include<DbgHelp.h>
- #pragma comment(lib,"DbgHelp.lib")
- // 創建Dump文件
- void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
- {
- HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- // Dump信息
- MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
- dumpInfo.ExceptionPointers = pException;
- dumpInfo.ThreadId = GetCurrentThreadId();
- dumpInfo.ClientPointers = TRUE;
- // 寫入Dump文件內容
- MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
- CloseHandle(hDumpFile);
- }
- // 處理Unhandled Exception的回調函數
- LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
- {
- CreateDumpFile(L"Test.dmp",pException);
- return EXCEPTION_EXECUTE_HANDLER;
- }
- void fun(int *p)
- {
- p[0]=0;
- }
- int main(int argc, char * argv[])
- {
- //註冊異常處理函數
- SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
- fun(NULL);
- return 0;
- }
二、調試Dump文件
2.1.VS調試
用VS打開dmp文件。測試時 dmp文件時本地產生的,因此VS會依據dmp文件自行找到exe,pdb和源代碼的路徑。因此直接點擊調試,程序會出錯代碼行中斷。
但若dmp文件是exe在另一臺機器上產生的,則我們最好把exe,pdb,dmp放到同一文件夾下,必須保證pdb與出問題的exe是同一時間生成的,用VS打開dmp文件後還需要設置符號表文件路徑和源代碼路徑:
(1) 當把pdb文件與dmp文件放入同一目錄下時,就不需設置其路徑,否則需要設置
工具->選項->調試->符號:
(2)還需設置源代碼路徑:
屬性->調試源代碼:
這樣點擊“使用僅限本機進行調試”,即可在出錯代碼行中斷:
2.2 WinDbg調試
(1)設置pdb路徑:File ->Symbol File Path
(2)設置exe路徑:File -> Image File Path
(3)設置源代碼路徑:File -> Source File Path(指sln所在目錄)
(4)打開dmp文件:File ->Open Crash Dump
(5)執行命令 !analyze –v
由分析結果可以看出,在main.cpp第7行出錯,錯誤類型:NULL_POINTER_WRITE.