c/c++記憶體洩漏檢測工具
1、 可以得到記憶體洩漏點的呼叫堆疊,如果可以的話,還可以得到其所在檔案及行號;
2、 可以得到洩露記憶體的完整資料;
3、 可以設定記憶體洩露報告的級別;
4、 它是一個已經打包的lib,使用時無須編譯它的原始碼。而對於使用者自己的程式碼,也只需要做很小的改動;
5、 他的原始碼使用GNU許可釋出,並有詳盡的文件及註釋。對於想深入瞭解堆記憶體管理的讀者,是一個不錯的選擇。
可見,從使用角度來講,Visual Leak Detector簡單易用,對於使用者自己的程式碼,唯一的修改是#include Visual Leak Detector的標頭檔案後正常執行自己的程式,就可以發現記憶體問題。從研究的角度來講,如果深入Visual Leak Detector
本文首先將介紹Visual Leak Detector的使用方法與步驟,然後再和讀者一起初步的研究Visual Leak Detector的原始碼,去了解Visual Leak Detector的工作原理。
使用 Visual Leak Detector(1.0)
下面讓我們來介紹如何使用這個小巧的工具。
首先從網站上下載zip包,解壓之後得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等檔案。將.h
注:我下載的是較新版1.9,直接安裝到系統中。因此使用時必須先在VC中設定一下目錄。
接下來需要將其加入到自己的程式碼中。方法很簡單,只要在包含入口函式的.cpp檔案中包含vld.h就可以。如果這個cpp檔案包含了stdafx.h,則將包含vld.h的語句放在stdafx.h的包含語句之後,否則放在最前面。如下是一個示例程式:
123456789 | #include <vld.h>voidmain(){…} |
接下來讓我們來演示如何使用Visual Leak Detector檢測記憶體洩漏。下面是一個簡單的程式,用new分配了一個int大小的堆記憶體,並沒有釋放。其申請的記憶體地址用printf輸出到螢幕上。
編譯執行後,在標準輸出視窗得到:
1 | p=003a89c0 |
在Visual C++的Output視窗得到:
WARNING: Visual Leak Detector detected memory leaks!
———- Block 57 at 0x003A89C0: 4 bytes ———- –57號塊0x003A89C0地址洩漏了4個位元組
Call Stack: —下面是呼叫堆疊
d:/test/testvldconsole/testvldconsole/main.cpp (7): f —表示在main.cpp第7行的f()函式
d:/test/testvldconsole/testvldconsole/main.cpp (14): main –雙擊以引導至對應程式碼處
f:/rtm/vctools/crt_bld/self_x86/crt/src/crtexe.c (586): __tmainCRTStartup
f:/rtm/vctools/crt_bld/self_x86/crt/src/crtexe.c (403): mainCRTStartup
0x7C816D4F (File and line number not available): RegisterWaitForInputIdle
Data: —這是洩漏記憶體的內容,0x12345678
78 56 34 12 xV4….. ……..
Visual Leak Detector detected 1 memory leak.
第二行表示57號塊有4位元組的記憶體洩漏,地址為0x003A89C0,根據程式控制臺的輸出,可以知道,該地址為指標p。程式的第7行,f()函式裡,在該地址處分配了4位元組的堆記憶體空間,並賦值為0x12345678,這樣在報告中,我們看到了這4位元組同樣的內容。
可以看出,對於每一個記憶體洩漏,這個報告列出了它的洩漏點、長度、分配該記憶體時的呼叫堆疊、和洩露記憶體的內容(分別以16進位制和文字格式列出)。雙擊該堆疊報告的某一行,會自動在程式碼編輯器中跳到其所指檔案的對應行。這些資訊對於我們查詢記憶體洩露將有很大的幫助。
這是一個很方便易用的工具,安裝後每次使用時,僅僅需要將它標頭檔案包含進來重新build就可以。而且,該工具僅在build Debug版的時候會連線到你的程式中,如果build Release版,該工具不會對你的程式產生任何效能等方面影響。所以儘可以將其標頭檔案一直包含在你的原始碼中。
Visual Leak Detector 工作原理
下面讓我們來看一下該工具的工作原理。
在這之前,我們先來看一下Visual C++內建的記憶體洩漏檢測工具是如何工作的。Visual C++內建的工具CRT Debug Heap工作原來很簡單。在使用Debug版的malloc分配記憶體時,malloc會在記憶體塊的頭中記錄分配該記憶體的檔名及行號。當程式退出時CRT會在main()函式返回之後做一些清理工作,這個時候來檢查除錯堆記憶體,如果仍然有記憶體沒有被釋放,則一定是存在記憶體洩漏。從這些沒有被釋放的記憶體塊的頭中,就可以獲得檔名及行號。
這種靜態的方法可以檢測出記憶體洩漏及其洩漏點的檔名和行號,但是並不知道洩漏究竟是如何發生的,並不知道該記憶體分配語句是如何被執行到的。要想了解這些,就必須要對程式的記憶體分配過程進行動態跟蹤。Visual Leak Detector就是這樣做的。它在每次記憶體分配時將其上下文記錄下來,當程式退出時,對於檢測到的記憶體洩漏,查詢其記錄下來的上下文資訊,並將其轉換成報告輸出。
初始化
Visual Leak Detector要記錄每一次的記憶體分配,而它是如何監視記憶體分配的呢?Windows提供了分配鉤子(allocation hooks)來監視除錯堆記憶體的分配。它是一個使用者定義的回撥函式,在每次從除錯堆分配記憶體之前被呼叫。在初始化時,Visual Leak Detector使用_CrtSetAllocHook註冊這個鉤子函式,這樣就可以監視從此之後所有的堆記憶體分配了。
如何保證在Visual Leak Detector初始化之前沒有堆記憶體分配呢?全域性變數是在程式啟動時就初始化的,如果將Visual Leak Detector作為一個全域性變數,就可以隨程式一起啟動。但是C/C++並沒有約定全域性變數之間的初始化順序,如果其它全域性變數的建構函式中有堆記憶體分配,則可能無法檢測到。Visual Leak Detector使用了C/C++提供的#pragma init_seg來在某種程度上減少其它全域性變數在其之前初始化的概率。根據#pragma init_seg的定義,全域性變數的初始化分三個階段:首先是compiler段,一般c語言的執行時庫在這個時候初始化;然後是lib段,一般用於第三方的類庫的初始化等;最後是user段,大部分的初始化都在這個階段進行。Visual Leak Detector將其初始化設定在compiler段,從而使得它在絕大多數全域性變數和幾乎所有的使用者定義的全域性變數之前初始化。
記錄記憶體分配
一個分配鉤子函式需要具有如下的形式:
12 | intYourAllocHook(intallocType,void*userData,size_t size,intblockType,longrequestNumber,constunsignedchar*filename,intlineNumber); |
就像前面說的,它在Visual Leak Detector初始化時被註冊,每次從除錯堆分配記憶體之前被呼叫。這個函式需要處理的事情是記錄下此時的呼叫堆疊和此次堆記憶體分配的唯一標識——requestNumber。
得到當前的堆疊的二進位制表示並不是一件很複雜的事情,但是因為不同體系結構、不同編譯器、不同的函式呼叫約定所產生的堆疊內容略有不同,要解釋堆疊並得到整個函式呼叫過程略顯複雜。不過windows提供一個StackWalk64函式,可以獲得堆疊的內容。StackWalk64的宣告如下:
1 2 3 4 5 6 7 8 9 10 11 | BOOLStackWalk64( DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); |
STACKFRAME64結構表示了堆疊中的一個frame。給出初始的STACKFRAME64,反覆呼叫該函式,便可以得到記憶體分配點的呼叫堆疊了。
相關推薦
Unix下C程式記憶體洩漏檢測工具Valgrind安裝與使用
Valgrind是一款用於記憶體除錯、記憶體洩漏檢測以及效能分析的軟體開發工具。 Valgrind的最初作者是Julian Seward,他於2006年由於在開發Valgrind上的工作獲得了第二屆Google-O'Reilly開原始碼獎。 Valgrind遵守GNU通用公共許
C/C++的記憶體洩漏檢測工具Valgrind memcheck的使用經歷
Linux下的Valgrind真是利器啊(不知道Valgrind的請自覺檢視參考文獻(1)(2)),幫我找出了不少C++中的記憶體管理錯誤,前一陣子還在糾結為什麼VS 2013下執行良好的程式到了Linux下用g++編譯執行卻崩潰了,給出一堆彙編程式碼也看不懂。久久不
c++記憶體洩漏檢測工具(上)
原文連結: http://blog.csdn.net/beanjoy/article/details/7578372 1/ VC自帶的CRT:_CrtCheckMemory 偵錯程式和 CRT 除錯堆函式 用法 /********
C 記憶體洩漏檢測工具
所有使用動態記憶體分配(dynamic memory allocation)的程式都有機會遇上記憶體洩露(memory leakage)問題,在Linux裡有三種常用工具來檢測記憶體洩露的情況,包括: mtrace dmalloc memwatch 1. mtrace
如何使用Valgrind memcheck工具進行C/C++的記憶體洩漏檢測
1. 使用未初始化的記憶體 Code : #include <stdio.h> #include <stdlib.h> int main(void) { char *p; char c = *p; printf("\n [%c]\n",c);
c/c++記憶體洩漏檢測工具
1、 可以得到記憶體洩漏點的呼叫堆疊,如果可以的話,還可以得到其所在檔案及行號; 2、 可以得到洩露記憶體的完整資料; 3、 可以設定記憶體洩露報告的級別; 4、 它是一個已經打包的lib,使用時無須編譯它的原始碼。而對於使用者自己的程式碼,也只需要做很小的改動; 5、
Linux C/C++ 記憶體洩漏檢測工具Valgrind
下面是一段有問題的C程式程式碼test.c #i nclude <stdlib.h> void f(void) { int* x = malloc(10 * sizeof(int)); x[10] = 0; //問題1: 陣列下標越界 } //問
C++記憶體洩漏檢測工具-Valgrind使用簡介
一 valgrind是什麼? Valgrind是一套Linux下,開放原始碼(GPL V2)的模擬除錯工具的集合。Valgrind由核心(core)以及基於核心的其他除錯工具組成。核心類似於一個框架(framework),它模擬了一個CPU環境,並提供服務給其他工具;
Linux C 程式設計記憶體洩露檢測工具(二):memwatch
Memwatch簡介 在三種檢測工具當中,設定最簡單的算是memwatch,和dmalloc一樣,它能檢測未釋放的記憶體、同一段記憶體被釋放多次、位址存取錯誤及不當使用未分配之記憶體區域。請往http://www.linkdata.se/sourcecode.html下載最
C語言記憶體洩漏檢測方法
記憶體洩漏是C語言程式設計中一個很常見的問題,而且由於記憶體洩漏所導致的問題出現較緩慢,所以不容易覺察,所以寫一個簡單的程式來檢測記憶體洩漏很有必要。 記憶體洩漏通常是指堆記憶體的洩漏,也就是通過malloc、calloc函式申請的記憶體,因此記憶體洩漏的檢測方法
Windows 7 下 vs2010記憶體洩漏檢測工具VLD的使用
1 環境和軟體 Windows7 32位系統 Visual Studio 2012 旗艦版 vld-2.2.3-setup.exe 大小1.04M 2 步驟 1)下載安裝 下載好 vld-2.2.3-setup.exe(大小1.04
Windows 記憶體洩漏檢測工具——LeakDiag 詳解
對於記憶體洩漏的檢查,本質上在於定位記憶體洩漏。這種定位包含兩層含義: 一是定位模組,即哪個模組出了問題。 二是定位程式碼,即找到造成記憶體洩漏的程式碼。 對此,在分工合作完成一個系統的背景下,我們檢查記憶體洩漏的工作流程就應該是:第一,定位模組;第二,如果是我們的模組出現
簡單強大的Android記憶體洩漏檢測工具 LeakCanary
幾乎每個程式設計師在開發的過程中都會遇到記憶體洩漏,那麼我們如何檢測到app是否哪裡出現記憶體洩漏呢?square公司推出了一款簡單粗暴的檢測記憶體洩漏的工具-- LeakCanary 什麼是記憶體洩漏? 記憶體洩漏是指由於疏忽或者錯誤造成程式未能釋放已經不再使用的記憶體,記憶體洩漏不
window使用記憶體洩漏檢測工具Leakdiag記錄
Leakdiag安裝 windows下記憶體洩漏查詢工具Leakdiag使用起來還是蠻方便的。 Leakdiag下載之後按照預設設定安裝,否則好像是會出問題的。 預設安裝是直接裝在C盤下。 那它是如何來檢測記憶體洩漏的呢? 下圖所示是Leakdiag目
嵌入式 不同平臺或者語言記憶體洩漏檢測工具
1. ccmalloc-Linux和Solaris下對C和C++程式的簡單的使用記憶體洩漏和malloc除錯庫。 2. Dmalloc-Debug Malloc Library. 3. Electric Fence-Linux分發版中由Br
IOS-記憶體洩漏檢測工具Instruments中的Leaks
Instruments 是一個很靈活的、強大的工具;是效能分析、動態跟蹤 和分析OS X 以及iOS程式碼的測試工具;用它可以極為方便收集關於一個或多個系統程序的效能和行為的資料,並能及時隨著時間跟蹤而產生的資料,並檢查所收集的資料,還可以廣泛收集不同型別的資料;也可以追蹤程式執行的過程,這樣instrume
【工具】valgrind檢測C++程式碼記憶體洩漏
一、valgrind介紹: valgrind是Linux下的一個開源工具,該工具用來檢測c++程式是否有非法使用記憶體的問題,例如訪問了未初始化的記憶體、訪問陣列時越界、忘記釋放動態記憶體等問題。Lin
一個簡單的記憶體洩漏檢測C工具
這個記憶體洩漏檢測工具很簡單,只能檢測同一個模組,同一個執行緒中傳送的記憶體洩漏,對於在編寫程式碼過程中的程式碼除錯有一定的幫助。如果要在整合測試或功能測試中檢測記憶體洩漏,還需藉助專門的工具。 1. 先取向malloc,free和calloc這幾個識別符號的定義:注意
C++ 記憶體洩漏檢測1:微軟自帶的記憶體洩漏檢測方法
在程式總的包含標頭檔案中新增以下程式碼, #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK
C++ 記憶體洩漏檢測方法
程式中通常包含著靜態儲存區和棧記憶體。靜態儲存區也就是靜態記憶體,是用來儲存區域性static物件、類static資料成員以及定義在任何函式之外的變數(全域性變數)。棧記憶體用來儲存定義在函式內的非static物件。分配在靜態或棧記憶體中的物件由編譯器自動建立