windows下的内存泄露检测工具VLD使用

1.写在前面

C/C++ 开发常常面临内存泄露问题的困扰,为了保证代码的交付质量,内存泄露检测是十分重要且必要的。本文以实际项目作为切入点,介绍windows下的一个内存泄露检测工具的用法,作为备忘/互相交流之用,不足之处还请批评指正。

2.VLD简介

VLD是一款可用于windows平台C/C++免费内存泄漏检查工具,相对使用比较方便,可以作为开发检测的一种手段,用以提高代码质量,它有如下优点
1)能够得到内存泄漏位置的调用堆栈,并且可以显示泄露位置所在的文件名及行号;
2)能够获得泄漏内存的完整数据;
3)用户可以自定义设置内存泄漏报告的级别;
4)以动态库的形式提供,源码需要做少许改动
5)源代码使用GNU许可发布,并有详细的文档及其注释。
VLD简单易用,只需要在源码中做少许改动,程序执行完毕后就能够输出内存泄露报告,下面就结合实际的代码来介绍该工具的使用。

3.VLD配置

首先可以从 https://kinddragon.github.io/vld/ 下载VLD进行安装,安装完毕后在安装目录下会看到如下几个文件夹:
在这里插入图片描述
这里可以根据自己的程序运行平台选择对应的库,本文选择 vld_x86.dll、dbghelp.dll、vld.lib、vld.ini、Microsoft.DTfW.DHL.manifest 这几个文件作为本次实例检测运行的依赖。

3.1.源码中添加头文件

在需要进行内存泄露检测的源码中首行添加#incude<vld.h>,VS工程中属性中 Linker->Input->Additional Dependencies,添加vld.lib,如下图所示:
在这里插入图片描述
在debug模式下将SDK编译出dll库(注:VLD默认在debug模式下开启, 本例中检测SDK内存泄露位置,事先已经在源码中添加了一行内存分配的代码,图中第51行,但是未进行释放,如下图所示)
在这里插入图片描述

3.2.配置VLD

将 vld_x86.dll、dbghelp.dll、vld.ini、Microsoft.DTfW.DHL.manifest 这几个文件一并拷贝到可执行文件的目录下,打开vld.ini文件,找到如下两个配置项:
ReportFile =.\memory_leak_report.txt //配置内存泄露检测报告文件的输出位置及检测报告文件名
ReportTo = both

配置完成后保存,再次检查一下可执行文件目录下的文件,同时将之前编译出的debug版本的dll库拷贝到可执行目录下,运行可执行文件,程序执行完并关闭后,此时会看到根目录下生成一个内存泄露检测报告:memory_leak_report.txt
在这里插入图片描述

3.3.内存泄漏检测报告解读

memory_leak_report.txt中的内容如下:
Visual Leak Detector Version 2.5.1 installed.
Outputting the report to the debugger and to D:\WorkSpace\SecureCard\branch\v1.0.1\sample\MFC_Demo\Release\memory_leak_report.txt
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x00FC6358: 512 bytes ----------
Leak Hash: 0x5537415D, Count: 1, Total 512 bytes
Call Stack (TID 4216):
ucrtbased.dll!malloc()
d:\workspace\securecard\branch\v1.0.1\src\source\secureukey.cpp (51): SecureCard.dll!SKF_EnumDev() + 0xD bytes
d:\workspace\securecard\branch\v1.0.1\sample\mfc_demo\sdcryptostortool\secureukeytooldlg.cpp (223): SecureUKeyDemo.exe!CSDCryptoStorToolDlg::OnBnClickedBtnRefresh()
d:\workspace\securecard\branch\v1.0.1\sample\mfc_demo\sdcryptostortool\secureukeytooldlg.cpp (138): SecureUKeyDemo.exe!CSDCryptoStorToolDlg::OnInitDialog()
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp (28): SecureUKeyDemo.exe!AfxDlgProc() + 0x4 bytes
USER32.dll!AddClipboardFormatListener() + 0x4B bytes
USER32.dll!EnumChildWindows() + 0xCDE bytes
USER32.dll!EnumChildWindows() + 0x3D0 bytes
USER32.dll!wvsprintfA() + 0x2D5 bytes
USER32.dll!AddClipboardFormatListener() + 0x4B bytes
USER32.dll!GetClassLongW() + 0x7AA bytes
USER32.dll!GetSystemMetricsForDpi() + 0x1747 bytes
USER32.dll!CallWindowProcA() + 0x1B bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp (1106): SecureUKeyDemo.exe!CWnd::DefWindowProcA() + 0x7 bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp (297): SecureUKeyDemo.exe!CWnd::Default() + 0x4 bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp (2093): SecureUKeyDemo.exe!CWnd::WindowProc() + 0x4 bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp (268): SecureUKeyDemo.exe!AfxCallWndProc()
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp (417): SecureUKeyDemo.exe!AfxWndProc() + 0x10 bytes
USER32.dll!AddClipboardFormatListener() + 0x4B bytes
USER32.dll!GetClassLongW() + 0x7AA bytes
USER32.dll!GetClassLongW() + 0x3AA bytes
USER32.dll!CallNextHookEx() + 0x19F bytes
ntdll.dll!KiUserCallbackDispatcher() + 0x4D bytes
USER32.dll!RegisterClassExW() + 0xB96 bytes
USER32.dll!CreateDialogIndirectParamAorW() + 0x35 bytes
USER32.dll!CreateDialogIndirectParamA() + 0x1B bytes
f:\dd\externalapis\windows\8.1\sdk\inc\winuser.inl (547): SecureUKeyDemo.exe!IsolationAwareCreateDialogIndirectParamA() + 0x15 bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp (363): SecureUKeyDemo.exe!CWnd::CreateDlgIndirect()
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp (460): SecureUKeyDemo.exe!CWnd::CreateRunDlgIndirect() + 0x10 bytes
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp (633): SecureUKeyDemo.exe!CDialog::DoModal() + 0x14 bytes
d:\workspace\securecard\branch\v1.0.1\sample\mfc_demo\sdcryptostortool\secureukeytool.cpp (78): SecureUKeyDemo.exe!CSDCryptoStorToolApp::InitInstance()
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winmain.cpp (37): SecureUKeyDemo.exe!AfxWinMain() + 0x4 bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (253): SecureUKeyDemo.exe!__scrt_common_main_seh() + 0x1A bytes
KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes
ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD … …

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

从上述报告内容中可以看到,工具检测到dll库中的一处内存泄露,泄露位置位于 secureukey.cpp文件中第 51行 ,在函数SKF_EnumDev()内部,存在512 bytes内存泄露,正是我们预先分配未释放的位置:
Leak Hash: 0x5537415D, Count: 1, Total 512 bytes
d:\workspace\securecard\branch\v1.0.1\src\source\secureukey.cpp (51): SecureCard.dll!SKF_EnumDev() + 0xD bytes

报告中还列出了更为详细的堆栈信息,便于对代码进行定位和分析,这里就不再进行详细的说明,有兴趣的话可以网上搜索更多信息进行学习。
当然用户也可以在Visual studio中配置vld,相关信息请自行搜索,此处不作介绍。

4.结束语

windows下内存泄露检测工具有很多,本文只列出VLD的使用,想了解更多内存泄露检测工具的使用,请自行搜索学习。作为C/C++开发,掌握简单的内存泄漏分析手段可以说是十分有必要的,掌握方法的同时也能加深对内存相关知识的理解。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值