程序崩溃时生成Dump文件

来源:互联网 发布:深圳云计算工程师招聘 编辑:程序博客网 时间:2024/06/02 10:46

Dump文件是进程的内存镜像,可以把程序运行时的状态完整的保存下来,之后通过调试工具可查出崩溃大致原因。

  • SetUnhandledExceptionFilter()设置一个在程序崩溃时被调用的回调函数。
  • MiniDumpWriteDump()创建Dump文件。
我写了一个CDumpFile类,程序崩溃时会生成“文件名_版本号 日期_时间.dmp”文件,在App里创建并调用它的Initialize()函数即可。

【DumpFile.h】

#pragma once#include <Dbghelp.h>  #pragma comment(lib, "Dbghelp.lib")  class CDumpFile{public:CDumpFile();~CDumpFile();private:static LONG WINAPI UnhandledExceptionFilterEx(EXCEPTION_POINTERS* pException);static void CreateDumpFile(LPCTSTR lpstrDumpFilePathName, EXCEPTION_POINTERS* pException);public:void Initialize(CString strFileDir = L""); // strFileDir为崩溃文件保存目录,默认为模块所在目录};

【DumpFile.cpp】

#include "stdafx.h"#include "DumpFile.h"CDumpFile::CDumpFile(){}CDumpFile::~CDumpFile(){}static WCHAR g_szDumpFileDir[MAX_PATH] = { 0 };CString GetFileVersion(const CString& strFilePath){CString strAppVersion;DWORD u32RessourceVersionInfoSize;DWORD u32JustAJunkVariabel;char* ps8VersionInfoPtr;struct LANGANDCODEPAGE {WORD wLanguage;WORD wCodePage;} *pstTranslationPtr(nullptr);wchar_t* ps16InformationPtr;UINT  u32VersionInfoSize;wchar_t  as16VersionValue[255];u32RessourceVersionInfoSize = GetFileVersionInfoSize(strFilePath, &u32JustAJunkVariabel);if (0 != u32RessourceVersionInfoSize){ps8VersionInfoPtr = new char[u32RessourceVersionInfoSize];if (GetFileVersionInfo(strFilePath, 0, u32RessourceVersionInfoSize, ps8VersionInfoPtr)){if (!VerQueryValue(ps8VersionInfoPtr,TEXT("VarFileInfo\\Translation"),(LPVOID*)&pstTranslationPtr,&u32VersionInfoSize)){delete[] ps8VersionInfoPtr;return strAppVersion;}}wsprintf(as16VersionValue,L"\\StringFileInfo\\%04x%04x\\FileVersion",pstTranslationPtr[0].wLanguage,pstTranslationPtr[0].wCodePage);if (!VerQueryValue(ps8VersionInfoPtr,as16VersionValue,(LPVOID*)&ps16InformationPtr,&u32VersionInfoSize)){delete[] ps8VersionInfoPtr;return strAppVersion;}if (wcslen(ps16InformationPtr) > 0){strAppVersion = CString(ps16InformationPtr);}delete[] ps8VersionInfoPtr;}return strAppVersion;}void CDumpFile::Initialize(CString strFileDir){wcsncpy_s(g_szDumpFileDir, strFileDir, strFileDir.GetLength());SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);}LONG WINAPI CDumpFile::UnhandledExceptionFilterEx(EXCEPTION_POINTERS* pException){WCHAR szModuleFilePath[MAX_PATH] = { 0 };GetModuleFileName(NULL, szModuleFilePath, MAX_PATH);CString strFileVersion = GetFileVersion(szModuleFilePath);WCHAR* pszModualFilename = PathFindFileName(szModuleFilePath);CString strFileName = CString(pszModualFilename) + L"_" + strFileVersion + CTime::GetCurrentTime().Format(" %Y-%m-%d %H_%M_%S") + L".dmp";if (wcslen(g_szDumpFileDir) == 0){/* 保存在模块所在目录 */GetModuleFileName(NULL, g_szDumpFileDir, MAX_PATH);PathRemoveFileSpec(g_szDumpFileDir);}WCHAR szDumpFilePath[MAX_PATH] = { 0 };PathAppend(szDumpFilePath, g_szDumpFileDir);if (!PathIsDirectory(szDumpFilePath)){SHCreateDirectoryEx(NULL, szDumpFilePath, nullptr);}PathAppend(szDumpFilePath, strFileName);CreateDumpFile(szDumpFilePath, pException);// 崩溃时弹框  FatalAppExit(-1, _T("提示信息:软件崩溃,请重启。"));return EXCEPTION_CONTINUE_SEARCH;}void CDumpFile::CreateDumpFile(LPCTSTR lpstrDumpFilePathName, EXCEPTION_POINTERS* pException){// 创建Dump文件  HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);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文件》
  • 《让程序在崩溃时体面的退出之Unhandled Exception》

0 0
原创粉丝点击