提交 9cc0982a 编写于 作者: mahuifa's avatar mahuifa

refactor:修改Release模式下关闭优化、生成调试信息功能

    1、使用更加规范的写法;
    2、在MinGW编译器下也可以使用。
上级 2f4b0b3d
......@@ -91,8 +91,8 @@
### 1.5 TestCrashHandler
> 1. 通过win api实现qt程序崩溃问题定位功能;
> 2. 只支持**msvc编译器**;
> 1. 通过Windows中的dbghelp api实现qt程序崩溃问题定位功能;
> 2. 只支持**msvc编译器**,MinGW虽然也可以运行并生成Dump文件,但是不方便调试
>
> 3. 低耦合模块,**一行代码**直接引用功能,无需添加第三方依赖库;
>
......@@ -102,7 +102,7 @@
>
> 6. 通过宏判断,在MinGW或其他系统环境编译时功能自动失效**不会编译失败**;
>
> 7. 支持release模块下生成dump文件。
> 7. 支持release模式下关闭优化,生成调试详细,崩溃时生成dump文件。
![Dump](FunctionalModule.assets/Dump.gif)
......
#---------------------------------------------------------
# 功能: 使用win api捕获qt崩溃异常信息,定位崩溃位置
# 功能: 使用windows下的dbghelp api捕获qt崩溃异常信息,定位崩溃位置
# 编译器: MSVC
#
# @开发者 mhf
# @邮箱 1603291350@qq.com
# @时间 2022/04/05
# @备注 无需引入 第三方依赖
# 虽然MSVC、MinGW都能运行并生成dump文件,但是由于Mingw编译的程序不会生成
# pdb符号文件,不方便调试,所以建议使用MSVC编译器
#---------------------------------------------------------
HEADERS += \
$$PWD/crashhandler.h
......@@ -14,10 +16,38 @@ SOURCES += \
$$PWD/crashhandler.cpp
LIBS += -ldbghelp
# msvc(VS调试模式,在VS2015 + QT5.6.3环境下调试通过)
QMAKE_CXXFLAGS_RELEASE += /Zi
QMAKE_CXXFLAGS_RELEASE += /Od
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG # Release版也将生成“.pdb”后缀的调试信息文件
## DEFINES +=QT_NO_DEBUG_OUTPUT # disable debug output
DEFINES -= QT_NO_DEBUG_OUTPUT # enable debug output
msvc:CONFIG(release, debug|release) {
QMAKE_CFLAGS_RELEASE -= -O2 # 取消C优化
QMAKE_CFLAGS_RELEASE += -Zi # 生成调试信息,放到pdb文件中
QMAKE_CXXFLAGS_RELEASE -= -O2 # 取消C++优化
QMAKE_CXXFLAGS_RELEASE += -Zi # 生成调试信息
QMAKE_LFLAGS_RELEASE -= /INCREMENTAL:NO # 选择增量链接
QMAKE_LFLAGS_RELEASE += /DEBUG # 将调试信息放到PDB文件中
message(MSVC编译器Release关闭优化,生成调试信息使用)
}
mingw:CONFIG(release, debug|release) {
QMAKE_CFLAGS_RELEASE -= -O2 # 取消C优化
QMAKE_CFLAGS_RELEASE += -O0 # 显示指定禁止优化
QMAKE_CFLAGS_RELEASE += -g # 生成C调试信息
QMAKE_CXXFLAGS_RELEASE -= -O2 # 取消C++优化
QMAKE_CXXFLAGS_RELEASE += -O0 # 显示指定禁止优化
QMAKE_CXXFLAGS_RELEASE += -g # 生成C++调试信息
QMAKE_LFLAGS_RELEASE -= -Wl,-s # 取消Release模式删除所有符号表和重新定位信息的设置
QMAKE_LFLAGS_RELEASE += -g # 链接器生成调试信息
message(Mingw编译器Release关闭优化,生成调试信息使用)
}
# 如果不加unix,MinGW也会进入这里
unix:gcc:CONFIG(release, debug|release) {
QMAKE_CFLAGS_RELEASE -= -O2 # 取消C优化
QMAKE_CFLAGS_RELEASE += -O0 # 显示指定禁止优化
QMAKE_CFLAGS_RELEASE += -g # 生成C调试信息
QMAKE_CXXFLAGS_RELEASE -= -O2 # 取消C++优化
QMAKE_CXXFLAGS_RELEASE += -O0 # 显示指定禁止优化
QMAKE_CXXFLAGS_RELEASE += -g # 生成C++调试信息
QMAKE_LFLAGS_RELEASE -= -Wl,-O1 # 取消Release模式链接器优化
QMAKE_LFLAGS_RELEASE += -g # 链接器生成调试信息
message(GCC编译器Release关闭优化,生成调试信息使用)
}
......@@ -3,17 +3,18 @@
#include <QDateTime>
#include <qglobal.h>
#ifdef _MSC_VER
#if defined(_MSC_VER)
#include <Windows.h> // Windows.h必须放在DbgHelp.h前,否则编译会报错
#include <DbgHelp.h>
#elif defined(__MINGW32__)
#include <windows.h> // MinGW下这两个头文件是小写
#include <dbghelp.h>
#endif
//MSVC编译器
#ifdef _MSC_VER
#if defined(_MSC_VER) && (_MSC_VER >= 1600) && (_MSC_VER <= 1900)
#pragma execution_character_set("utf-8")
#endif
//#if defined(_MSC_VER) && (_MSC_VER >= 1600)
//#pragma execution_character_set("utf-8")
//#endif
/**
* @brief 应用程序崩溃处理程序
* @param pException
......@@ -21,7 +22,8 @@
* EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,其他人来吧,于是windows调用默认的处理程序显示一个错误框,并结束(qt中会导致窗口卡死一段时间)
* EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行
*/
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException){//程式异常捕获
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{
//创建 Dump 文件
QString strPath = QString("%1.dmp").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH-mm-ss"));
#ifdef UNICODE
......@@ -29,7 +31,7 @@ LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException){//程式异常捕
#else
LPCSTR filePath = reinterpret_cast<LPCSTR>(strPath.toStdString().data());
#endif // !UNICODE
HANDLE hDumpFile = CreateFile(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hDumpFile = CreateFile(filePath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if( hDumpFile != INVALID_HANDLE_VALUE){
//Dump信息
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
......@@ -37,23 +39,22 @@ LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException){//程式异常捕
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
//写入Dump文件内容
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, nullptr, nullptr);
}
//这里弹出一个错误对话框并退出程序
EXCEPTION_RECORD* record = pException->ExceptionRecord;
QString errCode(QString::number((quint64)record->ExceptionCode, 16));
QString errAdr(QString::number((uint)record->ExceptionAddress, 16));
QMessageBox::critical(nullptr, "程式崩溃","<FONT size=4><div><b>对于发生的错误,表示诚挚的歉意</b><br/></div>"+
QString errCode(QString::number(quint64(record->ExceptionCode), 16));
QString errAdr(QString::number(quint64(record->ExceptionAddress), 16));
QMessageBox::critical(nullptr, "不会吧,程序居然发生异常了~","<FONT size=4><div><b>对于发生的错误,表示诚挚的歉意</b><br/></div>"+
QString("<div>错误代码:%1</div><div>错误地址:%2</div></FONT>").arg(errCode).arg(errAdr),
QMessageBox::Ok);
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
//#endif
void CrashHandler::initCrashHandler()
{
#ifdef _MSC_VER
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler); // 使用win API注册异常处理函数
#endif
SetUnhandledExceptionFilter(static_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(ApplicationCrashHandler)); // 使用win API注册异常处理函数
}
......@@ -10,12 +10,7 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册