QT应用编程: window下QT程序异常捕获并生成DMP文件、PDB文件

2024-07-21 1331阅读

文章目录

  • main.cpp代码捕获异常 生成dmp文件和pdb文件
  • DebugTest生成错误代码
  • 注意

    分析软件崩溃,除了需要dmp,还需要这个pdb文件

    dmp,文件记录了崩溃的信息,而pdb(代码工程数据库),则包含了你写的代码

    通过dump + pdb从而定位到你写的错误代码的地方

    main.cpp代码捕获异常 生成dmp文件和pdb文件

    #include "DebugTest.h"
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    //防止中文乱码
    #pragma execution_character_set("utf-8") 
    /**
     * 仅仅包含头文件并不足以让编译器知道如何链接到相应的库。因此,需要告诉编译器要链接哪个库。在Windows平台上,这通常是通过在源代码文件中使用#pragma comment(lib, "library_name")指令来完成的
     */
    //编译器链接Windows 调试帮助库  调试和错误报告
    #pragma comment(lib, "Dbghelp.lib")
    void CreateMiniDump(EXCEPTION_POINTERS* pep, char* strDumpFile)
    {
    	/**
    	 * strDumpFile:这是一个指向字符串的指针,表示要创建或打开的文件名。
    	 * GENERIC_READ | GENERIC_WRITE:这表示我们想要对该文件具有读取和写入的权限。| 符号用于组合这些权限。
    	 * 0:这是安全描述符的句柄,用于指定文件的安全属性。在这里,它被设置为 0,表示使用默认的安全描述符。
    	 * NULL:这是指向安全属性结构的指针,用于进一步定义文件的安全属性。在这里,它被设置为 NULL,表示使用默认的安全属性。
    	 * CREATE_ALWAYS:这是一个标志,指示如果文件已存在,它应该被截断为零长度,然后重新写入。如果文件不存在,它应该被创建。
    	 * FILE_ATTRIBUTE_NORMAL:这是一个标志,指示文件应该具有正常的属性。
    	 * 0:这是用于文件创建的文件模板的句柄。在这里,它被设置为 0,因为我们不使用文件模板。
    	 
    	 * 创建一个名为 strDumpFile 的文件(如果它还不存在),或者如果它已经存在,则截断它并重新写入。文件将具有读取和写入的权限,并且具有正常的文件属性
    	*/
    	HANDLE hFile = CreateFileA(strDumpFile, GENERIC_READ | GENERIC_WRITE, 0,
    		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    	//在程序崩溃或遇到异常时捕获其内存状态
    	//文件句柄的意思是用于标识和访问文件的唯一标识符
    	//确保hFile是一个有效的文件句柄,它既不是NULL也不是INVALID_HANDLE_VALUE(一个表示无效的句柄的特殊值)
    	if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
    	{
    		//创建dump文件的额外信息
    		MINIDUMP_EXCEPTION_INFORMATION mdei;
    		mdei.ThreadId = GetCurrentThreadId();//获取当前线程id
    		mdei.ExceptionPointers = pep;//异常发生时的信息
    		mdei.ClientPointers = TRUE;//表示`ExceptionPointers`中的指针是有效的
    		//设置转储类型
    		MINIDUMP_TYPE mdt = MiniDumpWithDataSegs;
    		//MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpNormal | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo);
    		//MiniDumpWriteDump是Windows API中的一个函数,用于将当前进程的内存状态写入一个文件
    		//它接受多个参数,包括当前进程、进程ID、文件句柄、转储类型以及额外的信息(如mdei)
    		BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, mdt,
    			&mdei, 0, 0);
    		//处理结果
    		if (rv)
    		{
    			//LOG_ERROR("create dump[%s] success.", strDumpFile);
    		}
    		else
    		{
    			//LOG_ERROR("create dump[%s]failed Error:[%d].", strDumpFile, GetLastError());
    		}
    		//关闭文件句柄
    		CloseHandle(hFile);
    	}
    }
    //在程序出现异常时,生成一个包含当前日期和时间的dump文件名,并调用一个函数来创建这个dump文件,以记录异常时的程序状态
    //WINAPI: 一个宏,通常用于Windows API函数的调用约定
    LONG WINAPI MyCustomFilter(EXCEPTION_POINTERS* pep)
    {
    	//LOG_ERROR("===================Program Exception=====================");
    	QString strDumpFile;
    	//使用sprintf风格的格式化方法来生成dump文件的名称
    	//获取了当前日期和时间
    	strDumpFile.sprintf("Dump_%s_%s.dmp", QDate::currentDate().toString("yyyyMMdd").toStdString().c_str(),
    		QTime::currentTime().toString("HHmmss").toStdString().c_str());
    	//LOG_ERROR("CreateDump Start");
    	//创建dump文件 将QString转换为char*格式的C字符串
    	CreateMiniDump(pep, strDumpFile.toLatin1().data());
    	//LOG_ERROR("CreateDump Finish");
    	 
    	//结束程序运行
    	QApplication::quit();
    	//异常已经被处理,可以继续执行后续的代码
    	return EXCEPTION_EXECUTE_HANDLER;
    }
    //出现异常时弹出提醒框
    LONG ExceptionCapture(EXCEPTION_POINTERS *pException) {
    	
    	//弹出错误对话框并退出程序
    	//Qt的QMessageBox类来显示一个“critical”(严重)级别的消息框
    	//参数:无父窗口 消息框标题 消息框内容 消息框按钮
    	QMessageBox::critical(nullptr, "错误提示", QString("程序遇到异常"), QMessageBox::Ok, QMessageBox::Ok);
    	return EXCEPTION_EXECUTE_HANDLER;
    }
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    	//注册异常捕获函数
    	//SetUnhandledExceptionFilter可以在Windows程序中,让未处理的异常发生时执行自定义的代码
    	SetUnhandledExceptionFilter(MyCustomFilter);
        DebugTest w;
        w.show();
        return a.exec();
    }
    

    DebugTest生成错误代码

    #include "DebugTest.h"
    #include "ui_DebugTest.h"
    DebugTest::DebugTest(QWidget *parent)
        : QWidget(parent)
    {
        ui.setupUi(this);
    	connect(ui.pushButton, &QPushButton::clicked,this,&DebugTest::pushButton_clicked);
    }
    DebugTest::~DebugTest()
    {
    }
    void DebugTest::pushButton_clicked() {
    	//指针不指向任何有效的内存地址
    	int *p = nullptr;
    	//尝试解引用一个nullptr指针(即使用*p来访问或修改指针指向的值)会导致运行时错误,因为并没有一个有效的内存位置可以访问
    	*p = 666666666;
    }
    

    注意

    只有在工程项目里面配置了这个,才会生成pdb

    QT应用编程: window下QT程序异常捕获并生成DMP文件、PDB文件

    设置步骤

    QT应用编程: window下QT程序异常捕获并生成DMP文件、PDB文件

    QT应用编程: window下QT程序异常捕获并生成DMP文件、PDB文件

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]