VC Memory leakage detection tool _ visual Leak Detector

Source: Internet
Author: User

First glance at visual Leak Detector
Flexibility and freedom are a major feature of the C/C ++ language, which poses a challenge for C/C ++ programmers. When the program becomes more and more complex, the memory management will become more and more complex, and memory problems will arise if you are careful. Memory leakage is one of the most common memory problems. If the memory leakage is not very serious, it will not affect the program much in a short period of time, which also makes the memory leakage problem highly concealed and difficult to be detected. However, no matter how slight memory leakage occurs, the destructive power of a program is astonishing when it runs for a long time, from performance degradation to memory depletion, and may even affect the normal operation of other programs. In addition, a common feature of memory problems is that memory problems are not very obvious in themselves. When exceptions occur, the time has elapsed and the site has not encountered any problems, this makes debugging memory very difficult.

Visual leak detector is a free memory leak detection tool for Visual C ++. It can be downloaded in the http://www.codeproject.com/tools/visualleakdetector.asp. Compared with other memory leak detection tools, it detects memory leaks and has the following features:
1. You can obtain the call stack of the memory leak point. If you can, you can also obtain the file and row number of the memory leak point;
2. You can obtain complete data that exposes the memory;
3. You can set the Memory Leak report level;
4. It is a packaged lib and does not need to compile its source code during use. You only need to make minor changes to your own code;
5. Its source code is released with the GNU license, with detailed documents and comments. It is a good choice for readers who want to learn more about heap memory management.

From the perspective of usage, visual leak detector is easy to use. The only change to your own code is to # include the header file of visual leak detector and then run your program normally, memory problems can be found. From the perspective of research, if you go deep into the visual leak detector source code, you can learn the principles of heap memory allocation and release, the principles of memory leak detection, and common techniques for memory operations.
This article will first introduce the use and steps of visual leak detector, and then study the source code of visual leak detector with the reader to understand the working principle of visual leak detector.
Use Visual Leak Detector (1.0)
The following describes how to use this small tool.
Download the zip package from the website, decompress the package, and obtain files such as VLD. H, vldapi. H, VLD. Lib, vldmt. Lib, vldmtdll. Lib, and dbghelp. dll. Copy the. h file to the default include directory of Visual C ++ and copy the. Lib file to the default lib directory of Visual C ++. The installation is complete. Due to version issues, if you use Windows 2000 or a previous version, you need to copy dbghelp. DLL to the running directory of your program, or other directories that can be referenced.
Next, you need to add it to your own code. The method is simple. You only need to include VLD. h In the. cpp file that contains the entry function. If the CPP file contains stdafx. H, place the statement containing VLD. h after the statement containing stdafx. h; otherwise, put it at the beginning. The following is an example program:
# Include <VLD. h>
Void main ()
{
...
}
Next, let's demonstrate how to use visual leak detector to detect memory leaks. The following is a simple program that allocates a heap memory of int size with new and has not been released. The requested memory address is output to the screen using printf.
# Include <VLD. h>
# Include <stdlib. h>
# Include <stdio. h>

Void F ()
{
Int * P = new int (0x12345678 );
Printf ("P = % 08x,", P );
}

Void main ()
{
F ();
}
After compilation and running, the following output is displayed in the standard output window:
P = 003a89c0

In the output window of Visual C ++, we get:

Warning: Visual leak detector detected memory leaks!
---------- Block 57 at 0x003a89c0: 4 bytes ---------- -- block 57 0x003a89c0 contains 4 bytes
Call Stack: -- The following is the call stack.
D:/test/testvldconsole/Main. cpp (7): f -- indicates the F () function in Main. cpp row 7th
D:/test/testvldconsole/Main. cpp (14): Double-click main to guide the corresponding code
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: -- this is memory leakage, 0x12345678
78 56 34 12 xv4 .............

