Visual Leak Detector配置项 StackWalkMethod

Posted 木三百川

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Visual Leak Detector配置项 StackWalkMethod相关的知识,希望对你有一定的参考价值。

使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 StackWalkMethod 的使用方法。

说明

使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 StackWalkMethod 的使用方法。同系列文章目录可见 《内存泄漏检测工具》目录


1. 配置文件使用说明

在程序中通过 #include "vld.h" 的方式检测内存泄漏时,VLD 首先会尝试在程序的生成目录下读取 vld.ini 文件,若未读取成功,则会尝试在 VLD 的安装目录下读取 vld.ini 文件,若仍未读取成功,则会使用内置的默认配置,内置的默认配置如果不动源码是无法更改的,因此通过修改相应目录下的 vld.ini 文件来定制 VLD 功能是最好的选择。当配置参数等号右边为空,或者给配置了不合法值时,在使用过程中会被程序重置到默认值。

2. 设置调用堆栈的跟踪方法

参数名StackWalkMethod

有效赋值fastsafe

默认值fast

功能说明:设置调用堆栈的跟踪方法。fast 方法速度快但跟踪的调用堆栈可能不完整,会漏掉一些;safe 方法能更可靠地获得完整的调用堆栈,但速度会慢很多,有可能导致被检测的程序性能出现显著下降,这时为了减少检测时间,可以将配置项 MaxTraceFrames 设置得小一些。

2.1 测试代码

#include <QCoreApplication>
#include <QDebug>
#include <QTime>
#include "vld.h"

void testFun(int i)

    if (i > 1)
    
        testFun(i-1);
    else
    
        int *ptr = new int(i);
        printf("ptr = %08x, *ptr = %08x.\\n", ptr, *ptr);
    


int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);

    QTime timedebuge;

    timedebuge.start();
    testFun(30);
    qDebug() << "Elapsed Time: " << timedebuge.elapsed() << "ms";

    return a.exec();

测试环境:QT 5.9.2MSVC 2015 32bitDebug 模式,VLD 版本为 2.5.1,VLD 配置文件只对该参数做修改,测试工程所在路径为:E:\\Cworkspace\\Qt 5.9\\QtDemo\\testVLD

2.2 StackWalkMethod = fast 时的输出

标准输出窗显示:

ptr = 006e90c0, *ptr = 00000001.
Elapsed Time:  1 ms

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 0x006E90C0: 4 bytes ----------
  Leak Hash: 0x03496A17, Count: 1, Total 4 bytes
  Call Stack (TID 11760):
    ucrtbased.dll!malloc()
    f:\\dd\\vctools\\crt\\vcstartup\\src\\heap\\new_scalar.cpp (19): testVLD.exe!operator new() + 0x9 bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (13): testVLD.exe!testFun() + 0x7 bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (25): testVLD.exe!main() + 0x7 bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (74): testVLD.exe!invoke_main() + 0x1B bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (264): testVLD.exe!__scrt_common_main_seh() + 0x5 bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (309): testVLD.exe!__scrt_common_main()
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_main.cpp (17): testVLD.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes
    ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes
    ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes
  Data:
    01 00 00 00                                                  ........ ........


Visual Leak Detector detected 1 memory leak (40 bytes).
Largest number used: 40 bytes.
Total allocations: 40 bytes.
Visual Leak Detector is now exiting.

2.3 StackWalkMethod = safe 时的输出

标准输出窗显示:

ptr = 012aa388, *ptr = 00000001.
Elapsed Time:  18 ms

VLD 输出报告:

Visual Leak Detector read settings from: D:\\Program Files (x86)\\Visual Leak Detector\\vld.ini
Visual Leak Detector Version 2.5.1 installed.
    Using the "safe" (but slow) stack walking method.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x012AA388: 4 bytes ----------
  Leak Hash: 0x9281F97B, Count: 1, Total 4 bytes
  Call Stack (TID 30696):
    ucrtbased.dll!malloc()
    f:\\dd\\vctools\\crt\\vcstartup\\src\\heap\\new_scalar.cpp (19): testVLD.exe!operator new() + 0x9 bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (13): testVLD.exe!testFun() + 0x7 bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (10): testVLD.exe!testFun() + 0xC bytes
    e:\\cworkspace\\qt 5.9\\qtdemo\\testvld\\main.cpp (25): testVLD.exe!main() + 0x7 bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (74): testVLD.exe!invoke_main() + 0x1B bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (264): testVLD.exe!__scrt_common_main_seh() + 0x5 bytes
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_common.inl (309): testVLD.exe!__scrt_common_main()
    f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe_main.cpp (17): testVLD.exe!mainCRTStartup()
    KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes
    ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes
    ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes
  Data:
    01 00 00 00                                                  ........ ........


Visual Leak Detector detected 1 memory leak (40 bytes).
Largest number used: 40 bytes.
Total allocations: 40 bytes.
Visual Leak Detector is now exiting.

2.4 输出结果对比

  • StackWalkMethod = fast 时,耗时 1 ms,此次检测输出了全部的调用堆栈。
  • StackWalkMethod = safe 时,耗时 18 ms,也检测输出了全部的调用堆栈。

以上是关于Visual Leak Detector配置项 StackWalkMethod的主要内容,如果未能解决你的问题,请参考以下文章

Visual Leak Detector配置项 TraceInternalFrames

Visual Leak Detector配置项 SkipCrtStartupLeaks

Visual Leak Detector配置项 ReportEncoding

Visual Leak Detector配置项 SkipHeapFreeLeaks

Visual Leak Detector配置项 MaxTraceFrames

Visual Leak Detector配置项 StartDisabled