dump生成與分析
阿新 • • 發佈:2018-12-31
來源:
軟體發生異常,沒有除錯環境,怎麼快速定位問題?遇到這類問題,最有的資訊就是生成dump檔案,然後通過dump檔案檢視callstack等資訊定位。
Dump檔案生成原理:
利用dbghelp使用SetUnhandledExceptionFilter設定回撥函式生成dump檔案,後分析異常地方。
本文實現方式:分裝類在MFC程式中呼叫並分析
1、類的實現
//CreateDump.h #pragma once #include <string> using namespace std; class CCreateDump { public: CCreateDump(); ~CCreateDump(void); static CCreateDump* Instance(); static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo); //宣告Dump檔案,異常時會自動生成。會自動加入.dmp檔名字尾 void DeclarDumpFile(std::string dmpFileName = ""); private: static std::string strDumpFile; static CCreateDump* __instance; };
//CreateDump.cpp #include "stdafx.h" #include "CreateDump.h" #include <DbgHelp.h> #pragma comment(lib, "dbghelp.lib") CCreateDump* CCreateDump::__instance = NULL; std::string CCreateDump::strDumpFile = ""; CCreateDump::CCreateDump() { } CCreateDump::~CCreateDump(void) { } long CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo) { HANDLE hFile = CreateFileA(strDumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL ); if(hFile!=INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = ExceptionInfo; ExInfo.ClientPointers = FALSE; // write the dump BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL ); CloseHandle(hFile); if (!bOK) { DWORD dw = GetLastError(); //寫dump檔案出錯處理,異常交給windows處理 return EXCEPTION_CONTINUE_SEARCH; } else { //在異常處結束 return EXCEPTION_EXECUTE_HANDLER; } } else { return EXCEPTION_CONTINUE_SEARCH; } } void CCreateDump::DeclarDumpFile(std::string dmpFileName) { SYSTEMTIME syt; GetLocalTime(&syt); char c[MAX_PATH]; sprintf_s(c,MAX_PATH,"[%04d-%02d-%02d %02d:%02d:%02d]",syt.wYear,syt.wMonth,syt.wDay,syt.wHour,syt.wMinute,syt.wSecond); strDumpFile = std::string(c); if (!dmpFileName.empty()) { strDumpFile += dmpFileName; } strDumpFile += std::string(".dmp"); SetUnhandledExceptionFilter(UnhandleExceptionFilter); } CCreateDump* CCreateDump::Instance() { if (__instance == NULL) { __instance = new CCreateDump; } return __instance; }
2、呼叫和產生方式
在程式初始化時候呼叫:
CCreateDump::Instance()->DeclarDumpFile("dumpfile");
3、寫出異常程式碼
int a = 9;
int b = 0;
int c = 0;
c = a / b;
執行程式,並執行此處程式碼(執行目錄下生成dump檔案)
4、把dmp檔案和exe, pdb檔案放在同一目錄下,然後用編譯器(如vc)開啟dmp檔案,然後開始除錯就會中斷到剛才異常的地方。