近期想學習下VLD的實現,打算從最簡單的V1.0版本看起。以下是V1.0版本自己嘗試翻譯下,最新的2.x版本似乎強大了很多。
簡介
Visual C++提供了內置的內存檢測機制,但其充其量只滿足了最小定位需求。VLD工具定位為內置內存洩漏的替代,提供了如下特性:
相對於Purify和BoundsChecher工具其是免費的,而其他免費工具,往往需要入侵式代碼、有嚴格的使用約束或者根本不可靠。VLD相對於其他免費工具的優點:
使用VLD
如果你需要同時檢查工程包含的DLL,見"在DLL中檢測",步驟:
VLD會自動在debug版本的程序中進行內存洩漏檢測,並在程序退出時自動在輸出窗口打印出洩漏報告。注意:當編譯的為Release版本的程序,VLD不會被鏈接到程序中。所以將vld.h的文件包含語句留在工程源代碼中是安全的。
配置選項
VLD有一些預編譯宏可以控制VLD的某些行為:
VLD_AGGREGATE_DUPLICATES 去除重復的內存洩漏信息。
VLD_MAX_TRACE_FRAMES 最大棧回溯深度;
VLD_MAX_DATA_DUMP 最大內存轉儲大小;
VLD_SELF_TEST 自我診斷,該特性總是激活的,每次運行VLD,VLD自身會故意洩漏21字節的內存,並填充字符串"Memory Leak Self-Test"。該特性用於確定VLD是否正在工作。
VLD_SHOW_USELESS_FRAMES 僅顯示有用的棧信息,heap和vld自身的棧默認不顯示;
VLD_START_DISABLED 禁止自使能,即手動啟動VLD檢測,這樣可能導致一些檢測失效。
VLD運行時
void VLDDisable(void); 禁用VLD;
void VLDEnable(void); 啟用VLD;
在DLL中檢測內存洩漏
檢測DLL中的內存洩漏有些特殊注意事項以保證VLD正常運行:VLD在每個進程應只被一個模塊鏈接;最佳建議是第一個被初始化的模塊;詳細情況如下:
隱式加載的DLL
隱式加載的DLL在應用程序main函數前就已經完成初始化。因此dll是第一個被初始化的模塊,而VLD應該被其鏈接。一般情況下exe程序會鏈接多個DLL,只要在第一個需要被檢查的模塊裡鏈接VLD即可。多個DLL的加載順序可以通過在調試器裡觀察得出。
顯式加載的DLL
顯示加載(LoadLibrary)的DLL初始化在exe程序初始化之後,此時,exe程序應該作為鏈接VLD的模塊;
靜態鏈接CRT的DLL
當DLL使用/ML或者/MT編譯器選項,會造成在一個進程中存在多個CRT實例。VLD的洩漏檢測不能跨越CRT邊界。一個VLD實例只能監視一個CRT實例的內存情況。如果要同時監視多個CRT實例,必須在每一個靜態鏈接CRT的模塊中都鏈接VLD;
已知的限制
VLD 不支持COM或其他和CRT堆無關的內存洩漏檢測。簡單的說:vld1.0版本只支持通過new或malloc開辟的內存的洩漏檢測;
VLD不支持V6.5版本的dbghelp.dll;
已編譯的VLD發行包和VS2005不兼容,如果需要支持請在VS2005下自行編譯;