Categories
Uncategorized

Valgrind memory leak detection tools

Memory leak Profile

What is a memory leak

Memory leaks (Memory Leak) refers to the procedures that have been dynamically allocated heap memory for some reason, the program does not release or not release, resulting in a waste of system memory, causing the program to run slower and even system crashes and other serious consequences. Memory leak has a hidden defect, cumulative feature, error detection more difficult than other illegal memory access. Because the cause of memory leaks memory block is not released, belong to the missing type defects rather than fault-type defects. In addition, the memory leak error symptoms usually do not have a direct observable, but gradually accumulate, reducing overall system performance, system crash may cause in extreme cases.

Mode memory leaks generated

A way to generate classification, memory leaks can be divided into four categories:

    Recurrent memory leak: A memory leak occurs in the code will be executed multiple times to, each time resulting in a memory leak when it is executed.

    Occasional memory leak: Code memory leak occurs only under certain environmental or process operation will occur. Recurrent sporadic and are opposed. For a particular environment, sporadic perhaps it becomes often made of. So the test environment and test methods to detect memory leaks is essential.

    One-time memory leak: A memory leak occurs in the code will only be executed once, or due to defects in the algorithm, there is always one and only cause a memory leak.

    Implicit memory leak: non-stop program allocates memory during operation, but only until the end of free memory. Strictly speaking, a memory leak did not happen here, because the release of the final program memory of all applications. But for a server program, you need to run a few days, weeks or even months, not timely release of memory can also cause all memory eventually run out of the system. So, we call this type of implicit memory leaks memory leaks. From the perspective of the user program’s point of view, the memory leak itself does not generate any harm, as a general user, do not feel the presence of a memory leak. Real harm is the accumulation of memory leaks, it will eventually run out of memory systems. From this perspective, a one-time memory leaks and no harm, because it does not accumulate, and the dangers implicit memory leaks is very large, as compared to Recurrent episodic memory leaks and it is more difficult to be detected .

Valgrind

Brief introduction

Valgrind is a tool for system debugging and analyzing Linux GPL programs. The workers use Valgrind suite, you can automatically detect many memory management and threading errors, make the program more stable. You can also perform detailed analysis to help accelerate the implementation of the program. Valgrind is Julian Seward works. Valgrind is a program debugging and analysis tools running on a Linux-based simulation technology, it contains a kernel, a software synthesizer’s CPU, and a range of gadgets. As shown below:

installation

CentOS installation:

# sudo yum install valgrind -y

Ubuntu installation:

# sudo apt install valgrind -y

The sample program

A simple example is given malloc.c.

#include
#include
void fun()
{
         int *x = malloc(10 * sizeof(int));
         x[10] = 0;
}
int main()
{
         int i = 99;
         fun();
         printf("i = %d\n",i);
         return 0;
}

There are two problems above code:

    No free resources out of the application;

    fun function inside the bounds, x [10] is illegal.

Memcheck

Is the most commonly used small tools to detect memory problems that appear in the program, will all read and write to memory is detected, all calls to malloc and free is captured, it can detect the following questions:

    Uninitialized memory usage;

    Read / write memory block after release;

    Read / write block of memory allocated by malloc exceeded;

    Read / write memory block inappropriate stack;

    Memory leaks, pointer points to a memory forever lost;

    Incorrect malloc / free or new / delete match;

    memcpy correlation function pointers overlap src and dst;

Memcheck gadgets we use to detect problems. Compile: gcc -Wall -o malloc malloc.c detection: valgrind ./malloc –show-reachable = [default: no] –leak-check = full to see more details

Where 34496 is the process ID of the program is running. Invalid write of size 4: Illegal written representation (cross-border), the following is the position to tell us the error occurred, fun function call in main. HEAP SUMMARY: illustrates the case where the stack can be seen applied for 40 bytes, an application that there behind, 0 is free. LEAK SUMMARY: also said the leaks heap, obviously missing 40 bytes. If i is not initialized in the main, there will be some other error.

# gcc -Wall -o malloc malloc.c                                                                     
malloc.c: In function ‘main’:
malloc.c:22:16: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]   # 未初始化变量
          printf("i = %d\n",i);                                                                                            
                ^
