/*
最近工作常常遇見記憶體流失的問題,一般這樣的問題都夠嗆,在網上找到了一個工具-VLD.順便翻譯了一下他的部分文檔.
記憶體流失偵查工具(Visual Leak Detector 1.9d (Beta))
翻譯:xRoy
2008-02-14 ,CD.
關鍵字:記憶體流失,VLD.
*/
介紹:(未翻譯)
Visual C++ provides built-in memory leak detection, but its capabilities are minimal at best. This memory leak detector was created as a free alternative to the built-in memory leak detector provided with Visual C++. Here are some of Visual Leak Detector's
features, none of which exist in the built-in detector:
* Provides a complete stack trace for each leaked block, including source file and line number information when available.
* Detects most, if not all, types of in-process memory leaks including COM-based leaks, and pure Win32 heap-based leaks.
* Selected modules (DLLs or even the main EXE) can be excluded from leak detection.
* Provides complete data dumps (in hex and ASCII) of leaked blocks.
* Customizable memory leak report: can be saved to a file or sent to the debugger and can include a variable level of detail.
Other after-market leak detectors for Visual C++ are already available. But most of the really popular ones, like Purify and BoundsChecker, are very expensive. A few free alternatives exist, but they're often too intrusive, restrictive, or unreliable. Visual
Leak Detector is currently the only freely available memory leak detector for Visual C++ that provides all of the above professional-level features packaged neatly in an easy-to-use library.
Visual Leak Detector is licensed free of charge as a service to the Windows developer community. If you find it to be useful and would like to just say "Thanks!", or you think it stinks and would like to say "This thing sucks!", please feel free to drop
me a note. Or, if you'd prefer, you can contribute a small donation. Both are very appreciated.
使用:
要在你的工程中使用VLD,按照這些步驟:
1.在你的程式的C/C++源檔案中,至少有一個包含了vld.h.到底包含到哪一個源檔案中並不重要,同樣的,包含此標頭檔時的與其他包含語句的先後關係也並不重要,當然先行編譯標頭檔除外,它要放在最前面.
2.如果你的工程中有一個或者多個Dll,並且你希望在這些Dll中使用VLD,在每個DLL中,應該滿足條件'1';
3.編譯為DEBUG版本
注意:不用於早期版本的VLD,現在,它能允許在多個源檔案中被包含,也可以被包含進一個被多次包含的通用標頭檔中.不管有多少源檔案包含了VLD.H,只有一個VLD拷貝會被裝載到進程中.
無論什麼時候運行調試版本,VLD都將在你的程式中探測記憶體流失.當你在VC調試器下運行你的程式時,當你的程式存在記憶體流失的時候在調試器的輸出視窗將會顯示一個所有探測到的記憶體流失的報告(這個報告也可以是儲存到檔案的方式,參見設定檔中的ReportFile項). 在錯誤報表(應該指調試器中的)中雙擊某個源檔案的行號,可以在代碼編輯器中跳轉到源檔案中出錯的那一行上.
注意:當你編譯發行版本的程式時,VLD將不會被連結到你的可執行程式中,所以,在對於你做發行工作時,是可以安全的拋棄VLD的,這樣做不會對你的程式產生任何效能降低或者其他的開銷.
配置選項:
這裡有一些配置參數,控制著VLD的動作行為.這些配置參數被儲存在vld.ini中.預設的情況下,這個檔案應該在VLD的安裝目錄下.然而,這個設定檔也可以拷貝程式的工作目錄下,在這種情況下,偵錯工具的時候起作用的是工作目錄下的這個.
------------------------------------------------------------
AggregateDuplicates
一般的,VLD會詳細地顯示每一個記憶體流失塊.將這個選項設定為yes將會使得VLD讓所有泄漏聚集在一起,共用相同的大小和調用棧,並在報告中單一的輸出.只有第一個泄漏塊將會被詳述.其他的都不會被顯示.替代而來的是一個顯示總共泄漏的數字和與之匹配的的大小和調用棧.
----------------------------------------------------------
ForceIncludeModules
在某些罕見的情況下,可能有必要在泄漏偵測中包含某個模組,但是也許不可能包含vld.h到任何一個源檔案中去.在這樣情況下,這個操作可以使用強制VLD來包含這些模組到記憶體偵測中.列出這些模組(DLL)的名字使它們被強制包含到泄漏偵測中.如果你使用了這個選項,你應該把vld.lib連結到你的工程中.
注意:當絕對有必要時,才使用這個選項.在某些情況下,使用這個選項會導致不可預知的行為,包括泄漏報告失敗或者/和崩潰.最好是不要使用此選項,除非你確定你知道自己在做什麼.
----------------------------------------------------------
MaxDataDump
將測參數設定成一個整數來限制在記憶體流失轉儲中顯示的資料大小.當這個數值位元組數量的記憶體已經被轉儲後,就會停止轉儲.這適用於任何一個泄漏塊太大或者調試器的輸出視窗變得十分雜亂.設定此參數為0,表示不轉儲.
----------------------------------------------------------
MaxTraceFrames
在預設情況下,VLD將儘可能遠的跟蹤調用棧.在你的調試版程式中每個被跟蹤的幀被附加到額外的開銷中(既有CPU時間也有記憶體使用量).如果你想限制這些開銷,你可以定義這個宏為一個數值.當跟蹤的幀達到這個數量,就會停止對棧的跟蹤.這個幀計數可能會包含一些"內部"的幀.預設情況下它們不會顯示在調試器視窗(見下面的 TraceInternalFrames).某些情況下,在調用棧開始處可能存在3個或者4個"內部"幀
當你使用這個宏的時候,要注意此處.否則的話,你可能不會看見你期望看到的幀.
----------------------------------------------------------
ReportEncoding
當記憶體流失報告儲存到檔案時,這個報告可以是Unicdoe而不是預設的ASCII編碼.這在記憶體流失時包含了Unicode的文字的時候有用.將此參數設定為"unicdoe"來產生一個unicoed編碼的報告.
----------------------------------------------------------
ReportFile
使用這個選項來指定目標報告檔案的位置和名字.如果不指定這個參數.報告檔案將產生在工作目錄下,名字為"memory_leak_report.txt" .
----------------------------------------------------------
ReportTo
使用這個參數來指定報告被附加到什麼地方.可以是以下參數之一:"debugger"(預設),"file"或者"both".
----------------------------------------------------------
SelfTest
VLD有自己偵測自己是否有泄漏的能力.這個功能總是啟用的.任何時間你運行VLD附加進你的程式來檢查記憶體流失,它也檢查自己.設定這個參數為"on"強制VLD故意泄漏一塊記憶體:一個內容為"Memory Leak Self-Test"的21個字元的塊被填進泄漏的塊.這確保了一種方法來測試VLD的自檢能力.並效驗它是否工作正常.這個選項通常在調試VLD自己的時候比較有用.
----------------------------------------------------------
SlowDebuggerDump
如果允許這個參數,將使得VLD比正常情況下更慢一點地寫報告到調試器的輸出視窗.這個參數是為了相容某些版本比較老的VS,如果向它(的輸出視窗)過快的寫內容,會導致丟失資訊.如果你注意到一些資訊好像從報告中消失了,嘗試開啟這個參數.
----------------------------------------------------------
StackWalkMethod
選擇這個參數可以遊走於棧上來擷取已申請記憶體的調用棧.預設的"fast"方法有可能不會每次都成功完全跟蹤到所有的棧.在這種情況下,"safe"方式也許能提供更可靠的方式,但是缺點是在調試時它比"fast"慢得多並且很可能導致效能明顯下降.大多數情況下將此參數設定為"fast"是沒有問題的.
如果你確實要使用"safe"方式,並注意到了明顯效能下降.你也許要考慮使用MaxTraceFrames參數來限制幀的數量.這能極大減少花在跟蹤棧的時間數量
----------------------------------------------------------
StartDisabled
設定這個選項為"yes"可以在最初禁止記憶體偵測.這樣你在運行時可以有選擇地允許記憶體偵測,而不用重新構建程式.但是應該謹慎使用這個參數,在禁用和允許偵測期間,任何記憶體流失都可能發生.
----------------------------------------------------------
TraceInternalFrames
這個參數聲明是否所有調用棧的幀(包含堆中的內部幀)都被追蹤.在調用棧上有很多用於判定引起泄漏的幀,它們都是VLD和C/C++以及Win32 Heap APIs的內部幀.一般這些幀在棧追蹤期間都被跳過了,這樣就稍稍縮小了花在追蹤和收集資料以及儲存的時間.在追蹤棧上包含所有的幀,所有的方式包含VLD自己的代碼都能,但是只對調試VLD自己有用.
在運行時控制VLD
使用預設的配置,VLD的記憶體偵測將在你的程式啟動並執行整個階段運行.在某些情形下你可能喜歡在某些程式碼片段選擇禁止記憶體偵測.VLD提供簡單的API來控制在運行時階段記憶體偵測的狀態.要使用這些API,在需要使用的源檔案中包含vld.h.
VLDDisable
這個函數禁止記憶體流失偵測.調用這個函數之後,記憶體流失偵測將保持禁止,直到明確的調用VLDEnable來允許.
void VLDDisable (void);
參數:
此函數無需參數.
傳回值:
無(總是成功).
注意:
這個函數控制記憶體流失偵測是基於每個線程的.換句話說,調用這個函數,僅僅對調用這個函數的線程禁止記憶體流失偵測.對於同一進程的其他的線程仍然保持允許.這將程式員從不得不同步多線程來允許或者禁止VLD中隔離了出來.注意,這也意味著要在進程範圍內禁止所有VLD,需要在每個線程中調用此函數.
VLDEnable
這個函數允許記憶體流失偵測如果之前已經被禁止了.調用這個函數後VLD將保持允許檢測狀態知道明確調用了VLDDisable().
void VLDEnable (void);
參數:
沒有參數
傳回值:
無(總是成功).
注意:
相似於VLDDisable,這個函數也是基於線程範圍內的.