VC++内存泄漏检测方法(3):Visual Leak Detector(VLD内存泄漏检测工具)支持VS2017

莘俊能
2023-12-01

Visual Leak Detector(以下简称:VLD) 是一个著名的 C/C++ 程序内存泄漏检测插件,而且还是免费且开源的。现在最新版本的 VLD v2.5.1 官方并不支持 Visual Studio 2017,只支持 Visual Studio 2008 到 Visual Studio 2015。

Visual Leak Detector | Enhanced Memory Leak Detection for Visual C++

https://github.com/KindDragon/vld

https://github.com/KindDragon/vld/releases -- 安装包下载

VLD(Visual LeakDetector)内存泄露库的使用 - DreamFaquir - 博客园 -- 使用说明

VS内存泄漏工具Visual Leak Detector2.5.1安装与使用_zxucver的博客-CSDN博客 -- 内存泄漏工具Visual Leak Detector2.5.1安装与使用

★编译源码

最新版本的 VLD v2.5.1 官方并不支持 Visual Studio 2017,只支持 Visual Studio 2008 到 Visual Studio 2015。

笔者使用的是VS2017环境,所以从官网下载https://github.com/KindDragon/vld/releases v2.5.1源码,自己编译,不使用官网的vld-2.5.1-setup.exe

1、VS2017打开工程vld_vs14.sln

2、编译之前,把所有子项目的平台工具集选择“Visual Studio 2015 (v140)

★注意事项:

*0、(非必须)源码修改\vld-2.5.1\src\utility.cpp,第721行开始,把原来的wcstombs_s函数替换为WideCharToMultiByte。

因为wcstombs_s不支持中文字符,需要设置Locale参数,setlocale(LC_ALL,"chs");用起来啰嗦还容易出错,故而替换之。

const size_t MAXMESSAGELENGTH = 5119;
size_t  count = 0;
CHAR    messagea [MAXMESSAGELENGTH + 1];

//firecat add
// wcstombs_s requires locale to be already set up correctly, but it might not be correct on vld init step. So use WideCharToMultiByte instead
//把Unicode文本转换为ANSI
count = WideCharToMultiByte(CP_ACP, 0, messagew, -1, NULL, 0, NULL, NULL);
memset(&messagea, 0, MAXMESSAGELENGTH + 1);
WideCharToMultiByte(CP_ACP, 0, messagew, -1, messagea, count, NULL, NULL);
/*
if (wcstombs_s(&count, messagea, MAXMESSAGELENGTH + 1, messagew, _TRUNCATE) != 0) {
// Failed to convert the Unicode message to ASCII.
assert(FALSE);
return;
}*/

messagea[MAXMESSAGELENGTH] = '\0';

1、难道VLD真的不支持 Visual Studio 2017 吗?其实并非如此。以下是解决办法:

我的 Visual Studio 2017 的安装路径为:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise

从以下目录中:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\Cpp
拷贝(覆盖)\dbghelp.dll 到 <项目文件夹>\Visual_Leak_Detector\bin\Win32
拷贝(覆盖)\x64\dbghelp.dll 到 <项目文件夹>\Visual_Leak_Detector\bin\x64

再以 Debug 模式运行该程序,在 output 窗口中可以看到详细的内存泄漏信息。

2、VS2017调试程序时,除了使用VS2017安装路径自带的dbghelp.dll文件,还需要Microsoft.DTfW.DHL.manifest文件,该文件在VLD源码包,路径是\vld-2.5.1\setup\dbghelp\x86和x64文件夹。Microsoft.DTfW.DHL.manifest文件很重要,没有它可不行,否则调试或运行时会报错。

3、接下来需要将VLD加入到自己的代码中。方法很简单,只要在包含入口函数的.cpp文件中包含vld.h就可以。如果这个cpp文件中包含了stdafx.h,则将包含vld.h的语句放在stdafx.h的包含语句之后,否则放在最前面。

'#include <vld.h>' should appear before '#include <afxwin.h>' in file stdafx.h

断点调试程序时,把文件vld.ini放在和.vcxproj工程文件一起的路径下。

发布程序时,把文件vld.ini放在和应用程序exe文件一起的路径下。

4、如何在Release版本下使用VLD?

请参考https://www.jianshu.com/p/1fb05cfdc76d,方法有2种:

方法(1)打开安装路径下的vld.ini文件,将ReportTo设置为both,为了在非bebug下也能看到检测结果

方法(2)宏定义:#define VLD_FORCE_ENABLE

; Sets the report file destination, if reporting to file is enabled. A relative

; path may be specified and is considered relative to the process' working

; directory.

;

;   Valid Values: Any valid path and filename.

;   Default: .\memory_leak_report.txt

;

ReportFile =  .\memory_leak_report.txt

; Sets the report destination to either a file, the debugger, or both. If

; reporting to file is enabled, the report is sent to the file specified by the

; ReportFile option.

;

;   Valid Values: debugger, file, both

;   Default: debugger

;

ReportTo = both

5、包含顺序

(1)对于非MFC工程,如有有 #include "stdafx.h" 的话,一定要把 "vld.h" 放在 stdafx.h之后包含。

#include "stdafx.h"

#include <vld.h>

(2)对于MFC工程,包含vid.h需要在包含afxwin.h之前

#include <vld.h>

#include <afxwin.h>

6、该工具只能检测堆(Heap)上分配的内存泄漏,不能检测VirtualAlloc(Private Data)申请的内存泄漏。

7、使用总结和举例:

附加包含目录添加C:\Program Files (x86)\Visual Leak Detector\include
附加库目录添加C:\Program Files (x86)\Visual Leak Detector\lib\Win64
附加依赖项添加vld.lib
支持release的方法1:将vld.ini中的ReportTo修改为both

方法2:宏定义#define VLD_FORCE_ENABLE

#include "stdafx.h"
#define VLD_FORCE_ENABLE //VLD_FORCE_ENABLE宏定义是为了Release版本也能生成报告
#include <vld.h>

int _tmain(int argc, _TCHAR* argv[])
{
    VLDGlobalEnable();
    VLDReportLeaks();
    char *strTest = new char[1024];
    sprintf(strTest,"111111");
    printf(strTest);
    VLDGlobalDisable();
    return 0;
}

MFC:

在stdafx.h文件最前面写:

#define VLD_FORCE_ENABLE//让release支持vld

#include <vld.h>//VLD要放在最前面

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN

#define VLD_FORCE_ENABLE//让release支持vld
#include <vld.h>//VLD要放在afxwin.h前面

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

★我个人实现的VS2017项目源码和dll库请下载

VisualLeakDetector(VLD内存泄漏检测工具)支持VS2017_vs内存泄漏-C++代码类资源-CSDN下载

★VLD请谨慎使用,有时候会误报。建议还是掌握windbg调试方法:

VC++内存泄漏检测方法(5):使用强大的Windbg工具,重点是Symbols Path设置


---参考文献---

其他内存检测工具:MallocDebug,purify, Valgrind,Kcachegrind,dmalloc,NuMega,BoundsChecker,ParaSoft ,Insure++等等。

Visual Leak Detector on Visual C++ 2017

 类似资料: