使用WinDbg查看Qt中引起程序崩溃的原因
Qt中程序崩溃往往没有任何错误提示,只提示程序异常结束。如果在项目复杂的时候往往很难找出错误原因,使用WinDbg生成的日志中能更加直观地看到错误的信息,以便程序员更改。
Qt中项目中pro文件加入以下代码
HEADERS += windbg.h
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE += $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
LIBS += -lDbgHelp
在Qt项目中新建一个h文件
命名为WinDbg,并加入以下代码
#ifndef WINDBG_H
#define WINDBG_H
#include <QApplication>
#include <QDir>
#include <QDateTime>
#include <windows.h>
#include <dbghelp.h>
long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp)
{
QString appName = QCoreApplication::applicationDirPath();
appName.append("/dmpDir");
QDir dir(appName);
if(!dir.exists()){
dir.mkpath(appName);
}
appName.append("/")
.append(QCoreApplication::applicationName())
.append(".")
.append(QString::number(QDateTime::currentMSecsSinceEpoch()))
.append("_CRASH_DUMP.DMP");
//create Dump file
HANDLE hDumpFile = ::CreateFile(
(LPCWSTR)appName.utf16(),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDumpFile != INVALID_HANDLE_VALUE)
{
//Dump info
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pexcp;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
//write Dump
::MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hDumpFile,
MiniDumpNormal,
&dumpInfo,
NULL,
NULL
);
}
return 0;
}
#endif // WINDBG_H
main函数调用以下函数
::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);
- 以下代码为例
int main(int argc, char *argv[])
{
::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
下载WinDbg
进入此网页进行下载
https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/
WinDbg的设置
-
点击文件
-
点击Settings
-
Debugging settings
-
添加项目路径,我的项目是在debug模式下生成的,则在项目路径的debug文件夹下,dempDir是我们生成dump文件的地方,完成后点击ok
- 打开程序运行崩溃后生成dump文件
- 滑倒最底下点击*!analyze -v*
- 等待加载完成会生成一段错误信息的分析
- 我这里是setGeometry函数出错,我需要回去检查这个函数中是否有传入空指针或者野指针
- 检查后发现,我这边指针为初始化就进行使用了