1. 程式人生 > >自定義VS程式異常處理及除錯Dump檔案(一)

自定義VS程式異常處理及除錯Dump檔案(一)

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檔案生成方式

  1. 通過WinDbg工具的命令
    用WinDbg來Attach崩潰提示視窗的process,然後輸入.dump /m C:\myapp.dmp命令,即可生成預設的miniDump檔案(只包含系統資訊、載入的模組(DLL)資訊、 程序資訊和執行緒資訊)。
  2. 通過Windows工作管理員,選擇指定程序,右鍵生成轉儲檔案(此時的轉儲檔案即為Full User-Mode Dumps,包含所有資訊,所以檔案比較大)。
  3. 通過程式碼在程式崩潰時生成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檔案時,
    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分析完畢。
  • WinDbg
  • 通過上圖,即可以看到程式碼崩潰的行數。

3. 自定義崩潰視窗

  1. 通常Windows會提供一個預設的崩潰提示視窗,或者是程式直接閃退。
    此處輸入圖片的描述
  2. 重寫ExceptionFilter函式,即可以重新定義崩潰視窗,用以提示使用者傳送相關資訊給軟體提供商。
    此處輸入圖片的描述
  3. 示例程式碼
    示例程式碼是Win32型別的DLL,匯出介面SetCustomUnhandledExceptionFilter在Solution的啟動Project的最開始呼叫一次即可。
    下載