Turning to prevent memory leakage using valgrind for checks in Linux

Source: Internet
Author: User
Tags valgrind

For onlineProgramI really don't feel useless, or I won't use it.

========================================================== ========================================================== =

One of the most troublesome problems in C/C ++ development is memory management. Sometimes it takes several days to find a memory leak or a memory access out of bounds, if there is a tool that can help us do this, valgrind is such a tool.

 

Valgrind is a software suite based on a simulated program debugger and analyzer in Linux. It can run on x86, amd64, and ppc32 architectures. Valgrind contains a core that provides a virtual CPU running program and a series of tools for debugging, profiling, and similar tasks. Valgrind is highly modular, so developers or users can add new tools to it without damaging their structures.

 

Valgrind Official Website: http://valgrind.org

You can download the latest valgrind from its website, which is open source code and free of charge.

 

I. Introduction

 

Valgrind contains several standard tools:

 

1. memcheck

 

Memory Management Issues in the memcheck probe. It checks all read/write operations on the memory and intercepts all malloc/New/free/delete calls. Therefore, memcheck can detect the following problems:

 

1) Use uninitialized memory

2) read/write memory released

3) read/write memory out of bounds

4) Inappropriate read/write memory stack space

5) Memory leakage

6) malloc/New/new [] and free/delete/Delete [] do not match.

 

2. cachegrind

 

Cachegrind is a cache parser. It simulates the execution of L1, D1, and L2 cache in the CPU, so it can accurately point outCodeThe cache in is not hit. If you need it, it can print the number of cache hits, memory reference and each line of code in which cache hits are missed, the summary of each function, each module, and the entire program. If you require more detailed information, it can print the number of missed machine codes for each line. On x86 and amd64, cachegrind automatically detects the machine's cache configuration through cpuid, so in most cases it no longer needs more configuration information.

 

3. helgrind

 

Helgrind searches for competing data in multi-threaded programs. Helgrind searches for memory addresses, which are accessed by more than one thread. If no consistent lock is used, it will be detected. This indicates that these addresses are not synchronized during multi-threaded access, which may cause time series problems that are difficult to find.

 

Ii. What does valgrind do to your program?

 

Valgrind is designed to be non-intrusive and work directly on executable files, so you do not need to recompile, connect, and modify your program before checking. To check a program, you only need to execute the following command.

 

Valgrind -- tool = tool_name program_name

 

For example, if we want to perform a memory check on the LS-l command, we only need to execute the following command.

 

Valgrind -- tool = memcheck LS-l

 

No matter which tool is used, valgrind always gets control of your program before it starts, and reads debugging information from the executable Link Library. Then, run the program on the virtual CPU provided by the valgrind core. valgrind processes the code based on the selected tool. The tool adds the detection code to the code, and return the Code as the final code to the valgrind core. Finally, the valgrind core runs the code.

 

To check for Memory leakage, you only need to add -- leak-check = yes. The command is as follows:

 

Valgrind -- tool = memcheck -- leak-check = Yes ls-l

 

Code added between different tools is greatly changed. At the end of each scope, memcheck adds code to check the access and value calculation of each piece of memory. The code size increases by at least 12 times and the running speed is 25 to 50 times slower than usual.

 

Every command in the valgrind simulation program is executed. Therefore, the checking tool and profiling tool are not only for your application, but also for shared libraries, gnu c libraries, and X client libraries.

 

3. Start now

 

First, enable the debugging mode (-G option of the GCC compiler) when compiling the program ). Without debugging information, even the best valgrind tool will be able to guess which function the specific code belongs. Open the debugging option for compilation and then use valgrind for check. valgrind will give you a detailed report, for example, which line of code has memory leakage.

 

When you check the C ++ program, you should also consider another option-fno-inline. It makes the function call chain very clear, which can reduce the confusion when you browse large C ++ programs. For example, when using this option, it is easy to use memcheck to check OpenOffice. Of course, you may not do this, but using this option makes valgrind generate more accurate error reports and reduce confusion.

 

Some compilation optimization options (such as-O2 or higher Optimization Options) may cause memcheck to submit incorrect uninitialized reports. Therefore, to make valgrind reports more accurate, it is best not to use optimization options during compilation.

 

If the program is started using a script, you can modify the code of the Startup Program in the script, or run the script using the -- Trace-Children = YES option.

 

The following is the output report for checking the LS-l command with memcheck. Execute the following command in the terminal:

 

Valgrind -- tool = memcheck LS-l

 

The program prints the result of the LS-l command. The final check report of valgrind is as follows:

 

= 4187 =

= 4187 = Error Summary: 0 errors from 0 contexts (suppressed: 19 from 2)

= 4187 = malloc/free: in use at Exit: 15,154 bytes in 105 blocks.

= 4187 = malloc/free: 310 allocs, 205 frees, 60,093 bytes allocated.

= 4187 = for counts of detected errors, Rerun with:-V

==4187 = searching for pointers to 105 not-freed blocks.

= 4187 = checked 145,292 bytes.

= 4187 =

= 4187 = leak summary:

= 4187 = definitely lost: 0 bytes in 0 blocks.

==4187 = possibly lost: 0 bytes in 0 blocks.

= 4187 = still reachable: 15,154 bytes in 105 blocks.

= 4187 = suppressed: 0 bytes in 0 blocks.

= 4187 = reachable blocks (those to which a pointer was found) are not shown.

= 4187 = to see them, Rerun with: -- show-reachable = Yes

 

