说明
使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。
1. 使用方式
在 QT 中使用 VLD 的方法可以查看另外几篇博客:
本次测试使用的环境为:QT 5.9.2,Debug 模式,VLD 版本为 2.5.1,VLD 配置文件不做任何更改使用默认配置,测试工程所在路径为:E:\Cworkspace\Qt 5.9\QtDemo\testVLD
。
2. 测试代码
写一个有一处内存泄漏的程序,如下:
#include <QCoreApplication>
#include "vld.h"
void testFun()
{
int *ptr = new int(0x55345678);
printf("ptr = %08x, *ptr = %08x", ptr, *ptr);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
testFun();
return a.exec();
}
3. 使用 32 bit 编译器时的输出
使用 MSVC 2015 32bit 编译器,程序运行时,在标准输出窗会输出以下结果:
ptr = 0070a3d0, *ptr = 55345678
程序运行结束后,检测到了内存泄漏,VLD 会输出以下报告(本例中出现一处内存泄漏),第 1~3 行显示 VLD 运行状态,第 4~21 行显示泄漏内存的详细信息,第 22~24 行总结此次泄漏情况,第 25 行显示 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 0x0070A3D0: 4 bytes ----------
Leak Hash: 0xA7ED883D, Count: 1, Total 4 bytes
Call Stack (TID 20672):
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 (6): testVLD.exe!testFun() + 0x7 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main()
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:
78 56 34 55 xV4U.... ........
Visual Leak Detector detected 1 memory leak (40 bytes).
Largest number used: 40 bytes.
Total allocations: 40 bytes.
Visual Leak Detector is now exiting.
4. 使用 64 bit 编译器时的输出
使用 MSVC 2015 64bit 编译器,程序运行时,在标准输出窗会输出以下结果:
ptr = 25a42da0, *ptr = 55345678
程序运行结束后,检测到了内存泄漏,VLD 会输出以下报告(本例中出现一处内存泄漏),第 1~3 行显示 VLD 运行状态,第 4~21 行显示泄漏内存的详细信息,第 22~24 行总结此次泄漏情况,第 25 行显示 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 0x0000000025A42DA0: 4 bytes ----------
Leak Hash: 0x92ED96C9, Count: 1, Total 4 bytes
Call Stack (TID 16444):
ucrtbased.dll!malloc()
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): testVLD.exe!operator new() + 0xA bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (6): testVLD.exe!testFun() + 0xA bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (16): testVLD.exe!main()
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (75): testVLD.exe!invoke_main()
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() + 0x14 bytes
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
Data:
78 56 34 55 xV4U.... ........
Visual Leak Detector detected 1 memory leak (56 bytes).
Largest number used: 56 bytes.
Total allocations: 56 bytes.
Visual Leak Detector is now exiting.
5. 输出报告对比结果
使用不同位数的编译器时,输出报告的差异主要体现在以下几点:
- 地址的表示位数不同,32 bit 编译器使用 8 位十六进制数表示,64 bit 编译器使用 16 位十六进制数表示。体现在输出的第 4 行,分别为
0x0070A3D0
和0x0000000025A42DA0
。 - 程序启动时所调用的
Windows
操作系统函数不完全相同,32 bit 编译器调用了两次RtlGetAppContainerNamedObjectPath()
函数和一次BaseThreadInitThunk()
函数,64 bit 编译器只调用了一次RtlUserThreadStart()
函数和一次BaseThreadInitThunk()
函数,且它们调用BaseThreadInitThunk()
函数时泄漏指令的内存偏移量不同,32 bit 编译器是0x19 bytes
,而 64 bit 编译器是0x14 bytes
。 - 内存管理头的宽度不同,32 bit 编译器时是
36 bytes
,64 bit 编译器时是52 bytes
。体现在输出的倒数第二行,分别为Total allocations: 40 bytes
和Total allocations: 56 bytes
,将代码请求的内存大小4 bytes
加上各自管理头的内存大小,可以得到与输出一致的结果: \(4 + 36 = 40bytes\) 及 \(4 + 52 = 56bytes\)。
- Detector Visual Leak VLDdetector visual leak vld detector方式visual leak skipheapfreeleaks detector visual leak 源码detector visual leak detector visual leak 2015 skipcrtstartupleaks detector visual leak forceincludemodulesmd detector visual leak stackwalkmethod detector visual leak detector版本visual leak traceinternalframes detector visual leak