windows下qt(msvc)查找crash 的方式 生成dump
程序员文章站
2022-06-16 15:45:02
...
上一遍我们研究了 mingw编译的程序生成dump和查找,这遍我们再研究一下msvc编译器下的qt程序
其中用到的类,以及整个工程,我放到了github可以供下载参考:源码
1. 生成dump文件
long ApplicationCrashHandler(EXCEPTION_POINTERS *pException){
{
// 在程序exe的上级目录中创建dmp文件夹
QDir *dmp = new QDir;
bool exist = dmp->exists("../dmp/");
if(exist == false)
dmp->mkdir("../dmp/");
}
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyy_MM_dd_hh_mm_ss");
QString time = current_date + ".dmp";
EXCEPTION_RECORD *record = pException->ExceptionRecord;
QString errCode(QString::number(record->ExceptionCode, 16));
QString errAddr(QString::number((uint)record->ExceptionAddress, 16));
QString errFlag(QString::number(record->ExceptionFlags, 16));
QString errPara(QString::number(record->NumberParameters, 16));
qDebug()<<"errCode: "<<errCode;
qDebug()<<"errAddr: "<<errAddr;
qDebug()<<"errFlag: "<<errFlag;
qDebug()<<"errPara: "<<errPara;
HANDLE hDumpFile = CreateFile((LPCWSTR)QString("../dmp/" + time).utf16(),
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDumpFile != INVALID_HANDLE_VALUE) {
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pException;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
CloseHandle(hDumpFile);
}
else{
qDebug()<<"hDumpFile == null";
}
return EXCEPTION_EXECUTE_HANDLER;
}
main 函数注册异常捕获函数
//注冊异常捕获函数
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
2. .pro 中添加文件配置 如果是release 版本禁用优化 ,启用生成调试信息
LIBS += -lDbgHelp
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG
3. dump 生成以后,用windbg 查看 dmp文件,也可以用 vs 直接打开调试。
直接运行 使用本机进行调试
注意:
1. 使用DMP文件和pdb文件调试时DMP、exe和pdb三个文件要保持版本一致。也就是说,如果你运行exe文件,程序崩溃,生成DMP文件后,此时你再重新编译程序,重新生成了exe文件和pdb文件。即使源码没有发生任何改动,你双击DMP文件也是没有办法再定位到源代码中的错误了。所以你得及时把exe文件和pdb文件做好备份。
2.有些时候即使程序崩溃了也是没有办法生成DMP文件的,比如有时数组越界导致程序崩溃的时候。所以这个方法也不能保证一定能找到程序崩溃的原因,所以大家得掌握更多的调试手段。
4。 这里主要介绍windbg 方式
步骤为:
- 运行Windbg。
- 指定PDB文件路径: File - Symbol File Path。多个路径用分号分隔。
- 指定代码路径:File - Source File Path
- 载入dump文件。
- Windbg命令行输入: !analyze -v
- 等待结果 - 函数调用堆栈,程序崩溃代码。busy状态表示正在生成结果。
注意:若生成的dump文件在本机,dump文件中将包含调试需要的PDB文件及源代码路径,若不在本机,可以通过WinDbg菜单[File] à [Symbol File path] 及 [Source File Path] 分别设置PDB文件路径和源代码路径。如果程序涉及到DLL,需要将EXE、DLL所有涉及的PDB、源代码路径都包括。
在WinDbg中点击【File】-----【Open Crash Dump】选择.DMP文件打开。
命令行输入 !analyze -v
查看效果