Visual leak detector detected 1 memory leak.
The second line indicates that block 57 has 4-byte memory leakage. The address is 0x003a89c0. According to the output on the console, you can see that the address is the pointer p. In the F () function of the program's 7th rows, a 4-byte heap memory space is allocated at the address, and the value is 0x12345678. In this way, in the report, we can see the same 4-byte content.
We can see that for every memory leak, this report lists the leak points, lengths, call stacks when the memory is allocated, and leaked memory contents (listed in hexadecimal and text formats respectively ). Double-click a row of the stack Report, and the corresponding row of the file is automatically jumped to the code editor. This information will be of great help for us to find memory leaks.
This is a convenient and easy-to-use tool. After installation, you only need to include the header file and re-build it. In addition, this tool will be connected to your program only when you build the debug version. If you build the release version, this tool will not affect your program performance or other aspects. So you can always include the header file in your source code.
How visual leak detector works
Let's take a look at the working principle of the tool.
Before that, let's take a look at how Visual C ++'s built-in memory leak detection tool works. Visual c ++ built-in tool CRT debug heap was originally easy to work. When the debug version of malloc is used to allocate memory, malloc records the file name and row number allocated to the memory block in the header. When the program exits, the CRT will perform some cleanup after the main () function returns. In this case, check the debugging heap memory. If the memory is still not released, there must be a memory leak. You can obtain the file name and row number from the headers of these unreleased memory blocks.
This static method can detect the memory leakage and the file name and row number of the leak point, but does not know how the leakage actually occurred, and does not know how the memory allocation statement is executed. To understand this, you must dynamically track the program's memory allocation process. This is what visual leak detector does. It records the context of each memory allocation. When the program exits, it searches for the detected Memory leakage, and converts the recorded context information to report output.

Initialization
Visual leak detector records every memory allocation. How does it monitor memory allocation? Windows provides allocation hooks to monitor the allocation of debugging heap memory. It is a user-defined callback function that is called every time memory is allocated from the debugging heap. During initialization, the visual leak detector registers this hook function with _ crtsetallochook, so that you can monitor all heap memory allocation since then.
How can I ensure that no heap memory is allocated before visual leak detector initialization? Global variables are initialized when the program starts. If visual leak detector is used as a global variable, it can be started with the program. However, C/C ++ does not specify the initialization sequence between global variables. If heap memory allocation exists in the constructors of other global variables, it may not be detected. Visual leak detector uses the # pragma init_seg provided by C/C ++ to reduce the probability of other global variables being initialized before it. According to the definition of # pragma init_seg, the initialization of global variables is divided into three stages: the first is the compiler segment. Generally, the Runtime Library of C language is initialized at this time, and then the Lib segment, it is generally used for initialization of the third-party class library, and the last is the user segment. Most of the initialization tasks are carried out at this stage. Visual leak detector sets its initialization in the compiler segment so that it is initialized before the vast majority of global variables and almost all user-defined global variables.

Record Memory Allocation
An allocation hook function must take the following form:
Int yourallochook (INT alloctype, void * userdata, size_t size, int blocktype, long requestnumber, const unsigned char * filename, int linenumber );
As mentioned above, it is registered during visual leak detector initialization and called each time before memory is allocated from the debugging heap. What this function needs to handle is to record the call stack at this time and the unique ID of the heap memory allocation-requestnumber.
Obtaining the binary representation of the current stack is not very complicated, but the stack content generated by different architectures, compilers, and function call conventions is slightly different, it is a little complicated to explain the stack and obtain the entire function call process. However, Windows provides a stackwritable 64 function to obtain the stack content. The declaration of stack1_64 is as follows:
Bool stack1_64 (
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
);
The stackframe64 structure represents a frame in the stack. The initial stackframe64 is provided. by calling this function repeatedly, you can obtain the call stack of the memory allocation point.
// Walk the stack.
While (count <_ vld_maxtraceframes ){
Count ++;
If (! Pstack1_64 (architecture, m_process, m_thread, & frame, & context,
Null, psymfunctiontableaccess64, psymgetmodulebase64, null )){
// Couldn't trace back through any more frames.
Break;
}
If (frame. addrframe. offset = 0 ){
// End of stack.
Break;
}

// Push this frame's program counter onto the provided callstack.
Callstack-> push_back (dword_ptr) frame. addrpc. offset );
}
So how can we get the initial stackframe64 structure? In the stackframe64 structure, other information is relatively easy to obtain, and the current program counter (EIP) cannot be directly read in the X86 architecture through software. Visual leak detector uses a method to obtain the current program counter. First, if it calls a function, the return address of the function is the current program counter, and the return address of the function can be easily obtained from the stack. The following is a program for visual leak detector to obtain the current program counter:
# If defined (_ m_ix86) | defined (_ m_x64)
# Pragma auto_inline (off)
Dword_ptr visualleakdetector: getprogramcounterx86x64 ()
{
Dword_ptr programcounter;

_ ASM mov axreg, [bpreg + sizeofptr] // get the return address out of the current stack frame
_ ASM mov [programcounter], axreg // put the return address into the variable we'll return

Return programcounter;
}
# Pragma auto_inline (on)
# Endif // defined (_ m_ix86) | defined (_ m_x64)
The call stack must be recorded. Visual leak detector uses a map-like Data Structure to record this information. This allows you to conveniently find the call stack from requestnumber. The alloctype parameter of the allocation hook function indicates the heap memory allocation type, including _ hook_alloc, _ hook_realloc, and _ hook_free. The following code processes various situations using Visual leak detector.

