Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析

 

目录

 

1. 概要

2. 研究目的

3. Qt+MSVC环境配置

3.1. 安装Qt

3.2. 安装VS或者安装对应版本的编译器

4. dump文件生成

4.1  Qt 生成dump文件的代码

5. Qt dump调试的原材料:pdb文件

6. 调试

6.1 使用VS调试

6.2 使用WinDbg调试

6.2.1 安装Windows Debugging Tools

6.2.2 调试


1. 概要

本文主要研究dump文件在windows操作系统、Qt编辑器、MSVC编译环境下的产生和分析。主要从以下几个方面来描述:

1. dump文件存在的意义;

2. 配置Win10操作系统下, QT + MSVC的编写编译环境;

3. dump文件如何产生;

4. windows 软件分析调试dump文件的必备材料:pdb文件;

5. 分析和调试方法;

2. 研究目的

为什么需要研究dump文件分析?

软件在长时间运行后,突然崩溃或死掉,且此时的日志也未写入或者日志中无法提示任何信息。此时我们就需要分析dump文件,判断崩溃时的堆栈,以及断点调试查看相关的值,进而了解到软件的不健壮节点并加以修复。

3. Qt+MSVC环境配置

尽量采用Qt自检测编译的方式来加载MSCV编译器。

3.1. 安装Qt

在安装Qt时,需要注意我们安装的kit版本,我的Qt版本是Qt5.12.2,选择安装的Kit有 Qt 5.12.2 MSVC2015 64bit、Qt 5.12.2 MSVC2017 32bit、Qt 5.12.2 MinGW 32-bit、 Qt 5.12.2 MinGW 64-bit。安装完成后,在Qt->工具->选项->Kits里看到安装的Kit套件。在安装完成后,可以选择将编译器所在的路径添加到环境变量。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第1张图片

3.2. 安装VS或者安装对应版本的编译器

因为在安装Qt时选择的kit中有Qt 5.12.2 MSVC2017 32bit,所以我选择安装VS的版本也是2017版本(ps:之前有安装2019版本,结果Qt不能自然搜索到对应的编译器,应该是Qt5.12.2无法检测到VS2019的编译器,当然,我们也可以在Qt中自定义个编译器,本文暂不做阐释)。选择安装的内容,包含 “使用C++的桌面开发”,“通用Windows平台开发”。

3. 配置Qt的MSVC的环境

在安装VS完成后,重启下Qt,会在Qt->工具->选项->Kits看到对应的编译器。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第2张图片

然后,将构建套件kit相应项配置编译器和调试器。微软的配置微软的编译器。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第3张图片

至此,Qt5.12 + MSVC编译环境就配置完成了。

4. dump文件生成

4.1  Qt 生成dump文件的代码


#include 
#include 
#pragma comment(lib, "user32.lib")

int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers)
{
    // 定义函数指针
    typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
        HANDLE,
        DWORD,
        HANDLE,
        MINIDUMP_TYPE,
        PMINIDUMP_EXCEPTION_INFORMATION,
        PMINIDUMP_USER_STREAM_INFORMATION,
        PMINIDUMP_CALLBACK_INFORMATION
        );
    // 从 "DbgHelp.dll" 库中获取 "MiniDumpWriteDump" 函数
    MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
    HMODULE hDbgHelp = LoadLibrary(_T("DbgHelp.dll"));
    if (NULL == hDbgHelp)
    {
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");

    if (NULL == pfnMiniDumpWriteDump)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    // 创建 dmp 文件件
    TCHAR szFileName[MAX_PATH] = { 0 };
    TCHAR szVersion[] = L"DumpFile";
    SYSTEMTIME stLocalTime;
    GetLocalTime(&stLocalTime);
    wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d.dmp",
        szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
        stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
    HANDLE hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
    if (INVALID_HANDLE_VALUE == hDumpFile)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    // 写入 dmp 文件
    MINIDUMP_EXCEPTION_INFORMATION expParam;
    expParam.ThreadId = GetCurrentThreadId();
    expParam.ExceptionPointers = pExceptionPointers;
    expParam.ClientPointers = FALSE;
    pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
        hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &expParam : NULL), NULL, NULL);
    // 释放文件
    CloseHandle(hDumpFile);
    FreeLibrary(hDbgHelp);
    return EXCEPTION_EXECUTE_HANDLER;
}

LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
    // 这里做一些异常的过滤或提示
    if (IsDebuggerPresent()) {
        return EXCEPTION_CONTINUE_SEARCH;
    }
    return GenerateMiniDump(lpExceptionInfo);
}

调用代码:

int main(int argc, char *argv[])
{
    //生成异常的dump文件
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);

    QApplication a(argc, argv);
    CoreDumpWin w;
    w.show();


    return a.exec();
}

至此,软件运行过程中,如果异常崩溃,会产出.dmp文件。

 

5. Qt dump调试的原材料:pdb文件

如果应用或服务产生pdb文件,只需要在项目构建的qmake添加额外的参数:

CONFIG+=force_debug_info" "CONFIG+=separate_debug_info"

Qt自身模块pdb文件在Qt安装时,是不安装的,所以需要我们手动去安装Qt的pdb文件:

手动安装匹配的pdb文件的原文链接地址。

a)首先在qt的安装目录下找到MaintenanceTool.exe,运行它

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第4张图片

b) 设置存储库地址,建议选择临时库,且添加地址, 测试并提醒成功,点击ok。(5122是Qt的版本号)

https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5122/
https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/tools_mingw/
https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5122_src_doc_examples/

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第5张图片

c) 添加或移除组件,点击“下一步”。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第6张图片

d)选择 "Qt Debug Information Files",选择完成后,点击“下一步”,并安装。如果网速慢的话,这将是个漫长的过程。(注意:除非你想卸载什么,否则不要去掉已经打勾项)

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第7张图片

至此,所有的配置与所需材料都已经完成。

6. 调试

编译Rlease程序,并将对应的pdb文件与应用/服务程序放到同一目录下,当软件执行出异常崩溃时,会在该目录下产生dmp文件,我们据此文件来调试堆栈,查看软件崩溃在什么地方,并调试它。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第8张图片

6.1 使用VS调试

调试方法:

a) 使用VS打开xxx.dmp文件,”使用本机进行调试“

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第9张图片

b) 调试时,会显示崩溃的代码,以及对应的堆栈信息,如有提示未加载符号,需要我们手动添加符号路径。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第10张图片

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第11张图片

通过堆栈,可以看到调用函数。

Win10 Qt5.12.2 + MSVC编译器 dump文件创建与分析_第12张图片

根据例子,可以分析出,MyTestClass对象指针为nullptr。调用函数on_pushButton_clicked()函数没有为MyTestClass对象指针分配内存。

6.2 使用WinDbg调试

WinDbg 除了可以分析软件崩溃的位置,也可以分析内存占用大,内存溢出等问题。

6.2.1 安装Windows Debugging Tools

官网下载 Win10SDK,并安装,且只安装Windows Debugging Tools,安装WinDbg调试软件。

6.2.2 调试

参考:https://www.cnblogs.com/nchxmoon/p/4390980.html

你可能感兴趣的:(windows,Qt学习)