Saturday, October 9, 2010

Valgrind for dummies to experts

Well... not really for experts; experts will know better than me.

Valgrind is a framework for dynamic analysis tools. As far as we are concerned, it is something that helps us remove those nasty segmentation faults and unnoticeable bugs.

If you believe that there is some wrong array indexing somewhere but can't find out where, then valgrind is the perfect tool for you.

The use of valgrind is simple.

1. Compile your code with the -g flag.
gcc abc.c -g -Wall
OR
g++ abc.cpp -g -Wall

2. Run with valgrind
valgrind ./a.out
OR
valgrind ./a.out <input

That's it.

Now what you need to know is how to understand the output.
The first few(around 5) lines are not interesting to us.

After that you will see the output of your code and the list of errors.
Most of the time, you should be looking for these lines :
1. Invalid write/read of size 4
It mostly means that you are accessing array index beyond the size of the array.

2. Conditional jump or move depends on uninitialised value(s)
It means you are having something like this :
int a;
if( a > 5 ) { // do stuff
}

You have not given any value to a.
If you try to print some uninitialized value, you will get this error message 4-5 times. You can identify it by seeing that there is a "printf" in each of these.

The most important part is the line just after the above messages. It looks something like this :

==8050== Invalid write of size 4
==8050== at 0x804841A: fun (val.c:5)
==8050== by 0x804844A: main (val.c:15)


It means that the error was at line 5 in the file abc.c, inside the function fun(), which was in turn called by main at line 15.

Valgrind is not perfect in finding array index overflows, especially when it comes to static arrays. Sometimes, running it with the following option may give better results :

valgrind ./a.out --tool=exp-ptrcheck