说明
使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 ReportEncoding 的使用方法。 同系列文章目录可见 《内存泄漏检测工具》目录
1. 配置文件使用说明
在程序中通过 #include "vld.h"
的方式检测内存泄漏时,VLD 首先会尝试在程序的生成目录下读取 vld.ini
文件,若未读取成功,则会尝试在 VLD 的安装目录下读取 vld.ini
文件,若仍未读取成功,则会使用内置的默认配置,内置的默认配置如果不动源码是无法更改的,因此通过修改相应目录下的 vld.ini
文件来定制 VLD 功能是最好的选择。当配置参数等号右边为空,或者给配置了不合法值时,在使用过程中会被程序重置到默认值。
2. 设置输出报告的编码格式
参数名:ReportEncoding
。
有效赋值:ascii
,unicode
。
默认值:ascii
。
功能说明:设置输出报告的编码格式。默认是 ascii
编码,若改为 unicode
编码,控制台输出报告的同时会自动将报告输出到文本文件中(即使没有人为设置输出到文件)。由于调试器 Debugger
是不支持 unicode
字符的,所以这个配置只对显示的内存数据形式有影响,当泄露块中包含 unicode
字符时,这个配置的效果才能体现。若项目路径中含有 unicode
字符,ascii
编码时将无法显示调用堆栈信息,改为 unicode
有时候则能正常显示,详见 StackOverflow vld displays empty call stack。
2.1 测试代码
#include <QCoreApplication>
#include "vld.h"
void testFun()
{
QString str = QStringLiteral("汉字unicode");
char *ptr = new char[30]();
QByteArray Block = str.toLocal8Bit();
memcpy(ptr, Block.constData(), Block.size());
printf("ptr = %08x, *ptr = %s.\n", ptr, ptr);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
testFun();
return a.exec();
}
测试环境:QT 5.9.2,MSVC 2015 32bit,Debug 模式,VLD 版本为 2.5.1,VLD 配置文件只对该参数做修改,测试工程所在路径为:E:\Cworkspace\Qt 5.9\QtDemo\testVLD
。
2.2 ReportEncoding = ascii 时的输出
标准输出窗显示:
ptr = 0119aa60, *ptr = 汉字unicode.
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 0x0119AA60: 30 bytes ----------
Leak Hash: 0x7A25A79D, Count: 1, Total 30 bytes
Call Stack (TID 2596):
ucrtbased.dll!malloc()
f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): testVLD.exe!operator new[]() + 0x9 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (7): testVLD.exe!testFun() + 0x10 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (19): 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:
BA BA D7 D6 75 6E 69 63 6F 64 65 00 00 00 00 00 ....unic ode.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
Visual Leak Detector detected 1 memory leak (66 bytes).
Largest number used: 66 bytes.
Total allocations: 66 bytes.
Visual Leak Detector is now exiting.
2.3 ReportEncoding = unicode 时的输出
标准输出窗显示:
ptr = 0141bbe8, *ptr = 汉字unicode.
VLD 输出报告(控制台):
Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.ini
Visual Leak Detector Version 2.5.1 installed.
NOTE: Visual Leak Detector: Unicode-encoded reporting has been enabled, but the
debugger is the only selected report destination. The debugger cannot display
Unicode characters, so the report will also be sent to a file. If no file has
been specified, the default file name is ".\memory_leak_report.txt".
Generating a Unicode (UTF-16) encoded report.
Outputting the report to the debugger and to E:\Cworkspace\Qt 5.9\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_32bit-Debug\memory_leak_report.txt
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x0141BBE8: 30 bytes ----------
Leak Hash: 0x7A25A79D, Count: 1, Total 30 bytes
Call Stack (TID 20200):
ucrtbased.dll!malloc()
f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): testVLD.exe!operator new[]() + 0x9 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (7): testVLD.exe!testFun() + 0x10 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (19): 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:
BA BA D7 D6 75 6E 69 63 6F 64 65 00 00 00 00 00 ??湵捩摯e..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
Visual Leak Detector detected 1 memory leak (66 bytes).
Largest number used: 66 bytes.
Total allocations: 66 bytes.
Visual Leak Detector is now exiting.
VLD 输出报告(文件 memory_leak_report.txt
):
Visual Leak Detector Version 2.5.1 installed.
NOTE: Visual Leak Detector: Unicode-encoded reporting has been enabled, but the
debugger is the only selected report destination. The debugger cannot display
Unicode characters, so the report will also be sent to a file. If no file has
been specified, the default file name is ".\memory_leak_report.txt".
Generating a Unicode (UTF-16) encoded report.
Outputting the report to the debugger and to E:\Cworkspace\Qt 5.9\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_32bit-Debug\memory_leak_report.txt
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x0141BBE8: 30 bytes ----------
Leak Hash: 0x7A25A79D, Count: 1, Total 30 bytes
Call Stack (TID 20200):
ucrtbased.dll!malloc()
f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): testVLD.exe!operator new[]() + 0x9 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (7): testVLD.exe!testFun() + 0x10 bytes
e:\cworkspace\qt 5.9\qtdemo\testvld\main.cpp (19): 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:
BA BA D7 D6 75 6E 69 63 6F 64 65 00 00 00 00 00 몺훗湵捩摯e..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
Visual Leak Detector detected 1 memory leak (66 bytes).
Largest number used: 66 bytes.
Total allocations: 66 bytes.
Visual Leak Detector is now exiting.
2.4 输出结果对比
- 当
ReportEncoding = ascii
时,泄漏内存中的数据(汉字unicode
)只有unicode
显示正确,根据句点.
的个数可知一行显示 16 个ascii
字符。 - 当
ReportEncoding = unicode
时,报告会同时输出到生成目录下,默认文件名为memory_leak_report.txt
,根据句点.
的个数可知一行显示 8 个unicode
字符。奇怪的是,不论是在控制台中还是在文件中,泄漏内存中的汉字并没有按期望正常显示,只有最后一个字母e
显示正确,这一现象产生的原因还未找到。对比控制台输出与文件输出,文件输出少了第一行Visual Leak Detector read settings from: D:\Program Files (x86)\Visual Leak Detector\vld.ini
,泄漏数据的显示也略有差别,其他部分两者完全保持一致。
- ReportEncoding Detector Visual Leakreportencoding detector visual leak detector 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