天天看點

VC++記憶體洩漏檢測方法(3):Visual Leak Detector(VLD記憶體洩漏檢測工具)支援VS2017

Visual Leak Detector(以下簡稱:VLD) 是一個著名的 C/C++ 程式記憶體洩漏檢測插件,而且還是免費且開源的。現在最新版本的 VLD v2.5.1 官方并不支援 Visual Studio 2017,隻支援 Visual Studio 2008 到 Visual Studio 2015。 https://kinddragon.github.io/vld/ https://github.com/KindDragon/vld https://github.com/KindDragon/vld/releases -- 安裝包下載下傳 https://www.cnblogs.com/starfire86/p/5594707.html -- 使用說明 https://blog.csdn.net/chaipp0607/article/details/79182471

-- 記憶體洩漏工具Visual Leak Detector2.5.1安裝與使用

★編譯源碼

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

筆者使用的是VS2017環境,是以從官網下載下傳

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 <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庫請下載下傳

https://download.csdn.net/download/libaineu2004/12118513

★VLD請謹慎使用,有時候會誤報。建議還是掌握windbg調試方法:

VC++記憶體洩漏檢測方法(5):使用強大的Windbg工具,重點是Symbols Path設定

---參考文獻---

其他記憶體檢測工具:MallocDebug,purify, Valgrind,Kcachegrind,dmalloc,NuMega,BoundsChecker,ParaSoft ,Insure++等等。

Visual Leak Detector on Visual C++ 2017

繼續閱讀