MiniDumpWriteDump是MS DbgHelp.dll 中一個API, 用于導出目前運作的程式的Dump. 這個dll程式系統中就有, 但是很多軟體, 都在自己的安裝目錄下儲存了這個.dll的最新的版本.
目的是當有異常發生的時候, 自動生成Dump檔案供之後的分析. 有了Dump檔案, 我們就可以使用WinDBG等調試器來分析異常發生時的情況. 其實這個功能很多軟體都有, 比如QQ, 魔獸世界, 等等. 它們在出現了異常的時候會彈出一個對話框, 讓使用者輸入異常發生時的情況, 然後把異常的dump檔案用email發回, 供開發者們分析修改bug.
不過有一點, 這裡需要程式的調試符号檔案(pdb檔案). 對于Debug版來說, 是生成的, 但是Release版來說預設是不生成的. 可以設定VC的編譯器, 讓它在Release版的時候也生成調試資訊. 這帶來一個新的問題, 因為.pdb裡面是儲存了源檔案的資訊的, 為了避免洩密, 可以采用VS中的CVPack工具, 從中去除敏感的資訊.
程式需要使用Dbghelp.h 和 Dbghelp.lib . 它們可以從MSDN找到.
Code:
#include <dbghelp.h>
#pragma comment(lib,"Dbghelp.lib")
LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
m_previousFilter = SetUnhandledExceptionFilter(MSJUnhandledExceptionFilter);
LONG WINAPI MSJUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
CreateMiniDump(pExceptionInfo);
return EXCEPTION_CONTINUE_SEARCH;
}
void CreateMiniDump(struct _EXCEPTION_POINTERS* ExceptionInfo)
char szFile[MAX_PATH+1] = {0};
_snprintf(szFile, MAX_PATH, ".//cc_%u.dmp", time(NULL));
HANDLE hFile = CreateFile(szFile, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if( INVALID_HANDLE_VALUE == hFile )
return;
MINIDUMP_EXCEPTION_INFORMATION mei;
mei.ThreadId = GetCurrentThreadId();
mei.ClientPointers = TRUE;
mei.ExceptionPointers = ExceptionInfo;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithFullMemory, &mei, NULL, NULL);
CloseHandle(hFile);