Use Valgrind to discover memory leaks and illegal memory operations

Source: Internet
Author: User
Tags garbage collection memory usage valgrind

Original address: http://www.cprogramming.com/debugging/valgrind.html

The translation will inevitably be due to personal level and there are inaccurate places, please more criticism, the above is the original link, we can also go directly to see.

Valgrind is a multi-purpose code review and memory debugging tool for Linux platforms. It can run your program in Valgrind's own environment, monitoring malloc/free, (New/delete for C + +) and other memory calls. If you use uninitialized memory, the array is written out of bounds, or you forget the free pointer, Valgrind detects them. Since these are some of the most common problems of the day, this article mainly describes how to use Valgrind to find such simple memory problems, although valgrind can do more.


For Windows users, if you don't have access to a Linux machine, or if you want to develop a Windows program, you might be more interested in IBM's Purity software, purity is similar to Valgrind features in detecting memory problems, and you can download it yourself.


Get Valgrind

If you are running Linux and do not have Valgrind installed, you can download it from valgrind download page.

Installation is very simple, only need to decompress on it. (XYZ in the following example is the meaning of the version number)

bzip2-d valgrind-xyz.tar.bz2
tar-xf Valgrind-xyz.tar
The above operation will create a directory, named VALGRIND-XYZ, switch to this directory, run the following command

./configure make make
install
Now that you have installed the Valgrind, let's see how to use it


using Valgrind to find memory leaks

A memory leak is one of the hardest bugs to detect because it doesn't show any external problems until you run out of memory and have a malloc failure. In fact, when we work in a language that doesn't have a garbage collection mechanism like C + +, almost half of the time is spent dealing with the problem of free memory correctly. If your program runs long enough and runs to that code branch, even an error is costly.


When you run your code with Valgrind, you need to specify what tools to use Valgrind, and simply run Valgrind and you'll get the current list. In this article, we mainly use the Memcheck tool, the Memcheck tool can guarantee our correct memory usage. Without additional parameters, Valgrind will print a generalized message calling call and malloc (note that 18490 is the process ID on my system; it is different at different runtimes)

