Valgrind: the memory error detector

David Lee's picture

C/C++ programming language provide powerful memory operating ability through pointers, and programmers can make efficient and flexible control to low-level memory. However, dynamic memory errors become one of the toughest part to debug. Almost every programmers have suffered segmentation fault or memory leak problem. Those errors which only appear at the run-time and can be detected by the compiler spend a lot of development time. Fortunately, there are many memory profiling tool can help programmers find the bugs effectively. Valgrind, the topic of this article, is one of these convenient tools.

Valgrind is a open source dynamic analysis software, which can be used to detect memory, cache and threading bugs, can use branch-prediction function to profile program performance, or even to plugin external tools to make more detailed program testing. This article only introduces the memory error detection function of Valgrind.

First we need a program to be detected, of course. Suppose we write a source code as follows (this code is cited by the Valgrind website,) and name it “test.c”.

1 #include <stdlib.h>
3 void f(void)
4 {
5 int* x = malloc(10 * sizeof(int));
6 x[10] = 0; // problem 1: heap block overrun
7 } // problem 2: memory leak -- x not freed
9 int main(void)
10 {
11 f();
12 return 0;
13 }

Then we compile it with “-g”, and don’t set any optimized option such as “-O1” to avoid the report of Valgrind shows inaccurate line number. So the compiled command can be:

gcc -g test.c -o test

If Valgrind has been installed (it’s trivial, just download and make!) then we can start to perform the memory detection. Just type the following command:

valgrind --leak-check=full --log-file=debug.log ./test
  1. “--leak-check=full” option turns on the completed memory leak detection 
  2. “--log-file=debug.log” means detection report will be saved in “debug.log”
  3. The final parameter of this command is the executing command of the program which we want to detect 

Now we can check the report. It’s complicated, we just need to highlight two points as follows:

  1. “==XXXXX==” means the process id is XXXXX  
  2. “Invalid write of size 4” tells which line of the source code make a mistake. Obviously, there is a access violation in “test.c:6”, we assigned some value to illegal position of the heap.
  3. ”40 bytes in 1 blocks are definitely lost in loss record 1 of 1” means there is a memory leakage, and the report also show that it is because we use a “malloc” function in “test.c:5” without responding “free”.

As above we perform a simple usage of Valgrind. The many other functions can be referenced to documents of the official website.