[[email protected] memcheck]# valgrind ./malloc                                                                                
==34555== Memcheck,a memory error detector                                                                                 
==34555== Copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.                                                   
==34555== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info                                                
==34555== Command: ./malloc                                                                                                 
==34555==                                                                                                                   
==34555== Invalid write of size 4                                                                                           
==34555==    at 0x40057B: fun (in /root/memcheck/malloc)                                                                    
==34555==    by 0x400594: main (in /root/memcheck/malloc)                                                                   
==34555==  Address 0x5203068 is 0 bytes after a block of size 40 alloc'd                                                    
==34555==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)                                                                 
==34555==    by 0x40056E: fun (in /root/memcheck/malloc)
==34555==    by 0x400594: main (in /root/memcheck/malloc)
==34555== 
==34555== Conditional jump or move depends on uninitialised value(s)
==34555==    at 0x4E80B9E: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
==34555== Use of uninitialised value of size 8
==34555==    at 0x4E7E26B: _itoa_word (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E824F0: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
==34555== Conditional jump or move depends on uninitialised value(s)
==34555==    at 0x4E7E275: _itoa_word (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E824F0: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
==34555== Conditional jump or move depends on uninitialised value(s)
==34555==    at 0x4E8253F: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
==34555== Conditional jump or move depends on uninitialised value(s)
==34555==    at 0x4E80C6B: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
==34555== Conditional jump or move depends on uninitialised value(s)
==34555==    at 0x4E80CEE: vfprintf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4E893E8: printf (in /usr/lib64/libc-2.17.so)
==34555==    by 0x4005A8: main (in /root/memcheck/malloc)
==34555== 
i = 0
==34555== 
==34555== HEAP SUMMARY:
==34555==     in use at exit: 40 bytes in 1 blocks
==34555==   total heap usage: 1 allocs,0 frees,40 bytes allocated
==34555== 
==34555== LEAK SUMMARY:
==34555==    definitely lost: 40 bytes in 1 blocks
==34555==    indirectly lost: 0 bytes in 0 blocks
==34555==      possibly lost: 0 bytes in 0 blocks
==34555==    still reachable: 0 bytes in 0 blocks
==34555==         suppressed: 0 bytes in 0 blocks
==34555== Rerun with --leak-check=full to see details of leaked memory
==34555== 
==34555== For counts of detected and suppressed errors,rerun with: -v
==34555== Use --track-origins=yes to see where uninitialised values come from
==34555== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 0 from 0)

View Code

Callgrind

Gprof analysis and similar tools, but run the program it was observed more nuanced, provide more information to give us. And different gprof, it is not necessary to add additional special option when compiling the source code, but with the debug option is recommended. Callgrind some data collection program is run, the establishment of a function call graph can also be carried cache simulation choices. At the end of the run, it will analyze the data written to a file, callgrind_annotate this document can be converted to a readable form.

Callgrind can help us to run the program were observed.

# valgrind --tool=callgrind ./malloc

  

It can be seen to generate a file callgrind.out.34755, the same process ID 34755 when the program is run. When callgrind run your program, you can also use callgrind_control to observe the implementation of the program, and does not interfere with its operation. For more information on the program is displayed:

# callgrind_annotate callgrind.out.34755

  

Cachegrind

Cache analyzer, which simulates the CPU cache I1, DI, and the secondary cache, the program can accurately indicated loss and the cache hit. If necessary, it also provides us with the number of cache misses, memory citations, and every line of code, the number of instructions for each function, each module generates the entire program, which is very helpful to the optimizer.

# valgrind --tool=cachegrind ./mallo

Helgrind

Used to detect competition problems arise in multi-threaded programs. Helgrind seeking access to the internal memory threads, but not consistently locked area. These areas tend to be the event of loss of synchronization between threads, and can lead to errors that are difficult excavation. Helgrind achieve a detection algorithm called “Eraser” competition, and made further improvements to reduce the number of reporting errors. But Helgrinf still in the experimental stage.

Massif

Stack analyzer can measure the stack program uses how much memory, tell us heap block, management block heap and stack size. Massif can help us to reduce memory usage, virtual memory in alternative modern systems, it can also speed up run our program, a program to reduce the chance of staying in the exchange zone.

In addition, lackey and nulgrind also provided. Lackey is a small tool, rarely used; Nulgrind just goes to show developers how to create a tool.

reference

Linux C ++ program under several memory leak checking tool https://blog.csdn.net/gatieme/article/details/51959654 Linux memory leak detection tools under valgrind https://cloud.tencent.com/developer/article / 1075945 Valgrind debugging http://www.voidcn.com/article/p-xyrqgaum-yq.html

Leave a Reply