欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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 直接打开调试。

windows下qt(msvc)查找crash 的方式 生成dump

直接运行 使用本机进行调试

注意:

1. 使用DMP文件和pdb文件调试时DMP、exe和pdb三个文件要保持版本一致。也就是说,如果你运行exe文件,程序崩溃,生成DMP文件后,此时你再重新编译程序,重新生成了exe文件和pdb文件。即使源码没有发生任何改动,你双击DMP文件也是没有办法再定位到源代码中的错误了。所以你得及时把exe文件和pdb文件做好备份。

2.有些时候即使程序崩溃了也是没有办法生成DMP文件的,比如有时数组越界导致程序崩溃的时候。所以这个方法也不能保证一定能找到程序崩溃的原因,所以大家得掌握更多的调试手段。

4。 这里主要介绍windbg 方式

windbg的下载和安装

步骤为:

  1. 运行Windbg。
  2. 指定PDB文件路径: File - Symbol File Path。多个路径用分号分隔。
  3. 指定代码路径:File - Source File Path
  4. 载入dump文件。
  5. Windbg命令行输入:  !analyze -v
  6. 等待结果 - 函数调用堆栈,程序崩溃代码。busy状态表示正在生成结果。

注意:若生成的dump文件在本机,dump文件中将包含调试需要的PDB文件及源代码路径,若不在本机,可以通过WinDbg菜单[File] à [Symbol File path] 及 [Source File Path] 分别设置PDB文件路径和源代码路径。如果程序涉及到DLL,需要将EXE、DLL所有涉及的PDB、源代码路径都包括。

 

在WinDbg中点击【File】-----【Open Crash Dump】选择.DMP文件打开。

windows下qt(msvc)查找crash 的方式 生成dump

命令行输入 !analyze -v

查看效果

 

相关标签: windbg 调试dump