% valgrind--tool=memcheck program_name
...
=18515== malloc/free:in use at exit:0 bytes in 0 blocks.
==18515== malloc/free:1 Allocs, 1 frees, bytes allocated.
==18515== for a detailed leak analysis,  rerun with:--leak-check=yes
If you have a memory leak, the number of alloc and free will be different (you can't release a piece of memory that belongs to more than one alloc). We'll come back later to see this profile, but for now, note that some errors are being stopped because they come from the standard library, not from your code.


If the number of alloc and free is different, you need to use the option--leak-check to rerun the program. This will show you all the calls that don't match the free malloc/new.

To illustrate, I used a simple program that I compiled into an executable file "example1"

#include <stdlib.h>
int main ()
{
    char *x = malloc;/* or, in C + +, "char *x = new CHAR[100] */
    R Eturn 0;
}
% Valgrind--tool=memcheck--leak-check=yes example1

This produces some information about the program shown above, generates a list, calls malloc but does not have the corresponding free.

==2116== bytes in 1 blocks is definitely lost in loss record 1 of 1
==2116== at    0x1b900dd0:malloc (Vg_replac e_malloc.c:131)
==2116== by    0x804840f:main (In/home/cprogram/example1)
This does not tell us as much as we would like, although we know that this memory leak is the discovery of a call to malloc in main, but we do not know the line number. This problem is because we did not compile with the GCC-G option, which adds debug symbols. So we recompile and get the more useful information below.

==2330== bytes in 1 blocks is definitely lost in loss record 1 of 1
==2330== at    0x1b900dd0:malloc (Vg_replac e_malloc.c:131)
==2330== by    0x804840f:main (Example1.c:5)
Now we know the exact line number, where this leak of memory is allocated. While it's still a problem to track down to free, at least we know where to start. And since you have a plan for every malloc or new call, you have plans to deal with this memory, knowing where the memory leaks will let you know where to start looking for problems.


Sometimes, the option--leak-check=yes will not show you all the memory leaks. To find all the unpaired calls to free and new, you need to use the option--show-reachable=yes. Its output is basically the same, but it will show you more unfreed of memory.


Using valgrind to find illegal pointers used

Valgrind uses the Memcheck tool to discover the use of illegal heap memory. For example, if you assign an array with malloc or new, and then try to access the outer bounds of the array:

Char *x = malloc (ten);
X[10] = ' a ';
The Valgrind will detect. For example, run the following program with Valgrind Example2

#include <stdlib.h>

int main ()
{
    char *x = malloc (ten);
    X[10] = ' a ';
    return 0;
}
How to run:

Valgrind--tool=memcheck--leak-check=yes example2
The result is:

==9814==  Invalid Write of size 1
==9814== at    0x804841e:main (example2.c:6)
==9814==  Address 0x1ba3607a is 0 bytes after a block of size alloc ' d
==9814== at    0x1b900dd0:malloc (vg_replace_malloc.c:131) 
  ==9814== by    0x804840f:main (Example2.c:5)
The results above tell us that we are crossing the border using a pointer that is assigned a 10bytes space, and the result is a ' Invalid write '. If we try to read the data from that memory, we will be warned ' Invalid read of size X ', where x is the size of the memory we are trying to read (it is 1 for char type, and 2 or 4 for int). Typically, Valgrind will print out the stack information for the function call, and we will know exactly where the error occurred.


Using Valgrind to detect uninitialized variables

Valgrind also has a purpose, which can detect the use of uninitialized values in conditional statements. Although you should get used to initializing a variable, Valgrind will help you find the places you forget. For example, run the following EXAMPLE3 code:

#include <stdio.h>

int main ()
{
    int x;
    if (x = = 0)
    {
        printf ("X is zero");/* Replace with cout and include 
                                iostream for C + +/
    }
    return 0;
  
   }

  
The result is:

==17943== Conditional Jump or move depends on uninitialised value (s)
==17943== at    0x804840a:main (example3.c:6 )
Valgrind will be smart enough to know if a variable is assigned a value with an uninitialized variable, for example, the following code:

#include <stdio.h>

int foo (int x)
{
    if (x < ten)
    {
        printf ("X is less than 10\n");
    }
}

int main ()
{
    int y;
    Foo (y);
}
The results are as follows:

==4827== Conditional Jump or move depends on uninitialised value (s)
==4827== at    0x8048366:foo (example4.c:5) 
  ==4827== by    0x8048394:main (example4.c:14)
You might think that the problem is in the Foo function, and the stack information is not important. However, since main passed an uninitialized value to the Foo function (you never assign a value to Y), we look for the problem and track the variable's assignment stack until we find an uninitialized variable.

This will only help you when your program goes to that branch, especially the conditional statements. So make sure you get the program to walk through all the branches when testing.


other issues that Valgrind can find

Valgrind detects some other inappropriate memory usage: If you free a pointer two times, the Valgrind will be detected for you; you will get the following error:

Invalid free ()
and follow a few related stacks

Valgrind also detects that the wrong method was selected when releasing memory. For example, in C + +, there are 3 basic methods of releasing dynamic memory: free,delete,delete[]. The free function only matches malloc, delete matches only new, delete[] matches only new[]. (although some compilers handle this type of error delete for you, there is no guarantee that all compilers will, it is not required).

If you trigger such a problem, you will get an error:

Mismatched free ()/Delete/delete []

This is a must to fix, even if your program happens to work.


something Valgrind can't find.

Valgrind cannot check the bounds of a static array (the space allocated on the stack). So, if you declare an array in your function

int main ()
{
    char x[10];
    X[11] = ' a ';
}
Well, Valgrind won't warn you. A solution that might be used for testing purposes is to convert your static array to dynamically allocate memory from the heap, where you need to do boundary detection, but this produces a lot of unfreed memory.


other warning messages that have been more

What is the disadvantage of valgrind? It consumes more memory--twice as much as the memory your source program needs. If you are detecting a large memory problem, then this may cause some problems. It will take a longer time to run your program. This usually shouldn't be a problem, and it's just an impact when you're testing. But if you're running a program that's already slow, this could be a problem.


Summary

Valgrind is a tool for x86 and AMD64 structures that runs in a Linux environment. It allows the programmer to run the program in its environment, so it can detect non-paired malloc and other problems that use illegal memory (such as uninitialized memory) or illegal memory operations (such as repeating the free same piece of memory and invoking the wrong destructor). Valgrind cannot detect static memory issues.


The level is limited, if has the friend found the mistake, welcome the message exchange.
Reprint please keep this article link, if think my article can help you, please top. Thank you.



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.