vs2019+qt工程中如何生成dump文件及调试详解

 更新时间:2026年01月11日 09:14:05   作者:new_zhou  
这篇文章主要介绍了vs2019+qt工程中如何生成dump文件及调试的相关资料,包括了调试前置条件、异常处理函数的区别、可复用代码、调试步骤等内容,需要的朋友可以参考下

一、调试前置条件

1、在编译之后,exe和pdb文件均需要发布给用户;

二、抓取异常的系统函数区分

AddVectoredExceptionHandler和SetUnhandledExceptionFilter

AddVectoredExceptionHandler 是“第一现场观察者”,
SetUnhandledExceptionFilter 是“最后兜底处理者”。
当一个异常发生时,Windows 内部顺序是:
``1️⃣ Vectored Exception Handlers (VEH)

2️⃣ 线程的 SEH (__try / __except)

3️⃣ C++ try / catch

4️⃣ UnhandledExceptionFilter (UEF)

5️⃣ Windows 默认异常处理(弹框 / 进程终止)`

对比项VEHUEF
调用时机最早最后
是否能看到 first-chance✅ 能❌ 不能
是否会被覆盖❌ 不会✅ 经常
稳定性⭐⭐⭐⭐⭐⭐⭐
使用难度
线上推荐

三、可直接复用的代码:

CrashDump.h:

#pragma once
#include <Windows.h>

class CrashDump
{
public:
    static void Install();

private:
    static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ep);
    static void WriteDump(PEXCEPTION_POINTERS ep);

private:
    static volatile LONG s_dumped;
};

CrashDump.cpp

#include "CrashDump.h"
#include <DbgHelp.h>
#include <strsafe.h>

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

volatile LONG CrashDump::s_dumped = 0;

void CrashDump::Install()
{
    AddVectoredExceptionHandler(1, VectoredHandler);
}

static bool IsFatalException(DWORD code, DWORD flags)
{
    // 明确忽略的异常(正常流程)
    switch (code)
    {
    case EXCEPTION_BREAKPOINT:
    case EXCEPTION_SINGLE_STEP:
    case 0xE06D7363: // C++ Exception
        return false;
    default:
        break;
    }

    // 不可继续异常 → 一定是致命的
    if (flags & EXCEPTION_NONCONTINUABLE)
        return true;

    // 常见致命异常
    switch (code)
    {
    case EXCEPTION_ACCESS_VIOLATION:
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
    case EXCEPTION_DATATYPE_MISALIGNMENT:
    case EXCEPTION_ILLEGAL_INSTRUCTION:
    case EXCEPTION_IN_PAGE_ERROR:
    case EXCEPTION_STACK_OVERFLOW:
        return true;
    default:
        return false;
    }
}

LONG CALLBACK CrashDump::VectoredHandler(PEXCEPTION_POINTERS ep)
{
    if (!ep || !ep->ExceptionRecord)
        return EXCEPTION_CONTINUE_SEARCH;

    DWORD code = ep->ExceptionRecord->ExceptionCode;
    DWORD flags = ep->ExceptionRecord->ExceptionFlags;

    // ⭐ 只处理真正致命异常
    if (!IsFatalException(code, flags))
        return EXCEPTION_CONTINUE_SEARCH;

    if (InterlockedCompareExchange(&s_dumped, 1, 0) == 0)
    {
        WriteDump(ep);

        // ❗真正崩溃点,立即终止
        TerminateProcess(GetCurrentProcess(), code);
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

void CrashDump::WriteDump(PEXCEPTION_POINTERS ep)
{
    wchar_t dir[MAX_PATH] = { 0 };
    GetModuleFileNameW(nullptr, dir, MAX_PATH);

    wchar_t* slash = wcsrchr(dir, L'\\');
    if (slash) *slash = 0;

    SYSTEMTIME st;
    GetLocalTime(&st);

    DWORD pid = GetCurrentProcessId();
    DWORD tid = GetCurrentThreadId();

    wchar_t path[MAX_PATH] = { 0 };

    StringCchPrintfW(
        path,
        MAX_PATH,
        L"%s\\DumpFile-%04d%02d%02d-%02d%02d%02d-P%u-T%u.dmp",
        dir,
        st.wYear, st.wMonth, st.wDay,
        st.wHour, st.wMinute, st.wSecond,
        pid, tid);

    HANDLE hFile = CreateFileW(
        path,
        GENERIC_WRITE,
        0,
        nullptr,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        nullptr);

    if (hFile == INVALID_HANDLE_VALUE)
        return;

    MINIDUMP_EXCEPTION_INFORMATION mei = {};
    mei.ThreadId = tid;
    mei.ExceptionPointers = ep;
    mei.ClientPointers = FALSE;

    MINIDUMP_TYPE type = (MINIDUMP_TYPE)(
        MiniDumpWithFullMemory |
        MiniDumpWithThreadInfo |
        MiniDumpWithHandleData |
        MiniDumpWithUnloadedModules);

    MiniDumpWriteDump(
        GetCurrentProcess(),
        pid,
        hFile,
        type,
        &mei,
        nullptr,
        nullptr);

    CloseHandle(hFile);
}

在main函数中调用:

 CrashDump::Install();

 QApplication a(argc, argv);
 ...

四、调试:

1、将dump文件放在对应的exe、pdb文件同级目录下;

2、

1)使用Visual Studio打开dump文件,然后设置符号路径,路径下需要有exe、pdb、dump;

2)点击“使用仅限本机进行调试”,即可重新异常情况;

总结

到此这篇关于vs2019+qt工程中如何生成dump文件及调试的文章就介绍到这了,更多相关vs2019 qt生成dump文件及调试内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言 柔性数组的使用详解

    C语言 柔性数组的使用详解

    柔性数组(Flexible Array)是引入的一个新特性,它允许你在定义结构体时创建一个空数组,而这个数组的大小可以在程序运行的过程中根据你的需求进行更改特别注意的一点是:这个空数组必须声明为结构体的最后一个成员,并且还要求这样的结构体至少包含一个其他类型的成员
    2022-03-03
  • C++中类的转换函数你了解吗

    C++中类的转换函数你了解吗

    这篇文章主要为大家详细介绍了C++中类的转换函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++11 lambda表达式在回调函数中的使用方式

    C++11 lambda表达式在回调函数中的使用方式

    这篇文章主要介绍了C++11 lambda表达式在回调函数中的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C++之Primer算术运算符详解

    C++之Primer算术运算符详解

    这篇文章主要介绍了C++之Primer算术运算符方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • opencv实现定时录像功能

    opencv实现定时录像功能

    这篇文章主要为大家详细介绍了opencv实现定时录像功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • C++实现五子棋游戏

    C++实现五子棋游戏

    这篇文章主要为大家详细介绍了C++实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C语言中if语句加大括号和不加大括号的区别介绍

    C语言中if语句加大括号和不加大括号的区别介绍

    这篇文章主要给大家介绍了关于C语言中if语句加大括号和不加大括号的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • 数据结构之AVL树详解

    数据结构之AVL树详解

    这篇文章主要介绍了数据结构之AVL树详解,本文非常细致的讲解了AVL树的基础知识、AVL树的旋转操作、AVL数的插入和删除操作等,需要的朋友可以参考下
    2014-08-08
  • C语言:十进制,BCD码互换详解

    C语言:十进制,BCD码互换详解

    这篇文章主要介绍了C语言十进制,BCD码互换实例,小编觉得这篇文章写的还不错,实例简单明了,需要的朋友可以参考下
    2021-09-09
  • C++实现LeetCode(312.打气球游戏)

    C++实现LeetCode(312.打气球游戏)

    这篇文章主要介绍了C++实现LeetCode(312.打气球游戏),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07

最新评论