在個人那篇《讓程序在崩潰時體面的退出之CallStack》中提供了一個在程序崩潰時獲得CallStack的方法。但是要想獲得CallStack,必須有pdb文件的支持。可是通常狀況下,發佈出去的程序都是Release版本的,都不會附帶pdb文件。那麼咱們怎麼能在程序崩潰的時候找到出錯的具體位置呢?這個時候就該Dump文件出場了!Dump文件是進程的內存鏡像,能夠把程序運行時的狀態完整的保存下來。
要想在程序崩潰的時候建立Dump文件,就須要用到DbgHelp.dll中Windows API的MiniDumpWriteDump()函數。該函數聲明以下:函數
BOOL WINAPI MiniDumpWriteDump( __in HANDLE hProcess, __in DWORD ProcessId, __in HANDLE hFile, __in MINIDUMP_TYPE DumpType, __in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, __in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, __in PMINIDUMP_CALLBACK_INFORMATION CallbackParam );
具體的參數和返回值的解釋能夠查找MSDN,有很詳細的說明。下面依然用上一篇文章中的例子代碼來講明怎麼在程序崩潰的時候建立Dump文件。.net
// 處理Unhandled Exception的回調函數 // LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException) { // 這裏彈出一個錯誤對話框並退出程序 // FatalAppExit(-1, _T("*** Unhandled Exception! ***")); return EXCEPTION_EXECUTE_HANDLER; } // 一個有函數調用的類 // class CrashTest { public: void Test() { Crash(); } private: void Crash() { // 除零,人爲的使程序崩潰 // int i = 13; int j = 0; int m = i / j; } }; int _tmain(int argc, _TCHAR* argv[]) { // 設置處理Unhandled Exception的回調函數 // SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler); CrashTest test; test.Test(); return 0; }
在上面的程序崩潰的時候,會調用函數ApplicationCrashHandler()。建立Dump文件的代碼就須要添加到該函數中。下面就是一個建立Dump文件的函數。調試
// 建立Dump文件 // void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException) { // 建立Dump文件 // 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); }
在函數ApplicationCrashHandler()用相似下面的代碼來調用上面的函數,就能夠在程序崩潰的時候建立Dump文件。code
CreateDumpFile(_T("C:\\Test.dmp"), pException);
下面簡單說一下Dump文件的用法。將Dump文件拷貝到含有應用程序和對應的pdb文件的目錄,在VS裏面打開Dump文件(或者直接雙擊Dump文件),VS會自動建立一個Solution,直接調試運行,代碼就會停到使程序崩潰的那一行上。就跟在VS裏面調試代碼一摸同樣。(VS2008)orm
在VS2010裏打開Dump文件,會顯示一個Minidump File Summary,而且能夠進行下面圖中的操做。blog