說明 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。 1. 使用前的準備 參考本人另一篇博客 安裝 Visual Leak Detector 下載 vld-2.5.1-setup.exe 並按步驟安裝 VLD。這一種使用方式的特點是,在一臺電腦上安裝完成後,將 VLD 安裝目錄下的 lib ...
說明
使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。
目錄1. 使用前的準備
參考本人另一篇博客 安裝 Visual Leak Detector 下載 vld-2.5.1-setup.exe 並按步驟安裝 VLD。這一種使用方式的特點是,在一臺電腦上安裝完成後,將 VLD 安裝目錄下的 lib 庫及 include 文件拷貝到項目目錄中,在項目 pro
文件中指明庫及頭文件的路徑,並將 vld.ini
文件和 VLD 安裝目錄 bin 文件夾下的全部文件拷貝到項目生成目錄下,最後在 mian.cpp
文件中 #include "vld.h"
。優點是,當把項目拷貝到別的電腦上編譯運行時,該電腦無需安裝 VLD,也不需要更改任何代碼。
2. 在 QT 中使用 VLD
我的 VLD 安裝目錄為 D:\Program Files (x86)\Visual Leak Detector
。安裝完成後,文件列表如下:
需要用到的是 bin
、include
和 lib
三個文件夾,以及 vld.ini
文件。下文示例項目所在路徑為 E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD
,項目路徑下的文件列表如下:
2.1 複製 lib 庫及頭文件
拷貝 include
文件夾中的 vld.h
及 vld_def.h
到項目路徑下,拷貝整個 lib
文件夾到項目路徑下,這兩步拷貝完成後,項目路徑下的文件列表如下:
2.2 在項目 .pro 文件中指明路徑
在項目對應的 pro
文件中添加 VLD 的頭文件和 lib
庫,pro
文件中添加如下代碼:
HEADERS += \
vld.h \
vld_def.h
win32{
CONFIG(debug, debug | release) {
contains(QT_ARCH, x86_64){
LIBS += -L$$PWD/lib/Win64 -lvld
}else{
LIBS += -L$$PWD/lib/Win32 -lvld
}
}
}
2.3 配置 bin 文件夾下的依賴庫
拷貝 bin\Win32
文件夾中的四個文件 dbghelp.dll
、Microsoft.DTfW.DHL.manifest
、vld_x86.dll
和 vld_x86.pdb
到 32 位 MSVC 在 Debug 模式下的生成目錄中,若不使用 DESTDIR
指令,但勾選 Shadow build
,預設的生成路徑為 E:\Cworkspace\Qt 5.9.0\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_32bit-Debug\debug
,拷貝結果如下:
64 位的做類似操作,拷貝 bin\Win64
文件夾中的四個文件 dbghelp.dll
、Microsoft.DTfW.DHL.manifest
、vld_x64.dll
和 vld_x64.pdb
到 64 位 MSVC 在 Debug 模式下的生成目錄中,若不使用 DESTDIR
指令,但勾選 Shadow build
,預設的生成路徑為 E:\Cworkspace\Qt 5.9.0\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_64bit-Debug\debug
,拷貝結果如下:
更佳的做法是使用 DESTDIR
指令,實現 32 位、64 位在指定路徑下生成 exe
,這樣可以將 exe
直接生成在對應的 Win32
和 Win64
路徑下,而不需要將上述 4 個文件分別拷貝到對應的 debug
目錄。為實現這種效果,首先將整個 bin
文件拷貝到項目路徑下,拷貝完成後,項目路徑下的文件列表如下:
在項目對應的 pro
文件中使用 DESTDIR
指令設置生成路徑,添加如下代碼:
contains(QT_ARCH, x86_64){
DESTDIR = $$PWD/bin/Win64
}else{
DESTDIR = $$PWD/bin/Win32
}
同時,為將 release
和 debug
兩種版本區分出來,不至於在同一個文件夾中引起混亂,在 pro
文件中額為添加如下代碼:
TARGET_NAME = testVLD
CONFIG(debug, debug|release) {
TARGET_NAME = $${TARGET_NAME}-d
}
TARGET = $${TARGET_NAME}
這樣設置之後,生成的 debug
版結果將比 release
版結果多一個 -d
尾碼,便於區分。
2.4 複製 vld.ini 文件
vld.ini
是 VLD 工具的配置文件,可以修改 vld.ini
內容以定製記憶體泄漏檢測報告。沒有該文件其實也能正常運行,但為了後續可定製,最好還是將 vld.ini
拷貝到生成目錄下。比如在上一步中的 E:\Cworkspace\Qt 5.9.0\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_32bit-Debug\debug
及 E:\Cworkspace\Qt 5.9.0\QtDemo\build-testVLD-Desktop_Qt_5_9_2_MSVC2015_64bit-Debug\debug
,若在上一步中使用了 DESTDIR
指令,則生成目錄變為 E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD\bin\Win32
及 E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD\bin\Win64
。
2.5 在 main.cpp 文件中添加頭文件
在項目的 main.cpp
文件中,添加頭文件:
#include "vld.h"
選擇 MSVC 32bit 或者 MSVC 64bit 編譯器,選擇 Debug
模式,編譯運行,就可以正常使用了。
2.6 無記憶體泄漏時的輸出報告
程式運行結束後,若沒有檢測到記憶體泄漏,VLD 會輸出以下 4 行報告:
Visual Leak Detector read settings from: E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD\bin\Win32\vld.ini
Visual Leak Detector Version 2.5.1 installed.
No memory leaks detected.
Visual Leak Detector is now exiting.
需要註意的是,此時讀取的配置文件 vld.ini
已經不是 VLD 安裝路徑下的那個了,從第一行可以看到具體路徑。使用 64 位 MSVC 時的輸出如下:
Visual Leak Detector read settings from: E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD\bin\Win64\vld.ini
Visual Leak Detector Version 2.5.1 installed.
No memory leaks detected.
Visual Leak Detector is now exiting.
因為使用了 DESTDIR
指令, 32 位和 64 位會在所指定的路徑下生成,符合預期結果。
3. 無法正常使用的可能原因
按前述步驟進行配置後,就可以卸載已經安裝的 VLD 工具了,到 VLD 安裝路徑下,雙擊 unins000.exe
,彈窗點擊“是(Y)” 按鈕卸載 VLD,重新編譯運行程式,仍可正常使用。當把項目拷貝到別的電腦上編譯運行時,新電腦環境無需安裝 VLD,也不需要更改任何代碼。若無法正常使用,考慮以下可能的原因。
- 檢查編譯器版本,VLD 無法在 minGW 下使用,只能使用 MSVC 編譯器。
- 檢查是否是 Debug 模式,VLD 無法直接在 Release 模式下使用。
- 檢查文件的位數是否正確,32 bit /64 bit 不能混用。
- 清除上一次的編譯文件,重新編譯運行一下。
- 若路徑中存在空格,添加庫時一定要使用
$$quote()
將路徑括起來,否則路徑解析不正確。 - 檢查生成目錄下是否包含有 VLD 的 4 個依賴文件,32 位為
dbghelp.dll
、Microsoft.DTfW.DHL.manifest
、vld_x86.dll
和vld_x86.pdb
,64 位為dbghelp.dll
、Microsoft.DTfW.DHL.manifest
、vld_x64.dll
和vld_x64.pdb
。
4. 示例源碼
4.1 工程 .pro 文件
# testVLD.pro
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += main.cpp
HEADERS += \
vld.h \
vld_def.h
win32{
CONFIG(debug, debug | release) {
contains(QT_ARCH, x86_64){
LIBS += -L$$PWD/lib/Win64 -lvld
}else{
LIBS += -L$$PWD/lib/Win32 -lvld
}
}
}
contains(QT_ARCH, x86_64){
DESTDIR = $$PWD/bin/Win64
}else{
DESTDIR = $$PWD/bin/Win32
}
TARGET_NAME = testVLD
CONFIG(debug, debug|release) {
TARGET_NAME = $${TARGET_NAME}-d
}
TARGET = $${TARGET_NAME}
4.2 主函數 main.cpp 文件
// mian.cpp
#include <QCoreApplication>
#include "vld.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}
4.3 示例工程目錄結構
工程目錄結構如下:
E:\Cworkspace\Qt 5.9.0\QtDemo\testVLD
│ main.cpp
│ testVLD.pro
│ testVLD.pro.user
│ vld.h
│ vld_def.h
│
├─bin
│ ├─Win32
│ │ dbghelp.dll
│ │ Microsoft.DTfW.DHL.manifest
│ │ testVLD-d.exe
│ │ testVLD-d.ilk
│ │ testVLD-d.pdb
│ │ testVLD.exe
│ │ testVLD.pdb
│ │ vld.ini
│ │ vld_x86.dll
│ │ vld_x86.pdb
│ │
│ └─Win64
│ dbghelp.dll
│ Microsoft.DTfW.DHL.manifest
│ testVLD-d.exe
│ testVLD-d.ilk
│ testVLD-d.pdb
│ testVLD.exe
│ testVLD.pdb
│ vld.ini
│ vld_x64.dll
│ vld_x64.pdb
│
└─lib
├─Win32
│ vld.lib
│
└─Win64
vld.lib
本文作者:木三百川
本文鏈接:https://www.cnblogs.com/young520/p/17242116.html
版權聲明:本文系博主原創文章,著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請附上出處鏈接。遵循 署名-非商業性使用-相同方式共用 4.0 國際版 (CC BY-NC-SA 4.0) 版權協議。