| Valgrind 3.3 - Advanced Debugging and Profiling for GNU/Linux applications by J. Seward, N. Nethercote, J. Weidendorfer and the Valgrind Development Team Paperback (6"x9"), 164 pages ISBN 0954612051 RRP £12.95 ($19.95) |
6.3.2 Things to watch out for
Some odd things that can occur during annotation:
-
If annotating at the assembler level, you might see
something like this:
1 0 0 . . . . . . leal -12(%ebp),%eax 1 0 0 . . . 1 0 0 movl %eax,84(%ebx) 2 0 0 0 0 0 1 0 0 movl $1,-20(%ebp) . . . . . . . . . .align 4,0x90 1 0 0 . . . . . . movl $.LnrB,%eax 1 0 0 . . . 1 0 0 movl %eax,-16(%ebp)
How can the third instruction be executed twice when the others are executed only once? As it turns out, it isn't. Here's a dump of the executable, using ‘objdump -d’:8048f25: 8d 45 f4 lea 0xfffffff4(%ebp),%eax 8048f28: 89 43 54 mov %eax,0x54(%ebx) 8048f2b: c7 45 ec 01 ... movl $0x1,0xffffffec(%ebp) 8048f32: 89 f6 mov %esi,%esi 8048f34: b8 08 8b 07 08 mov $0x8078b08,%eax 8048f39: 89 45 f0 mov %eax,0xfffffff0(%ebp)
Notice the extra ‘mov %esi,%esi’ instruction. Where did this come from? The GNU assembler inserted it to serve as the two bytes of padding needed to align the ‘movl $.LnrB,%eax’ instruction on a four-byte boundary, but pretended it didn't exist when adding debug information. Thus when Valgrind reads the debug info it thinks that the ‘movl $0x1,0xffffffec(%ebp)’ instruction covers the address range 0x8048f2b--0x804833 by itself, and attributes the counts for the ‘mov %esi,%esi’ to it. - Inlined functions can cause strange results in the function-by-function summary. If a function ‘inline_me()’ is defined in ‘foo.h’ and inlined in the functions ‘f1()’, ‘f2()’ and ‘f3()’ in ‘bar.c’, there will not be a ‘foo.h:inline_me()’ function entry. Instead, there will be separate function entries for each inlining site, i.e. ‘foo.h:f1()’, ‘foo.h:f2()’ and ‘foo.h:f3()’. To find the total counts for ‘foo.h:inline_me()’, add up the counts from each entry. The reason for this is that although the debug info output by gcc indicates the switch from ‘bar.c’ to ‘foo.h’, it doesn't indicate the name of the function in ‘foo.h’, so Valgrind keeps using the old one.
- Sometimes, the same filename might be represented with a relative name and with an absolute name in different parts of the debug info, e.g.: ‘/home/user/proj/proj.h’ and ‘../proj.h’. In this case, if you use auto-annotation, the file will be annotated twice with the counts split between the two.
- Files with more than 65,535 lines cause difficulties for the Stabs-format debug info reader. This is because the line number in the ‘struct nlist’ defined in ‘a.out.h’ under Linux is only a 16-bit value. Valgrind can handle some files with more than 65,535 lines correctly by making some guesses to identify line number overflows. But some cases are beyond it, in which case you'll get a warning message explaining that annotations for the file might be incorrect. If you are using gcc 3.1 or later, this is most likely irrelevant, since gcc switched to using the more modern DWARF2 format by default at version 3.1. DWARF2 does not have any such limitations on line numbers.
- If you compile some files with ‘-g’ and some without, some events that take place in a file without debug info could be attributed to the last line of a file with debug info (whichever one gets placed before the non-debug-info file in the executable).
This list looks long, but these cases should be fairly rare.
| ISBN 0954612051 | Valgrind 3.3 - Advanced Debugging and Profiling for GNU/Linux applications | See the print edition |