自定義VS程式異常處理及除錯Dump檔案(一)
阿新 • • 發佈:2019-01-10
1. Dump檔案
1. Dump檔案介紹
Dump檔案(Dump File),也叫轉儲檔案,以.DMP為檔案字尾。dump檔案是程序在記憶體中的映象檔案,通過轉換然後儲存成以.DMP字尾的檔案。dump檔案根據儲存時的選項不同,會生成不同大小的檔案,其中記錄資訊也自然有所不同。
2. Dump檔案分類
程式分兩種,核心模式程式和使用者模式程式,也即Ring0程式和Ring3程式。Dump檔案是伴隨著程式而生成的,所以Dump檔案也同樣分兩種。
1. Kernel-Mode Dump Files(核心模式Dump檔案),主要是驅動程式,此文不涉及。
2. User-Mode Dump Files(使用者模式Dump檔案),主要是應用程式及服務程式,此文所講。
使用者模式Dump檔案又分Full User-Mode Dumps和Minidumps。前者生成的是完整的記憶體快照,所以檔案比較大。後者依然生成選項,生成包含不同資訊的Dump檔案。此文以Minidumps檔案來分析除錯。
3. Dump檔案生成方式
- 通過WinDbg工具的命令
用WinDbg來Attach崩潰提示視窗的process,然後輸入.dump /m C:\myapp.dmp
命令,即可生成預設的miniDump檔案(只包含系統資訊、載入的模組(DLL)資訊、 程序資訊和執行緒資訊)。 - 通過Windows工作管理員,選擇指定程序,右鍵生成轉儲檔案(此時的轉儲檔案即為Full User-Mode Dumps,包含所有資訊,所以檔案比較大)。
- 通過程式碼在程式崩潰時生成Dump檔案。
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib" )
// 此函式需要包含上面標頭檔案和引入相應的庫
LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* _pExcp)
{
HANDLE hFile = CreateFile(
"d:\\Format.dmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
return EXCEPTION_CONTINUE_EXECUTION;
}
MINIDUMP_EXCEPTION_INFORMATION einfo = {0};
einfo.ThreadId = ::GetCurrentThreadId();
einfo.ExceptionPointers = _pExcp;
einfo.ClientPointers = FALSE;
MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal, // 指定生成預設的Minidump檔案
&einfo,
NULL,
NULL);
CloseHandle(hFile);
return EXCEPTION_EXECUTE_HANDLER;
}
// 下面函式放在當前模組的入口函式處,指定ExceptionFilter替換原生的異常處理
// 即當原本要彈出崩潰提示視窗前,需要經過此函式處理,可以處理完立即退出,也可以繼續
SetUnhandledExceptionFilter(ExceptionFilter);
2. 分析Dump檔案
1. 使用Visual Studio
- 選擇與生成Dump檔案相同版本的VS。
- 啟動VS並開啟Dump檔案。
- 必須保證生成Dump檔案的程式的PDB檔案和原始碼相一致。
- VS2005開啟Dump檔案時,直接按F5除錯,程式碼會停在出錯的地方,通過Call Stack視窗檢視。
- VS2010開啟Dump檔案時,
需要通過Set symbol paths
設定符號檔案路徑,也即PDB檔案路徑。然後點選Debug with Native Only
,程式碼即會暫時在出錯的地方,通過Call Stack視窗檢視相關資訊。
2. 使用WinDbg
- 選擇相應版本的WinDbg,x86還是AMD64(也即X64,因為64桌面架構系統是AMD最新發布)。
- File->Open Crush Dump,開啟指定的Dump檔案。
- File->Symbol File Path,新增
srv*D:\Symbols*http://msdl.microsoft.com/download/symbols
- File->Symbol File Path,新增程式的PDB資料夾路徑。這樣可以除錯系統DLL,也可以除錯自有程式。
- 然後在WinDbg命令列中輸入
!analyze -v
,等待WinDbg分析完畢。 - 通過上圖,即可以看到程式碼崩潰的行數。
3. 自定義崩潰視窗
- 通常Windows會提供一個預設的崩潰提示視窗,或者是程式直接閃退。
- 重寫
ExceptionFilter
函式,即可以重新定義崩潰視窗,用以提示使用者傳送相關資訊給軟體提供商。
- 示例程式碼
示例程式碼是Win32型別的DLL,匯出介面SetCustomUnhandledExceptionFilter
在Solution的啟動Project的最開始呼叫一次即可。
下載