In this article I will discuss a way to build a memory leakdetection program for C and C++ applications.This is not an attempt at writinga fully fledged leak detector but rather an introduction to one way (of many)ways of finding leaks.
本文將要探討的是一種用于檢查C與C++應用程序的內存泄露的方法,鑒于授人以魚(yú)不如授人以漁的理念,本文主旨并非在于提供一個(gè)完整可用的泄露檢測工具,而是重點(diǎn)介紹一種通用的方法。
The approach I've gone for is libraryinjection and even if the C++ source code provided is for Linux (tested onUbuntu 11.10) the method should work for any platform that allows libraryinjection.
我準備要闡述的就是庫注入的方法,文中采用的C++測試代碼盡管是在Linux平臺運行的(Ubuntu11.10),但是此方法并不限于Linux平臺,只要庫注入可用,任何平臺都可引入此方法。
What is a leak什么是泄露There are many ways in which an application can leakresources, and there are many different resources that can be leaked. Inthis article I'll focus on and only look for memory leaks (not file handles orsockets or any other resource that might be allocated), but even whenconstraining the scope to just memory there are still many different kinds ofleaks. When talking about memory leaks in C++, most people think ofscenarios like this (very simplified one);
應用程序會(huì )因各種問(wèn)題會(huì )產(chǎn)生資源泄露,同時(shí)也有各種不同的資源會(huì )有泄露隱患。本文將要探討的只是內存泄露(不是文件句柄、sockets或者其它可能存在泄露的資源),當然即便是將范圍縮小至“內存”泄露的問(wèn)題,也是有各種不同種類(lèi)的泄露。當討論到C++中的內存泄露時(shí),很多人腦海中立馬浮現的是如下代碼所示的問(wèn)題(或者類(lèi)似的):
點(diǎn)擊(此處)折疊或打開(kāi)
Memory is allocated but is not deleted/unallocated beforethe reference to the allocated memory goes out of scope. This means of coursethat the memory will be unavailable for use as well as for furtherallocations until the program terminates.
上述內存分配之后在超出該內存的引用范圍后并沒(méi)有釋放,這就意味著(zhù)這塊內存在整個(gè)進(jìn)程的周期范圍內將不可被再次使用,因而產(chǎn)生了泄漏。
But memory leaks can appear in other more subtle ways aswell, sometimes the memory is still referenced but just not used, such as whenitems are regularly added to a std::vector without ever being released. If such astd::vector is never cleared and still never again looked at by theapplication it can be considered leak, even though the memory is stillreferenced.
但往往內存泄漏會(huì )以各種其它形態(tài)出現,比如有時(shí)內存仍然是被引用的但是沒(méi)有使用,比如有時(shí)將item加入到std::vector中之后沒(méi)有釋放,如果此vector沒(méi)有被清空并且沒(méi)有再被應用程序操作調用,則也被認作是產(chǎn)生了泄漏,盡管內存仍然可以引用。
In this article,for simplicity, I'll only look at the first scenario; allocated memory that isnot deallocated. In short, I'll show a way of tracking each call to malloc and free and record information so that they can be married up.
本文主要闡述的是一種方法,因而為簡(jiǎn)單起見(jiàn),主要講述第一種情形的泄露,即分配的內存沒(méi)有被釋放。簡(jiǎn)而言之就是我會(huì )去跟蹤malloc與free的調用,以此來(lái)保證二者的次數時(shí)匹配的。
You might argue that you're using C++ andare therefore allocating and deallocating your memory using new anddelete but in most cases the implementation of those will still call the C versions malloc and free.
或許你要強調使用的是C++,因而使用的是new和delete來(lái)做內存的分配與釋放,但是究其根源,使用的還是底層c調用的malloc與free函數。
Library Injection庫注入Library Injection is when a user tells the OS to first lookin LibraryA for system wide methods before lookingin the "standard" libraries, where LibraryA is a library containing an overload ofa system function. On some Linux and Unix distributions this can be achievedusing the LD_PRELOAD environment variable to set thelibrary that is to be injected.
所謂庫注入,是當用戶(hù)告訴系統在涉及到系統范圍內的函數調用時(shí),當“庫A”中包含了系統函數的重載時(shí),首先調用“庫A”而非直接調用標準庫中的此類(lèi)函數,在一些Linux或者Unix發(fā)行版本中,可以通過(guò)LD_PRELOAD環(huán)境變量來(lái)設置要注入的庫。
Totrack memory allocations and deallocations a shared library containing overloadsfor malloc and free must be created and then injected so that whenever an allocationof memory is requested the custom version is hit first.
為了跟蹤內存的分配和釋放,一個(gè)包含malloc和free函數重載的動(dòng)態(tài)庫必須先創(chuàng )建再注入進(jìn)去,這樣一旦分配內存的函數被調用,那么用戶(hù)預設的重載的版本將會(huì )被先調用。
First step is to create a C++ file, leakfinder.cpp, that will contain thetwo methods;
首先創(chuàng )建一個(gè)C++文件,leakfinder.cpp將包含如下兩個(gè)函數:
點(diǎn)擊(此處)折疊或打開(kāi)
The above example can be compiled into a shared libraryusing g++ (which is the compiler I'll use forthe C++ code through out this article) by running:
上述函數可以使用g++來(lái)編譯成動(dòng)態(tài)鏈接庫(本文中Demo將全部使用C++代碼來(lái)實(shí)現)。
Using an example C program that is built to leak we cantest this, the example C program is called c_example and it looks like this:
使用一段C程序可以測試泄露的問(wèn)題,C程序如下c_example如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
It is important to test theinjection in a terminal other than the one used to compile the source code orthe injection might (will) interfere with the compiler and any other commandsthat use malloc or free.
要強調的是,測試這段注入代碼時(shí)需要在特定的終端上運行,以避免編譯源碼或者其它可能調用到malloc或free函數的應用被此庫函數攔截下來(lái)而導致操作失敗。
Therefore, when working with thisexample make sure you have one terminal open for compiling and building (boththe leak finder and the example applictions), and one where the LD_PRELOAD environment variable is set where you canrun the test applications.
因而,測試這些代碼時(shí),你需要有兩個(gè)終端來(lái)操作,一個(gè)用于編譯(包括“泄露檢測工具”以及應用測試代碼),一個(gè)用來(lái)設置LD_PRELOAD環(huán)境變量后來(lái)運行測試代碼。
Another way of making sure the pre-loadonly is applicable for the c_example application is by running it like this;LD_PRELOAD=./leakfinder.soc_example.
另外一個(gè)確保pre_load只為C_example使用的方法是,如下這樣運行:LD_PRELOAD=./leadfinder.so c_example
Set the LD_PRELOAD in your terminal to point to the leakfinder.so and run the c_example test application using;
在終端上將LD_PRELOAD設置為leakfinder.so再運行c_example程序可以這樣設置:
When first run it turns out that no allocations ordeallocations are detected, this is because of the linkage. As g++(a C++ andnot a C compiled) was used to compile the leakfinder.cpp file it has applied namemangling and that means he function names do not match the intended systemfunctions malloc and free. To resolve this issue the functions has to be declared with C linkage:
首次運行會(huì )發(fā)現沒(méi)有任何分配或釋放操作被探測到,這是因為鏈接問(wèn)題,因為g++編譯器是c++而非c編譯器,編譯leadfinder.cpp時(shí)考慮到C++中存在的重載問(wèn)題,函數名并沒(méi)有匹配系統調用的malloc與free函數,解決此問(wèn)題的辦法是函數定義之前增加如下修飾部分:
點(diǎn)擊(此處)折疊或打開(kāi)
When the leak finder with the correct linkage is preloadedand the example is run it will generate an output that looks something likethis;
當此鏈接問(wèn)題解決后,泄露檢查工具會(huì )被預加載,測試代碼運行的結果如下所示:
Loads and loads of allocations and deallocationsintercepted! This is because even though the test application onlyexplicitly allocates a few things other parts also allocates and deallocatesstuff, such as the printf and even the cout calls in the injected code.
我們看到不僅僅是我們認為調用malloc與free的地方被攔截了。
這是因為即便我們在測試demo中調用內分配的地方有限,但是其它一些現有的函數如printf甚至cout調用內部都調用了分配和釋放內存函數。
The print out ends with a Segmentationfault which is ofcourse because you cannot hope to replace an actual memory allocation with aprint statement and expect stuff to still work , but the method is proved to work.
最后輸出的段錯誤提示,是因為沒(méi)有辦法使用簡(jiǎn)單的輸出操作來(lái)替代真正的內存分配并且還能讓其繼續保持工作。但是這至少證明了我所闡述的方法是可行的。
Actual implementation真正的實(shí)現As it is clearly very important for the overloaded methods malloc and free to still do the work they are intended to do (as in allocating anddeallocating memory on and from the heap) the injected code must look uppointers to the actual implementation and delegate the calls to these beforetracking them.
顯而易見(jiàn)的是我們重載的malloc與free函數是需要真正意義上實(shí)現它們原有的功能,即能實(shí)現在堆上動(dòng)態(tài)的分配和釋放內存,因而攔截的代碼部分除了跟蹤,最終還是需要訪(fǎng)問(wèn)這些函數真正實(shí)現的指針。
Finding it找到函數實(shí)現To find the actual implementation is done by calling dlsym (defined in dlfcn.h),this function returns function pointers to functions made available using dlopen. Using the constant RTLD_NEXT the previous entry can be retrieved, and that pointer can bestored in a static variable to cache it so the lookup doesn't have to take placeevery time;
找到函數真正的實(shí)現是通過(guò)調用dlsym(定義在dlfcn.h中)來(lái)實(shí)現的,通過(guò)調用dlopen可以實(shí)現利用此函數返回指定函數的指針。通過(guò)RTLD_NEXT常量,之前的入口便可獲得,這個(gè)入口指針可以保存在一個(gè)靜態(tài)變量中,從而無(wú)需每次替換時(shí)都來(lái)重新查詢(xún)這個(gè)指針。
點(diǎn)擊(此處)折疊或打開(kāi)
點(diǎn)擊(此處)折疊或打開(kāi)
In the code above the system version (or standard version)of malloc and free are looked up using dlsym(RTLD_NEXT,[name of function]) and then stored in sys_malloc and sys_free respectively. After the system version of the functions are cached(if not already cached) they're called to perform the allocation ordeallocation and after that the leak finder will intercept the calls to trackthe information required to compile a list of leaks.
上述代碼中,系統自帶(或標準庫自帶)的malloc和free函數使用dlsym(RTLD_NEXT,[函數名])可以獲取到入口地址并且分別保存為sys_malloc和 sys_free,在系統自帶函數入口保存好了后,他們會(huì )用來(lái)真正實(shí)現內存的分配和釋放,在此之后,“內存泄露檢測器”會(huì )攔截應用程序中的所有對這兩個(gè)函數的調用,從而能跟蹤到用戶(hù)所需要的信息。
Allocation Info分配信息To allow the user to fix leaks, each leak needs to beassociated with additional information to make it easy to track down the leakand correct it, in leakfinder I track four different things;
為了允許用戶(hù)解決泄露問(wèn)題,每個(gè)泄露需關(guān)聯(lián)可以用于跟蹤和糾正這些泄露的其它信息,在“泄露探測器”中我跟蹤4種不同信息。
1) References
2) Stacktrace
3) Size
4) Thread
1) 引用
2) 堆棧軌跡
3) 內存大小
4) 線(xiàn)程ID
References引用In order to marry up a deallocation to a previousallocation there need to be something that is unique and consistent across malloc and free calls, and one thing that can be used is the address of theallocated memory. It has to be unique as no two allocations are allowed to getthe same piece of memory and it's consistent across calls as it's the returnvalue of the allocation and the parameter to the deallocation.
為了使得釋放操作能與之前的分配操作匹配,需要有針對malloc與free調用的持續的唯一性記錄??梢杂脕?lái)實(shí)現此記錄的便是分配的內存地址。因為這個(gè)地址肯定是唯一的,并且作為分配內存時(shí)的返回值和釋放時(shí)的傳入值,在整個(gè)調用期間它也是持續存在的。
Stacktrace堆棧軌跡In order for a memory leak detector to be useful it needsto be able to tell the user where the leak was allocated. One way to geta stacktrace in Linux is to use the backtrace and backtrace_symbols functions in execinfo.h.
為了使得“內存泄露檢測器”并非浪得虛名,我們不但需要檢測到泄露的存在,而且應能準確定位到是何處分配的內存存在泄露問(wèn)題。在Linux上獲取堆棧軌跡的方法是使用execinfo.h頭文件中的 backtrace 和backtrace_symbols方法。
Function backtrace gets all the return addresses for all the functions that arecurrently active on the stack in a particular thread, which is essentially the stacktrace.
In order to get a more readable version of the stacktrace the returnaddresses from backtrace can be fed into backtrace_symbols to get the names of the functions on the stack.
backtrace 函數可以用來(lái)獲取特定線(xiàn)程上當前棧內所有函數地址作為返回值供分析使用,本質(zhì)上來(lái)講就是堆棧軌跡。
為獲得堆棧軌跡的更多的可用分析信息,可以通過(guò)backtrace返回的地址傳入backtrace_symbols 函數后獲取棧上的函數名。兩個(gè)函數體分別如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
Less important but still sometimes useful is to record thesize of the allocation and which thread it was allocated on.
盡管不太重要,但是記錄下分配的內存大小以及分配該內存的線(xiàn)程有時(shí)還是有一定價(jià)值的。
The size is passed in as a size_t argument to malloc so that is easy enough to grab and record.
內存大小是malloc函數的類(lèi)型為size_t的傳入參數,因而易于獲得并記錄下來(lái)。
Recording the current thread id might be slightly harderdepending on the thread library used, in this example I've used the pthread library so I get the thread id as a pthread_t by calling pthread_self().
記錄下當前線(xiàn)程可能稍顯復雜,因為這會(huì )依賴(lài)于所使用的線(xiàn)程庫。本文中的例子我使用的是pthread庫,因而可以通過(guò)調用pthread_self()函數,其類(lèi)型為pthread_t的返回值便是該線(xiàn)程的ID。
allocation_infoallocation_info類(lèi)The information listed above, reference, stacktrace, sizeand thread are in leakfinder stored in a class called.
上述列出的引用、堆棧軌跡、大小以及線(xiàn)程ID在本“泄漏檢測器”中封裝在allocation_info的類(lèi)中。其定義與實(shí)現如下所示:
allocation_info.h點(diǎn)擊(此處)折疊或打開(kāi)
點(diǎn)擊(此處)折疊或打開(kāi)
Armed with a way of intercepting allocations (libraryinjection) and a way to store allocation information (allocation_info) we're now ready to implement our basic memory leak detector.
擁有了攔截分配內存函數(庫注入)的方法和存儲分配信息的方法(allocation_info類(lèi)),我們接下來(lái)先實(shí)現一個(gè)簡(jiǎn)單的“內存泄露檢測器”。
Allocations分配The first problem with tracking allocations inside theallocation method is that to track it memory needs to be allocated to store the allocation_info, and that obviously means that for every allocation anotherallocation is required. Since the additional allocation uses malloc as well the approach leads to a stack overflow.
首先來(lái)的問(wèn)題就是,為了講內存分配的信息存儲在allocation_info中,就另外需要調用內存分配函數malloc來(lái)分配這個(gè)存儲信息區域,這樣就陷入了死循環(huán)直至棧溢出。
The solution is to only track allocations that areoriginating from outside of leakfinder.By declaring a staticboolean called i***ternalSource that is set to false before the allocation is recorded and back to true when done it is possible to exclude allocation that arise fromrecording the source allocation. The overloaded mallocmethod then looks something like this;
解決的方法是,只跟蹤“內存泄露檢測器”代碼外部的一些內存分配函數,通過(guò)定義一個(gè)名為i***ternalSource 的靜態(tài)變量來(lái)區分,在進(jìn)行對外部分配內存信息記錄之前將其設置為false,完成記錄之后設置為true,這可以有效的將記錄內存分配信息時(shí)調用的malloc函數與被監控的malloc函數區分開(kāi)來(lái)。沖在的malloc函數如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
This takes care of the exclusion of internal allocation butsuffers from threading issues as the statici***ternalSource might be read/written by two threads at the same time causingundefined behaviour.
上述代碼的確做到了將檢測器內部調用malloc的情況區別開(kāi)來(lái),但是存在的問(wèn)題是,如果有同時(shí)有多個(gè)線(xiàn)程對靜態(tài)變量i***ternalSource 進(jìn)行讀寫(xiě)操作,那么就有可能導致一些不確定的結果。
By guarding the inside of the if-statement with a lock(using pthread threads) the malloc method changes to this;
為了對此進(jìn)行防護,采用加鎖的辦法(使用pthread線(xiàn)程),上述重載的malloc修改如下:
點(diǎn)擊(此處)折疊或打開(kāi)
Now the malloc implementation is thread safe (or thread-safeish, it still suffersfrom some issues but for sake of simplicity I'm going to keep it this way forthis article).
現在實(shí)現的malloc函數就能確保是線(xiàn)程安全的。(或者說(shuō)相對安全的,因為還是存在一些特殊情形會(huì )導致問(wèn)題存在,但是為了簡(jiǎn)單起見(jiàn),本文中我們認為此已經(jīng)足以確保該部分是線(xiàn)程安全的)。
The rest of the implementation is the matter of grabbingthe stacktrace and storing it along with the reference, size and thread id. Thesize is already passed in and the thread id has been grabbed using pthread_self, the remaining this to store is simply the reference which is theaddress of ptr which is returned by the actual implementation ofmalloc.
剩下的實(shí)現即抓取堆棧軌跡并且將其引用、大小和線(xiàn)程ID記錄下來(lái)。大小已經(jīng)記錄,線(xiàn)程ID也通過(guò)pthread_self函數獲得,剩下的需要存儲的就是真正的malloc函數返回的內存指針ptr。
All of the above yields a malloc function that looks like this;
綜上述所,最終實(shí)現的malloc函數版本如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
To marry up a deallocation to a previous allocation issimple. The free uses the same method of preventing it to be run for an internalfree and thread safety and in addition to this it's just a matter of findingthe allocation_info in the allocations vector. The unique key is the reference or address;
與之前的分配內存的操作匹配的釋放甚是簡(jiǎn)單,我們需要重載的free函數也需要考慮到之前提到的“內存泄露檢測器”內部的free調用和線(xiàn)程安全問(wèn)題,除此之外還需要做的就是從allocation容器中獲取allocation_info (分配的內存信息),其唯一性標識便是內存的引用或者說(shuō)地址。
點(diǎn)擊(此處)折疊或打開(kāi)
After all the allocations and deallocations have beentracked and matched off the ones that were never deallocated must be reportedon, so when is a suitable time to do that?
所有的分配操作和釋放操作均已記錄下,那么對于那些分配之后沒(méi)有釋放的落單的地方必須要上報出來(lái),何時(shí)做才合適呢?
Since it's pretty much technically impossible to tell if aleak has happened before the program terminates leakfinderuses programexit to sum up the leaks. One might argue that the leak happens when thepointer referencing the memory goes out of scope of the pointer has not beendeallocated but since it is possible to store the pointer value in just aboutany other data structure that can be hard to rely on.
鑒于技術(shù)上不太可能實(shí)現在程序結束之前就統計出是否存在內存泄露的問(wèn)題,我們的“內存泄露檢測器”使用程序退出機制來(lái)實(shí)現泄露的統計??赡軙?huì )有人說(shuō),指針在引用超出該指針作用域范圍的內存后沒(méi)有釋放,這會(huì )導致內存泄露的產(chǎn)生,但是由于指針值可以存儲在任何其它數據結構中,因而這個(gè)假設是很難成立的。
C style destructorC風(fēng)格的析構 There are different ways to hook into the termination of aprogram, which one to pick depends on platform and personal taste.
One approach is to use a pragma directive;
很多方法可以實(shí)現hook到程序的終結,選擇哪一個(gè)往往會(huì )由平臺和個(gè)人喜好確定。
一種方法是使用pragma命令,如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
but for leakfinder I've gone for a C style destructor;
但是對我們的“泄露檢測器”,我準備使用的是c風(fēng)格的析構函數。
點(diǎn)擊(此處)折疊或打開(kāi)
Using this approach, the method compile_allocation is executed when the shared library is unloaded, this is typicallyat program exit.
使用這一方法,compile_allocation函數在共享庫卸載時(shí)會(huì )被調用,這是程序退出時(shí)的典型特征。
Since all the not unallocated allocations are held in thevector allocations at program exit, the work of thecompile_allocation method is just to iterate through the leaks and somehow output theleak information.
由于程序退出時(shí),所有的沒(méi)有被釋放的內存仍然保留在allocations這個(gè)容器中,compile_allocation這個(gè)函數的作用就是利用迭代器便利所有這些沒(méi)有被釋放的內存,并輸出這些泄露的相關(guān)信息。
Where the best place tooutput the leak information to I am not entirely sure of. In certain scenariosa file would be convinient but for simplicity I've decided to let leakfinder just dump the summary to standard out.
我并不確定哪兒來(lái)輸出這些泄露信息是最好的,輸出到一個(gè)文件當然是灰常方便的,但是在此為了簡(jiǎn)單,我就直接往標準輸出上來(lái)顯示了。
To avoid extra work i***ternalSource needs to be set to false at the beginning of compile_allocaion as printing the summary requires allocations to take place.
為了避免不必要的錯誤,i***ternalSource 在準備打印compile_allocaion信息之前就需要設為false。
To print addresses and pointers in hex variables hex and dec from iomanip are used.
為了將地址和指針輸出為十六進(jìn)制形式,通過(guò)iomanip中的hex和dec來(lái)實(shí)現打印。
點(diǎn)擊(此處)折疊或打開(kāi)
To try it out first build the leakfinder shared library by typing (there's alsoa makefile included for those who cares not forcompiling by hand);
首先來(lái)將“leakfinder”編譯成共享庫,可以通過(guò)g++命令來(lái)編譯或者直接用現成的makefile編譯。
Then build the c_example shared library by typing;
再編譯c_example共享庫:
Then, open up a different terminal and set the LD_PRELOAD;
再來(lái)開(kāi)啟一個(gè)終端,并設置LD_PRELOAD變量。
Lastly, run the c_example in the terminal where LD_PRELOAD was set;
最后,在設置過(guò)LD_PRELOAD環(huán)境變量的終端上啟動(dòng)c_example:
Running that application should produce an output similarto this;
輸出的結果大致如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
While that has indeed first printed the output of c_example followed by the summary of the fourleaks, the stactrace isn't very easy to dechiper. That is because the programis lacking symbols but by compiling it again (in the first terminal) withoption -rdynamic this can be corrected;
從輸出的結果中,的確可以看到c_example中出現的4次泄露的記錄,但是堆棧軌跡并不太易讀。這是由于編譯程序時(shí),少了-rdynamic設置,而缺少符號文件。重新編譯即可解決此問(wèn)題。
A more useful stacktrace is provided;
更完整的堆棧軌跡如下所示:
點(diǎn)擊(此處)折疊或打開(kāi)
Now the method name is included and that makes it a wholelot easier to read, and while this works for C++programsas well their stacktraces are still a bit messy because of name mangling, butstill very much readable when compiled with -rdynamic,as seen below in the output from cpp_example (also included in the download);
這樣函數名已經(jīng)顯示出來(lái),就更易讀了,但是在c++程序中,這個(gè)堆棧軌跡還是因為命名空間的問(wèn)題有些混亂,但是使用 –rdynamic后還是有很多改進(jìn)的,下面的輸出時(shí)cpp_example程序的輸出結果。
點(diǎn)擊(此處)折疊或打開(kāi)
Like I stated at the beginning of the article, this is notan attempt at a finished leak detection product but an explanation of how sucha product can be created. The observant reader will have realised thatthe implementation included with this article is lacking in many areas, it doesnot explicitly cater for (for example) calloc and that using a std::vector to store the allocation_info objects results in a linear performance penalty on the lookups.
如我剛開(kāi)始介紹的,本文的目的并非試圖實(shí)現一個(gè)功能十足的“內存泄露檢測器”的產(chǎn)品,只是闡述了如何去按照我給出的方法來(lái)去實(shí)現這個(gè)產(chǎn)品。細心的讀者會(huì )發(fā)現這個(gè)demo中的實(shí)現還是有很多欠缺的,比如demo中沒(méi)有明確的提供calloc函數的重載,并且使用std::vector存儲allocation_info對象的結果是導致在大量數據查找時(shí)的性能的線(xiàn)性下降。
Regardless of this, I hope the article has provided acertain amount of insight into how leaks can be spotted in a non-intrusive way(in the sense that the application code does not need to be instrumented orotherwise augmented).
拋開(kāi)這些,我希望本文能夠為你提供一種解決非入侵式的內存泄露探測方法(就這個(gè)層面來(lái)講,應用程序代碼無(wú)需做自身的檢測或其它方式來(lái)增強監測)
And weirdly enough, the Code Project article submission wizarddoes not allow me to upload .tar files, so if you want one of those instead;you can get it from here (the allocation_info.cpp file is broken but I'll fixthat at a later time, the .zip file is correct); https://sites.google.com/site/fredrikbornander/Home/leakfinder.tar?attredirects=0&d=1
文中的demo可以在以下地址下載。(附件中已有)
Any comments are most welcome.
聯(lián)系客服