Switch (type ){
Case _ hook_alloc:
Visualleakdetector. hookmalloc (request );
Break;

Case _ hook_free:
Visualleakdetector. hookfree (pdata );
Break;

Case _ hook_realloc:
Visualleakdetector. hookrealloc (pdata, request );
Break;

Default:
Visualleakdetector. Report ("Warning: Visual leak detector: In allochook (): unhandled allocation type (% d)./N", type );
Break;
}
In this case, the hookmalloc () function gets the current stack and adds the current stack and requestnumber to the data structure similar to map. The hookfree () function deletes this information from a data structure similar to map. The hookrealloc () function calls hookfree () and hookmalloc () in sequence ().

Detect memory leakage
The working principle of the built-in memory leak detection tool in Visual C ++ is mentioned above. Similar to this principle, because global variables are structured in reverse order, when visual leak detector is structured, almost all other variables have been destructed, at this time, if there is still a heap of memory not released, it must be a memory leak.
The allocated heap memory is organized through a linked list, and the check for Memory leakage is to check the linked list. However, Windows does not provide a way to access this linked list. Visual leak detector uses a small trick to get it. First, apply for a temporary memory on the stack. Then, the address of the memory can be converted to a _ crtmemblockheader structure, in which the linked list can be obtained. The Code is as follows:
Char * pheap = new char;
_ Crtmemblockheader * pheader = phdr (pheap)-> pblockheadernext;
Delete pheap;
Pheader is the first pointer of the linked list.

Report Generation
We have discussed how visual leak detector detects, records memory leaks, and its call stack. However, if this information is useful to programmers, it must be converted into a readable form. Visual leak detector uses symgetlinefromaddr64 () and symfromaddr () to generate readable reports.
// Iterate through each frame in the call stack.
For (frame = 0; frame <callstack-> size (); frame ++ ){
// Try to get the source file and line number associated
// This program counter address.
If (psymgetlinefromaddr64 (m_process,
(* Callstack) [frame], & displacement, & sourceinfo )){
...
}

// Try to get the name of the function containing this program
// Counter address.
If (psymfromaddr (m_process, (* callstack) [frame],
& Displacement64, pfunctioninfo )){
Functionname = pfunctioninfo-> name;
}
Else {
Functionname = "(function name unavailable )";
}
...
}
In summary, the work of visual leak detector is divided into three steps: first register a hook function during initialization; then, when the memory is allocated, the hook function is called to record the current scene; finally, check the heap memory allocation linked list to determine whether there is a memory leak and convert the leaked memory into readable output. Interested readers can read the source code of visual leak detector.

Summary
In terms of use, visual leak detector is simple and convenient, and the results report is clear at a glance. In principle, visual leak detector is the right remedy to the memory leakage problem. Isn't Memory leakage easy to detect? The memory allocation is recorded every time, and the general account is calculated when the program exits. When the memory leak occurs, it is not time-out migration, not the leak point at the time? Then we will record the scene and clearly tell the user how the leaked memory is leaked during the call process.
Visual leak detector is an easy-to-use memory leak detection tool. The latest version is 1.9a, which adopts a new detection mechanism and has made many improvements in functions. You may wish to try it out.
 
 
 
Download installer and source code: http://blog.5d.cn/vip/snailman/upload/2006-12/20061220114350421.rar

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/seawen/archive/2009/01/05/3714128.aspx

 

 

Common memory leak check tools: http://www.cnblogs.com/da6wei6/archive/2008/09/07/1286400.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.