当前位置:   article > 正文

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

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


分析软件崩溃,除了需要dmp,还需要这个pdb文件
dmp,文件记录了崩溃的信息,而pdb(代码工程数据库),则包含了你写的代码
通过dump + pdb从而定位到你写的错误代码的地方

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

#include "DebugTest.h"
#include <QtWidgets/QApplication>
#include <WinSock2.h>
#include <DbgHelp.h>
#include <windows.h>
#include <winnt.h>
#include <QMessageBox>
#include <QString>
#include <QTime>
#include <QDebug>

//防止中文乱码
#pragma execution_character_set("utf-8") 

/**
 * 仅仅包含<DbgHelp.h>头文件并不足以让编译器知道如何链接到相应的库。因此,需要告诉编译器要链接哪个库。在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();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意

只有在工程项目里面配置了这个,才会生成pdb
在这里插入图片描述
设置步骤
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/865448
推荐阅读
相关标签
  

闽ICP备14008679号