Here "4187" refers to the ID of the process that executes LS-l, which is helpful for distinguishing reports of different processes. Memcheck will report how much memory is allocated and released, How much memory is leaked, How much memory is accessible, and how many bytes of memory is checked.

 

The following two examples Use valgrind for memory check:

 

Example 1 (test. C ):

 

 

# Include <string. h> int main (INT argc, char * argv []) {char * PTR; PTR = (char *) malloc (10); strcpy (PTR, "01234567890 "); return 0 ;}

 

Compile the program

 

Gcc-g-o Test test. c

 

Use valgrind to execute the command

 

Valgrind -- tool = memcheck -- leak-check = yes./test

 

The report is as follows:

 

==4270 = memcheck, a memory error detector.

= 4270 = copyright (c) 2002-2006, and gnu gpl 'd, by Julian Seward et al.

= 4270 = Using libvex rev 1606, a library for Dynamic Binary Translation.

= 4270 = copyright (c) 2004-2006, and gnu gpl 'd, by openworks LLP.

= 4270 = Using valgrind-3.2.0, a dynamic binary instrumentation framework.

= 4270 = copyright (c) 2000-2006, and gnu gpl 'd, by Julian Seward et al.

= 4270 = For more details, Rerun with:-V

= 4270 =

==4270 = Invalid write of size 1

= 4270 = at 0x4006190: strcpy (mc_replace_strmem.c: 271)

==4270 = by 0x8048db: Main (test. C: 8)

==4270 = address 0x4023032 is 0 bytes after a block of size 10 alloc 'd

= 4270 = at 0x40044f6: malloc (vg_replace_malloc.c: 149)

==4270 = by 0x80483c5: Main (test. C: 7)

= 4270 =

==4270 = Invalid write of size 1

= 4270 = at 0x400619c: strcpy (mc_replace_strmem.c: 271)

==4270 = by 0x8048db: Main (test. C: 8)

==4270 = address 0x4023033 is 1 bytes after a block of size 10 alloc 'd

= 4270 = at 0x40044f6: malloc (vg_replace_malloc.c: 149)

==4270 = by 0x80483c5: Main (test. C: 7)

= 4270 =

= 4270 = Error Summary: 2 errors from 2 contexts (suppressed: 12 from 1)

= 4270 = malloc/free: in use at Exit: 10 bytes in 1 blocks.

= 4270 = malloc/free: 1 allocs, 0 frees, 10 bytes allocated.

= 4270 = for counts of detected errors, Rerun with:-V

= 4270 = searching for pointers to 1 not-freed blocks.

= 4270 = checked 51,496 bytes.

= 4270 =

= 4270 =

==4270 = 10 bytes in 1 blocks are definitely lost in loss record 1 of 1

= 4270 = at 0x40044f6: malloc (vg_replace_malloc.c: 149)

==4270 = by 0x80483c5: Main (test. C: 7)

= 4270 =

= 4270 = leak summary:

= 4270 = definitely lost: 10 bytes in 1 blocks.

==4270 = possibly lost: 0 bytes in 0 blocks.

= 4270 = still reachable: 0 bytes in 0 blocks.

= 4270 = suppressed: 0 bytes in 0 blocks.

= 4270 = reachable blocks (those to which a pointer was found) are not shown.

= 4270 = to see them, Rerun with: -- show-reachable = Yes

 

From this report, we can see that the process number is 4270, And the write memory of row 8th of test. C is out of bounds. The strcpy function causes the write memory to be out of bounds,

The 7th rows leak 10 bytes of memory, causing memory leakage of the malloc function.

 

Example 2 (test2.c)

 

 

# Include <stdio. h> int Foo (int x) {If (x <0) {printf ("% d", x);} return 0 ;}int main (INT argc, char * argv []) {int X; Foo (x); Return 0 ;}

 

Compile the program

 

Gcc-g-o Test2 test2.c

 

Use valgrind for memory check

 

Valgrind -- tool = memcheck./Test2

 

The output report is as follows:

 

==4285 = memcheck, a memory error detector.

= 4285 = copyright (c) 2002-2006, and gnu gpl 'd, by Julian Seward et al.

= 4285 = Using libvex rev 1606, a library for Dynamic Binary Translation.

= 4285 = copyright (c) 2004-2006, and gnu gpl 'd, by openworks LLP.

= 4285 = Using valgrind-3.2.0, a dynamic binary instrumentation framework.

= 4285 = copyright (c) 2000-2006, and gnu gpl 'd, by Julian Seward et al.

= 4285 = For more details, Rerun with:-V

= 4285 =

= 4285 = conditional jump or move depends on uninitialised value (s)

= 4285 = at 0x8048372: Foo (test2.c: 5)

==4285 = by 0x80483b4: Main (test2.c: 16)

= 4285 = p

= 4285 = Error Summary: 1 errors from 1 contexts (suppressed: 12 from 1)

= 4285 = malloc/free: in use at Exit: 0 bytes in 0 blocks.

= 4285 = malloc/free: 0 allocs, 0 frees, 0 bytes allocated.

= 4285 = for counts of detected errors, Rerun with:-V

= 4285 = all heap blocks were freed -- no leaks are possible.

 

From this report, we can see that the PID of the process is 4285, And the foo function is called in line 2 of the test2.c file. The Foo function in line 3 of the test2.c file uses an uninitialized variable.

 

Valgrind has many other options to use. For more information, see the man manual page of valgrind and the online documentation of valgrind official website.

 

Related Article

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.