// 創建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);
}
從上面的代碼中可以看出,要想創建Dump文件,必須得到一個指向EXCEPTION_POINTERS結構的指針。怎麼在try/except塊中得到這個指針呢?這個時候就需要用到Windows API中的GetExceptionInformation()。這個函數的返回值就是一個指向EXCEPTION_POINTERS結構的指針。下面是具體的代碼。
// 作爲except塊中表達式的函數
//
LONG CrashHandler(EXCEPTION_POINTERS *pException)
{
// 在這裏添加處理程序崩潰情況的代碼
//
// 這裏以彈出一個對話框爲例子
//
MessageBox(NULL, _T("Message from Catch handler"), _T("Test"), MB_OK);
// 創建Dump文件
//
CreateDumpFile(_T("C:\\Test.dmp"), pException);
return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
__try
{
MessageBox(NULL, _T("Message from '__try' section"), _T("Test"), MB_OK);
// 除零,人爲的使程序崩潰
//
int i = 13;
int j = 0;
int m = i / j;
}
// 捕捉到讓程序崩潰的異常時創建Dump文件
//
__except(CrashHandler(GetExceptionInformation()))
{
// 這裏以彈出一個對話框爲例子
//
MessageBox(NULL, _T("Message from '__except' section"), _T("Test"), MB_OK);
}
MessageBox(NULL, _T("Funcation completed"), _T("Test"), MB_OK);
return 0;
}
編譯上面的代碼並運行,會依次彈出下面這些對話框,並在C盤創建一個Dump文件Test.dmp。
有了Dump文件,就可以輕鬆定位使程序崩潰的那行代碼,具體方法可參考我的《讓程序在崩潰時體面的退出之Dump文件》。