Qt开发:软件崩溃时,如何生成dump文件

一、程序崩溃时如何自动生成 Dump 文件

步骤一:包含必要的头文件

#include <Windows.h>
#include <DbgHelp.h>

pro文件中添加库

LIBS += -lDbghelp

步骤二:创建生成 Dump 的函数

void CreateMiniDump(EXCEPTION_POINTERS* pep)
{
    SYSTEMTIME stLocalTime;
    GetLocalTime(&stLocalTime);

    TCHAR szFileName[MAX_PATH];
    swprintf_s(szFileName, MAX_PATH, L"CrashDump_%04d%02d%02d_%02d%02d%02d.dmp",
        stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
        stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);

    HANDLE hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL, NULL);

    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
    {
        MINIDUMP_EXCEPTION_INFORMATION mdei;
        mdei.ThreadId = GetCurrentThreadId();
        mdei.ExceptionPointers = pep;
        mdei.ClientPointers = TRUE;

        BOOL success = MiniDumpWriteDump(
            GetCurrentProcess(),
            GetCurrentProcessId(),
            hFile,
            MiniDumpWithFullMemory,  // 你也可以用 MiniDumpNormal
            &mdei,
            nullptr,
            nullptr);

        CloseHandle(hFile);

        if (success) {
            QString msg = QString("程序崩溃啦!\nDump 文件已保存为:\n%1").arg(QString::fromWCharArray(szFileName));
            MessageBoxW(NULL, (LPCWSTR)msg.utf16(), L"崩溃提示", MB_OK | MB_ICONERROR);
        } else {
            MessageBoxW(NULL, L"程序崩溃啦!但保存 Dump 文件失败。", L"崩溃提示", MB_OK | MB_ICONERROR);
        }
    }
}

步骤三:设置异常处理函数

LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* pExceptionInfo) {
    CreateMiniDump(pExceptionInfo);
    return EXCEPTION_EXECUTE_HANDLER;
}

步骤四:在程序入口设置异常处理

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

     // 故意触发异常(测试用)
     int* p = nullptr;
     *p = 42;

    return a.exec();
}

二、支持多线程中的异常捕获

  C++ 中 SetUnhandledExceptionFilter 只能捕获未被 catch 的 SEH 异常。如果你用 Qt 的多线程(如 QThread),线程内部抛出的是 std::exception 或 Qt 异常,是不会自动走到 UnhandledExceptionFilter 的。

方法:在线程函数中加 __try/__except 包裹

unsigned __stdcall ThreadFunc(void* param)
{
    __try {
        // 正常线程代码
        int* p = nullptr;
        *p = 100; // 故意异常
    }
    __except (CreateMiniDump(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {
        // 可选处理
    }

    return 0;
}

如果使用的是 QThread,可以重写 run() 方法,并包裹异常处理:

void MyThread::run()
{
    __try {
        // 正常逻辑
    }
    __except (CreateMiniDump(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {
        // 崩溃时生成 dump
    }
}

三、在 DLL 中使用 Dump 捕获

如果写的是一个 DLL 插件,也可以捕获崩溃,在 DllMain 中设置异常处理:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH) {
        SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
    }
    return TRUE;
}

四、封装成可复用类

可以把这整个流程封装成一个类,如:

class DumpCatcher
{
public:
    static void Init() {
        SetUnhandledExceptionFilter(UnhandledFilter);
    }

private:
    static LONG WINAPI UnhandledFilter(EXCEPTION_POINTERS* pExceptionInfo) {
        CreateMiniDump(pExceptionInfo);
        return EXCEPTION_EXECUTE_HANDLER;
    }

    static void CreateMiniDump(EXCEPTION_POINTERS* pep);
};

然后在程序入口调用:

DumpCatcher::Init();

五、MiniDumpWriteDump函数详解

  MiniDumpWriteDump 是 Windows 平台下由 DbgHelp 库提供的函数,用于在应用程序崩溃或其他时机生成进程的内存转储(.dmp)文件,便于事后用调试器(如 Visual Studio、WinDbg)分析崩溃原因和程序状态。

函数原型:

BOOL MiniDumpWriteDump(
    HANDLE                            hProcess,
    DWORD                             ProcessId,
    HANDLE                            hFile,
    MINIDUMP_TYPE                     DumpType,
    PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
    PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
    PMINIDUMP_CALLBACK_INFORMATION    CallbackParam
);

参数说明:
在这里插入图片描述

常用 MINIDUMP_TYPE:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值