Using and understanding the Valgrind core
6
2.4. Reporting of errors
When an error-checking tool detects something bad happening in the program, an error message is written to the
commentary. Here's an example from Memcheck:
==25832== Invalid read of size 4
==25832== at 0x8048724: BandMatrix::ReSize(int, int, int) (bogon.cpp:45)
==25832== by 0x80487AF: main (bogon.cpp:66)
==25832== Address 0xBFFFF74C is not stack'd, malloc'd or free'd
This message says that the program did an illegal 4-byte read of address 0xBFFFF74C, which, as far as Memcheck can
tell, is not a valid stack address, nor corresponds to any current heap blocks or recently freed heap blocks. The read is
happening at line 45 of bogon.cpp, called from line 66 of the same file, etc. For errors associated with an identified
(current or freed) heap block, for example reading freed memory, Valgrind reports not only the location where the
error happened, but also where the associated heap block was allocated/freed.
Valgrind remembers all error reports. When an error is detected, it is compared against old reports, to see if it is
a duplicate. If so, the error is noted, but no further commentary is emitted. This avoids you being swamped with
bazillions of duplicate error reports.
If you want to know how many times each error occurred, run with the -v option. When execution finishes, all the
reports are printed out, along with, and sorted by, their occurrence counts. This makes it easy to see which errors have
occurred most frequently.
Errors are reported before the associated operation actually happens. For example, if you're using Memcheck and your
program attempts to read from address zero, Memcheck will emit a message to this effect, and your program will then
likely die with a segmentation fault.
In general, you should try and fix errors in the order that they are reported. Not doing so can be confusing. For example,
a program which copies uninitialised values to several memory locations, and later uses them, will generate several
error messages, when run on Memcheck. The first such error message may well give the most direct clue to the root
cause of the problem.
The process of detecting duplicate errors is quite an expensive one and can become a significant performance overhead
if your program generates huge quantities of errors. To avoid serious problems, Valgrind will simply stop collecting
errors after 1,000 different errors have been seen, or 10,000,000 errors in total have been seen. In this situation you
might as well stop your program and fix it, because Valgrind won't tell you anything else useful after this. Note that
the 1,000/10,000,000 limits apply after suppressed errors are removed. These limits are defined in m_errormgr.c
and can be increased if necessary.
To avoid this cutoff you can use the --error-limit=no option. Then Valgrind will always show errors, regardless
of how many there are. Use this option carefully, since it may have a bad effect on performance.
2.5. Suppressing errors
The error-checking tools detect numerous problems in the system libraries, such as the C library, which come pre-
installed with your OS. You can't easily fix these, but you don't want to see these errors (and yes, there are many!)
So Valgrind reads a list of errors to suppress at startup. A default suppression file is created by the ./configure
script when the system is built.
You can modify and add to the suppressions file at your leisure, or, better, write your own. Multiple suppression files
are allowed. This is useful if part of your project contains errors you can't or don't want to fix, yet you don't want to
continuously be reminded of them.