Qt MSVC 的release模式抓取崩溃位置
一、编辑器设置及WinDbg程序获取安装
1、使用Qt creater编辑器的设置
1、打开项目后,在左侧工具栏选择项目,构建设置选择release模式,Separate debug info选项为Enable。
2、 项目配置文件**.pro中加入指定代码
作用:用于配置编译器和链接器在生成发布版本时的额外参数,编译时会在程序同济目录生成.pdb文件(如果已经有生成可以忽略)
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE += $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
2、 使用VS2022编辑器的设置
1、使用VS2022的扩展->Qt VS Tools-> Open Qt Project File(.pro)打开加载Qt项目
2、打开项目属性,设置链接器->调试->生成调试信息 设置为“生成调试信息(/DEBUG)"
注意事项:选择release模式
3、设置 C/C++ ->常规->调试信息格式 设置为"程序数据库(/Zi)"
4、设置 C/C++ ->优化->优化 设置为"已禁用(/Od)"
3、WinDbg 安装
已安装时忽略,其他下载地址:http://www.kkx.net/soft/107130.html;也可以app store微软商店下载。
4、项目中加入的捕获代码
1、新建头文件,定义函数,引入相关头文件
#ifndef CAPDUMP_H
#define CAPDUMP_H
#include "Windows.h"
#include "DbgHelp.h"
#include <QCalendar>
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QObject>
#include <iostream>
#include <qt_windows.h>
#include <tchar.h>
#pragma comment(lib, "DbgHelp.lib")
#pragma comment(lib, "user32.lib")
void GetExceptionDescription(DWORD errCode, QString &errdata);
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException);
#endif // CAPDUMP_H
2、源文件代码加入
#include "CapDump.h"
void GetExceptionDescription(DWORD errCode, QString &errdata) {
LPTSTR lpMsg = NULL;
HMODULE Hand = LoadLibrary(TEXT("ntdll.dll"));
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS /*FORMAT_MESSAGE_FROM_SYSTEM*/ | FORMAT_MESSAGE_FROM_HMODULE, Hand, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsg, 0, NULL);
errdata = QString::fromWCharArray(lpMsg);
qDebug() << errdata;
LocalFree(lpMsg);
}
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException) { //捕获异常
QString newDmpPath = QCoreApplication::applicationDirPath() + "/Dumps"; //创建 Dump 目录
QDir dir;
dir.mkpath(newDmpPath);
newDmpPath = QString("%1/dump_%2.dmp").arg(newDmpPath).arg(QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss_zzz"));
std::wstring wlpMsg = newDmpPath.toStdWString();
LPCWSTR lpMsg = wlpMsg.c_str();
HANDLE hDumpFile = CreateFile(lpMsg, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile != INVALID_HANDLE_VALUE) {
//Dump信息
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pException;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = FALSE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL); //写入Dump文件的内容
}
return EXCEPTION_EXECUTE_HANDLER;
}
3、注册该函数
main.cpp 内 main函数内 在 QApplication a(argc, argv); 后加入
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) ApplicationCrashHandler); //注冊异常捕获函数
4、编译运行
二、代码中加入崩溃示例代码 (以赋值空指针为例)
在主线程中某函数加入
int *p = NULL;
*p = 0;
示例如下:
三、WinDbg抓取错误函数
1、使用WinDbg打开dmp文件
2、设置Symbol路径
3、接下来设置源码路径(我的代码pro项目管理文件及代码在同一级目录,设置时看自己的项目路径)
4、在WinDbg命令行下输入!analyze -v 运行
!analyze -v //按回车后约等待10s中再分析结果