封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。

Posted 沙漠中的雨滴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。相关的知识,希望对你有一定的参考价值。

#pragma once

#include <windows.h>
#include <dbghelp.h>

#pragma comment(lib, "dbghelp.lib") 

typedef void(__stdcall *PF_CallBack)(const char* msg);


class MiniDump 
{
private:
    static      PF_CallBack     m_pFun;
    static      char            m_szProcessName[32];

public:
    MiniDump(){};
    ~MiniDump(){};

    static void TcharToChar(TCHAR * tchar, char * _char);
    static void CharToTchar(const char * _char, TCHAR * tchar);
    static const char * GenerateDumpFilePath();

    static void EnableAutoMinDump(const char* pProcessName, PF_CallBack pFunc, bool bEnable = true);
    static LONG ApplicationUnhandledExceptionFilter(EXCEPTION_POINTERS *pException);
    static void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException);

};

PF_CallBack MiniDump::m_pFun = NULL;
char        MiniDump::m_szProcessName[32] = "test";

void MiniDump::EnableAutoMinDump(const char* pProcessName, PF_CallBack pFunc, bool bEnable)
{
    if (bEnable) {
        m_pFun = pFunc;
        memset(m_szProcessName, 0, sizeof(m_szProcessName));
        memcpy(m_szProcessName, pProcessName, strlen(pProcessName) + 1);
        SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationUnhandledExceptionFilter);
    }
}

LONG MiniDump::ApplicationUnhandledExceptionFilter(EXCEPTION_POINTERS *pException)
{
    TCHAR szDumpFile[MAX_PATH] = { 0 };
    CharToTchar(GenerateDumpFilePath(), szDumpFile);
    CreateDumpFile(szDumpFile, pException);

    if (m_pFun != NULL) {
        char szMsg[2048] = { 0 };
        m_pFun(szMsg);
    }

    return EXCEPTION_EXECUTE_HANDLER;
}

void MiniDump::CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
    // 创建Dump文件;
    HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    // Dump信息;
    if (hDumpFile != NULL && hDumpFile != INVALID_HANDLE_VALUE) {
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;

        // 写入Dump文件内容;
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
        CloseHandle(hDumpFile);
    }
}

void MiniDump::TcharToChar(TCHAR * tchar, char * _char)
{
    int iLength = 0;
    iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
}

void MiniDump::CharToTchar(const char * _char, TCHAR * tchar)
{
    int iLength;
    iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
    MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
}

const char * MiniDump::GenerateDumpFilePath()
{
    //路径
    TCHAR szDumpDirT[MAX_PATH] = { 0 };
    GetCurrentDirectory(MAX_PATH, szDumpDirT);
    char szDumpDir[MAX_PATH] = { 0 };
    TcharToChar(szDumpDirT, szDumpDir);

    //时间
    SYSTEMTIME stTime;
    GetLocalTime(&stTime);
    char szCurtTime[64] = { 0 };
    sprintf_s(szCurtTime, sizeof(szCurtTime) / sizeof(char), "%04d-%02d-%02d-%02d-%02d-%02d", stTime.wYear, stTime.wMonth, stTime.wDay, stTime.wHour, stTime.wMinute, stTime.wSecond);

    //dump文件路径
    char szDumpFile[MAX_PATH] = { 0 };
    sprintf_s(szDumpFile, sizeof(szDumpFile) / sizeof(char), "%s\\%s_%s.dmp", szDumpDir, m_szProcessName, szCurtTime);

    return szDumpFile;
}

  

#pragma once
#include <windows.h>#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib") 
typedef void(__stdcall *PF_CallBack)(const char* msg);

class MiniDump {private:    static      PF_CallBack     m_pFun;    static      char            m_szProcessName[32];
public:    MiniDump(){};    ~MiniDump(){};
    static void TcharToChar(TCHAR * tchar, char * _char);    static void CharToTchar(const char * _char, TCHAR * tchar);    static const char * GenerateDumpFilePath();
    static void EnableAutoMinDump(const char* pProcessName, PF_CallBack pFunc, bool bEnable = true);    static LONG ApplicationUnhandledExceptionFilter(EXCEPTION_POINTERS *pException);    static void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException);
};
PF_CallBack MiniDump::m_pFun = NULL;char        MiniDump::m_szProcessName[32] = "test";
void MiniDump::EnableAutoMinDump(const char* pProcessName, PF_CallBack pFunc, bool bEnable){    if (bEnable) {        m_pFun = pFunc;        memset(m_szProcessName, 0, sizeof(m_szProcessName));        memcpy(m_szProcessName, pProcessName, strlen(pProcessName) + 1);        SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationUnhandledExceptionFilter);    }}
LONG MiniDump::ApplicationUnhandledExceptionFilter(EXCEPTION_POINTERS *pException){    TCHAR szDumpFile[MAX_PATH] = { 0 };    CharToTchar(GenerateDumpFilePath(), szDumpFile);    CreateDumpFile(szDumpFile, pException);
    if (m_pFun != NULL) {        char szMsg[2048] = { 0 };        m_pFun(szMsg);    }
    return EXCEPTION_EXECUTE_HANDLER;}
void MiniDump::CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException){    // 创建Dump文件;    HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);    // Dump信息;    if (hDumpFile != NULL && hDumpFile != INVALID_HANDLE_VALUE) {        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;        dumpInfo.ExceptionPointers = pException;        dumpInfo.ThreadId = GetCurrentThreadId();        dumpInfo.ClientPointers = TRUE;
        // 写入Dump文件内容;        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);        CloseHandle(hDumpFile);    }}
void MiniDump::TcharToChar(TCHAR * tchar, char * _char){    int iLength = 0;    iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);    WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);}
void MiniDump::CharToTchar(const char * _char, TCHAR * tchar){    int iLength;    iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);    MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);}
const char * MiniDump::GenerateDumpFilePath(){    //路径    TCHAR szDumpDirT[MAX_PATH] = { 0 };    GetCurrentDirectory(MAX_PATH, szDumpDirT);    char szDumpDir[MAX_PATH] = { 0 };    TcharToChar(szDumpDirT, szDumpDir);
    //时间    SYSTEMTIME stTime;    GetLocalTime(&stTime);    char szCurtTime[64] = { 0 };    sprintf_s(szCurtTime, sizeof(szCurtTime) / sizeof(char), "%04d-%02d-%02d-%02d-%02d-%02d", stTime.wYear, stTime.wMonth, stTime.wDay, stTime.wHour, stTime.wMinute, stTime.wSecond);
    //dump文件路径    char szDumpFile[MAX_PATH] = { 0 };    sprintf_s(szDumpFile, sizeof(szDumpFile) / sizeof(char), "%s\\%s_%s.dmp", szDumpDir, m_szProcessName, szCurtTime);
    return szDumpFile;}

以上是关于封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。的主要内容,如果未能解决你的问题,请参考以下文章

记一次 腾讯会议 的意外崩溃分析

VS2017社区中的C++程序崩溃

Ubuntu内部错误信息及处理

在 Swift 的 Objective-C++ 类中设置变量 --> 意外的 nil 崩溃

定制的 C++ Windows 应用程序崩溃并生成一个空的 dmp 文件

当父母在python中崩溃时杀死子进程