设为首页 加入收藏

TOP

【Visual Leak Detector】QT 中 VLD 输出解析(二)(二)
2023-07-23 13:34:58 】 浏览:77
Tags:Visual Leak Detector VLD 解析
iles (x86)\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\new_scalar.cpp;
  • Visual Studio 2019 使用的 new_scalar.cpp 文件真实路径为 D:\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\crt\src\vcruntime\new_scalar.cpp
  • 在不同系统上的相同版本的 Visual C++ Runtime Library 中,这个内置路径通常是一样的。(19) 表示 operator new() 函数中分配内存的代码位于 new_scalar.cpp 文件的第 19 行,最后面的 + 0x9 bytes 表示从 operator new() 函数开始到导致泄漏产生的指令的内存偏移量,这些信息在调试时很有用,可以帮助快速定位到确切代码行。

    第 9 行中,e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (6): testVLD.exe!testFun() + 0x7 bytes 表示 main.cpp 位于 e:\cworkspace\qt 5.9\qtdemo\testvld 路径下,这与项目实际路径是一致的,差别只是 VLD 将其全部转成了小写字母形式,testFun() 函数中分配内存的代码位于 main.cpp 的第 6 行,这与实际情况完全一致。最后面的 + 0x7 bytes 表示从 testFun() 函数开始到导致泄漏产生的指令的内存偏移量,这个信息据说是多用于汇编调试中,与实际是否能对上还没仔细研究过。

    第 10 行中,e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main() 表示 main() 函数中分配内存的代码位于 main.cpp 的第 16 行,没有提供指令的内存偏移信息,这与实际情况(第 14 行)有些差异,不过第 14 与第 16 行之间并没有别的代码,造成这种差异的原因有待深究,但对于定位泄漏点所在位置已经够用了。

    第 11~14 行,跟踪显示了启动程序所调用的函数链,其中 mainCRTStartup() 函数是入口点。

    第 15~17 行,跟踪显示了程序启动时所调用的 Windows 操作系统函数,BaseThreadInitThunk() 一般都会出现在调用栈底,它是 Windows 进程中所有用户模式线程的入口点,系统调用它在进程中启动一个新线程,并由它调用程序的主函数。ntdll.dll 中的 RtlGetAppContainerNamedObjectPath() 函数被调用了两次,但指令的内存偏移量不同(分别是 0x11E bytes0xEE bytes),这也是一个 Windows 操作系统函数,用于检索与进程相关的应用程序容器名称,由 Windows 系统的各个部分和其他需要知道应用程序容器名称的程序调用,关于 Windows 容器的介绍,可以查看 Microsoft Windows 和容器

    第 18~19 行,分别用十六进制及 ASCII 字符显示了泄漏内存块中信息,内存初始化时赋的初始值为 0x55345678,计算机默认使用小端字节序,因此在内存中各字节的十六进制初始值分别为 78 56 34 55,转化为十进制数,0x780x560x340x55 分别为 120、86、52、85,查找 ASCII 码表,可得这四个字节对应的 ASCII 字符分别为 xV4U,与 VLD 的输出完全一致。VLD 在显示内存内容时,每行最多显示 16 个字节,但这次只泄漏了 4 个字节,因此在显示上第 19 行中间有 12 个字节的空白位,行尾有 12 个占位点(.... ........)。

    第 22 行,表示本次运行检测到 1 处内存泄漏,泄漏的总大小为 40 bytes,这里面不光包含用于 int 存储的 4 bytes,还包含用于管理追踪这块内存的另外 36 bytes,因此,虽然代码只请求了 4 bytes 的内存,但程序实际上为此分配了 40 bytes 的内存。可以查看以下资料。(当使用 32 bit 的 Debug 编译器时,这块管理内存的大小为 36bytes,当使用 64 bit 的 Debug 编译器时,大小变为 52bytes。差别产生的原因是 _CrtMemBlockHeader 结构体中含有指针类型成员,而指针类型在不同位数的环境下内存量宽度是不一样的。)

    第 23 行,表示整个检测过程中全部泄漏块总大小的最大值(即检测过程中 \(max{\{上一行括号内的值\}}\)),为 40 bytes,原因看前一条,有兴趣的可以阅读 VLD 源码。

    第 24 行,表示本次运行中堆上分配内存的总大小,为 40 bytes,即代码申请 int4 bytes,和管理块占用的 36 bytes

    第 25 行,表示 VLD 正常退出。

    在程序的第 6 行加个断点,按 F5 进入调试状态,结果如下,调用堆栈中各函数的名称、所属文件、所在行号、调用顺序都和 VLD 一致。

    Oh Shit!-图片走丢了-打个广告-欢迎来博客园关注“木三百川”

    3. 有一处内存泄漏时的输出报告(int 数组型)

    写一个有一处内存泄漏的程序,如下:

    #include <QCoreApplication>
    #include "vld.h"
    
    void testFun()
    {
        int *ptr = new int[10];
        ptr[0] = 0x64568932;
        printf("ptr = %08x", ptr);
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        testFun();
    
        return a.exec();
    }
    

    程序运行时,在标准输出窗会输出以下结果:

    ptr = 00ab4340
    

    程序运行结束后,检测到了内存泄漏,VLD 会输出以下报告(本例中出现一处内存泄漏),第 1~3 行显示 VLD 运行状态,第 4~23 行显示泄漏内存的详细信息,第 24~26 行总结此次泄漏情况,第 27 行显示 VLD 退出状态。

    Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.ini
    Visual Leak Detector Version 2.5.1 installed.
    WARNING: Visual Leak Detector detected memory leaks!
    ---------- Block 1 at 0x00AB4340: 40 bytes ----------
      Leak Hash: 0x39CB72AB, Count: 1, Total 40 bytes
      Call Stack (TID 29256):
        ucrtbased.dll!malloc()
        f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): testVLD.exe!operator new[]() + 0x9 bytes
        e:\cw
    首页 上一页 1 2 3 下一页 尾页 2/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇Linux环境中使用C++ JsonCpp库 下一篇【Visual Leak Detector】QT 中 V..

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目