记录:MSVC+Qt生成dump文件

本文只是记录下 MSVC+Qt 生成 dump 的代码。

dump 文件能够保存程序内部的内存、堆栈、句柄、线程等程序运行相关的信息,当程序异常无法在调试环境里解决时,dump 文件是分析问题的重要手段。

相关 win API 文档可以在 MSDN 查看:https://docs.microsoft.com/zh-cn/search/?terms=MiniDumpWriteDump

DUMPTYPE 参数我只使用了 MiniDumpNormal,可以根据文档加上自己需要的。

dump 文件一般配合 pdb 文件使用,通过 pdb 可以找到堆栈地址对应的函数、行号等。

如果使用的 QtCreator,可以打开如下设置:

如果使用 VS ,可以打开如下两个设置:

生成 dump 完整代码: 

#include "mainwindow.h"
#include "CrashDump.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    CrashDump::init("Test");

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
#pragma once

#include <QObject>
#include <QCalendar>
#include <QDateTime>
#include <QFileInfo>
#include <QDir>
#include <Windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "DbgHelp")
#include <iostream>

static QString __module_name;

/**
 * @brief MSVC+Qt 生成dump文件
 * @author 龚建波
 * @date 2021-2-11
 * @details 配合pdb文件使用,生成exe时记得生成dpb
 */
class CrashDump
{
public:
    //初始化注册
    static void init(const QString &module)
    {
        __module_name=module;
        //异常捕获
        ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exceptionFilter);
    }

    //获取exe路径
    static QString getAppPath()
    {
        DWORD v;
        QVarLengthArray<char, 2048> buffer;
        size_t size = 0;
        do {
            size += 2048;
            buffer.resize((int)size);
            v = ::GetModuleFileNameA(NULL, buffer.data(), DWORD(buffer.size()));
        } while (v >= size);

        return QString::fromLocal8Bit(buffer.data(), v);
    }

    //生成dump路径,可以自定义路径以及命名格式
    static QString getDumpPath()
    {
        QFileInfo app_info(getAppPath());
        QString dump_path=QString("%1/dump/%2 %3.dmp")
                .arg(app_info.absolutePath())
                .arg(__module_name)
                .arg(QDateTime::currentDateTime().toString("yyyy_MM_dd hh.mm.ss"));
        QFileInfo dump_info(dump_path);
        if(!dump_info.dir().exists()&&!dump_info.dir().mkpath(dump_info.absolutePath()))
            dump_path=QString("%1.dump").arg(__module_name);
        return dump_path;
    }

    //异常处理
    static LONG exceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
    {
        QString dump_path = getDumpPath();
        std::cerr<<"crash dump:"<<dump_path.toStdString()<<std::endl;

        //创建文件
        HANDLE file_handle = ::CreateFileA(dump_path.toLocal8Bit().data(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file_handle != INVALID_HANDLE_VALUE) {
            DWORD dump_type = MiniDumpNormal; //可以加上需要的其他枚举值
            MINIDUMP_EXCEPTION_INFORMATION dump_info;
            dump_info.ClientPointers = TRUE;
            dump_info.ExceptionPointers = lpExceptionInfo;
            dump_info.ThreadId = ::GetCurrentThreadId();
            //写入dump
            ::MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file_handle, (MINIDUMP_TYPE)dump_type, &dump_info, NULL, NULL);
        }
        ::CloseHandle(file_handle);
        //这里可以把程序拉起来
        return EXCEPTION_CONTINUE_SEARCH; //or EXCEPTION_EXECUTE_HANDLER
    }
};

程序遇到异常生成 dump 文件后,可以使用 VS 打开:

这里符号路径我只设置了 exe 对应 pdb 的路径:

最后点仅限本机调试就可以看到异常现场了:

(2021-3-26)要注意的是,SetUnhandledExceptionFilter 并不能捕获所有的异常,可以搜索其他的相关函数:

    //terminate()
    set_terminate(terminateHandler);
    //printf(NULL)
    _set_invalid_parameter_handler(invalidParameterHandler);
    //调用纯虚函数
    _set_purecall_handler(purecallHandler);
    //new异常
    _set_new_handler(newHandler);

 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
根据提供的引用内容,NMAKE:-1: error: U1073错误是由于无法生成指定的文件而导致的。具体来说,错误信息中提到了无法生成"D:\Qt\Qt6.4\6.6.1\msvc2019_64\lib\Qt6Mqttd.lib"文件。这可能是由于以下几个原因导致的: 1. 缺少相关的依赖库或文件。请确保你的项目中包含了正确的依赖库,并且这些库的路径是正确的。 2. 编译器或构建工具的配置错误。请检查你的编译器和构建工具的配置,确保它们与你的项目要求相匹配。 3. 编译器或构建工具版本不兼容。请确保你使用的编译器和构建工具的版本与你的项目要求相匹配。 为了解决这个问题,你可以尝试以下几个方法: 1. 检查依赖库和文件路径是否正确。确保你的项目中包含了正确的依赖库,并且这些库的路径是正确的。 2. 检查编译器和构建工具的配置。确保你的编译器和构建工具的配置与你的项目要求相匹配。 3. 更新编译器和构建工具的版本。如果你的编译器和构建工具版本不兼容,尝试更新它们到与你的项目要求相匹配的版本。 4. 检查你的cmake文件是否编写错误。根据引用中的描述,错误可能是由于将CMAKE_SOURCE_DIR错误地当做CMAKE_CURRENT_SOURCE_DIR使用导致的。请检查你的cmake文件,确保路径和变量的使用是正确的。 希望以上方法能够帮助你解决NMAKE:-1: error: U1073错误。如果问题仍然存在,请提供更多的信息以便我们能够更好地帮助你解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龚建波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值