Valgrind is powerful
memory checker
that can detect use of uninitialised memory and
memory leaks. Instructions for installing and running are given
Caution: We have several examples where Valgrind has failed to find a leak.
In such cases, consider MemCheck as well.
Select/create a suitable directory in which to build Valgrind. e.g.
cd /minos/software/OO/minos_packs
- Get Valgrind from
http://valgrind.kde.org.
- Unpack it. For example 2.4.0:-
bunzip2 valgrind-2.4.0.tar.bz2
tar xvf valgrind-2.4.0.tar
- Decide where to install it e.g.:-
setenv $INSTALLATION /minos/software/OO/minos_packs_pplxgen/
- Configure it:-
cd valgrind-2.4.0
./configure --prefix=$INSTALLATION
It should end by saying something like:-
Using the following suppressions by default:
glibc-2.2.supp xfree-3.supp xfree-4.supp
Valgrind finds problems in both glibc and X and since you don't want
to fix them (or indeed know about them) thoughtfully provides a
suppression file that will prevent it reporting problems in these areas.
- Build and install it:-
gmake
gmake install
- If the build and install have worked properly you should have a web brows-able
$INSTALLATION/share/doc/valgrind/manual.html
which is well worth reading carefully (well after having a little play perhaps)
and the binary valgrind should be in:-
$INSTALLATION/bin
although if you a using a C based shell you may need to rehash before it gets picked up.
- Try a quick test:-
valgrind ls -l
This tests the ls command which should only take a few seconds to run
and may even find some problems! It also demonstrates a great feature
of Valgrind - it's totally non-invasive.
See also an introductory talk On Valgrind.
Valgrind works by running the code under test on a "synthetic CPU"
i.e. by emulation, so the code runs an order of magnitude slower than
normally. Unless you actually want to test out the database interface,
it is a good idea to set up the DBI so that it gets as much data as
possible from the level 2 cache. If you are not sure how to do this
then the easiest way is to:-
- Create a cache directory e.g.:-
mkdir /minos/software/dbi_cache
- Signal the DBI to use the cache:-
setenv ENV_DBI "Level2Cache = '/minos/software/dbi_cache'"
- Run a very short loon job i.e.:-
loon -bq my_script.C date_file
where my_script.C is the script you want to test and has something like:-
cr.Path("Reco").Run(10);
- run 10 event. Check afterwards that the directory is populated with .dbi_cache files.
Run Valgrind with the following command:-
valgrind --tool=memcheck\
--db-attach=yes\
--gen-suppressions=yes \
--suppressions=root.supp \
--error-limit=no \
--leak-check=yes \
loon -bq my_script.C date_file
As the above shows, the command syntax is:-
valgrind --tool=name valgrind-options command command-options
Now we will look at each Valgrind option in turn.
- --tool=memcheck
Select the Valgrind tool called memcheck which is the heavyweight memory checker.
There are several other possible tools e.g. Addrcheck, Cachegrind, etc.
- --db-attach=yes
This tells Valgrind to ask if you want to
launch the debugger each time it finds a problem. One of the powerful
features of Valgrind is that it catches the error before it
happens so if you agree to run the debugger you get to debug just in
time.
One slight down side is that it takes a little while for the debugger
to load all the sharable libraries and when you have finished in the
debugger you have to leave and return to Valgrind by typing:-
quit
so have to go through the reload each time you choose to debug a problem.
- --gen-suppressions=yes
This tells Valgrind to ask if you want to print out a suppression
string each time it finds a problem. These suppression strings can be
added to a file that can be used to suppress reporting of further
problems of this type in future runs of Valgrind.. An example might
be:-
{
<insert a suppression name here>
Memcheck:Cond
fun:_ZNK13PerRecordTags10IsCompleteEv
fun:_ZN14PerInputStream8NextTagsEv
fun:_ZN21PerInputStreamManager17AdvanceRecordTagsEv
fun:_ZN21PerInputStreamManager4NextEP12MomNavigatorj
}
Valgrind only reports each problem once so you won't get floods of
messages coming from a single problem.
- --suppressions=root.supp
Valgrind has it's own suppression files, which are generated when you
install Valgrind so would be appropriate to mask problems for the
system on which it is installed. You can add further ones for example
root.supp.
- --error-limit=no
By default when Valgrind has seen 300 different types of error or
30000 errors in total it treats your program as a lost cause and tells
you to go and fix it. This option prevents it bailing out.
- --leak-check=yes
By default when Valgrind terminates, it skips leak checking. Use this
option to force post execution leak analysis.
- loon -bq my_script.C date_file
This isn't a Valgrind option of course but the command you want to analyse.
There are a number of other options and it really is worth studying:-
$INSTALLATION/share/doc/valgrind/manual.html
For example you will learn the reason why Valgrind only reports the
use of uninitialised data when it's use changes the course of the
program. For example:-
int a;
int b = a;
int c = b > 0 ? 1 : 2;
a is undefined and Valgrind is perfectly happy to let it's undefined
value get propagated into b. Its only when coming to define c, where a
test on the value of b is made, does it complain.
|