Valgrind not showing line numbers in spite of -g flag (on Ubuntu 11.10/VirtualBox)

djb picture djb · Feb 17, 2012 · Viewed 56.4k times · Source

I'm following 'Learn C the Hard Way', specifically the chapter on Valgrind. This chapter gives you a deliberately wrong program to show how Valgrind works.

When I run the exercise under Valgrind I do not get line numbers in my stack trace, just '(below main)' for the errors.

I am definitely compiling with the -g flag.

My Valgrind output is as follows:

djb@twin:~/projects/Learning/C$ valgrind ./ex4
==5190== Memcheck, a memory error detector
==5190== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5190== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==5190== Command: ./ex4
==5190== 
==5190== Use of uninitialised value of size 4
==5190==    at 0x4078B2B: _itoa_word (_itoa.c:195)
==5190==    by 0x407CE55: vfprintf (vfprintf.c:1619)
==5190==    by 0x40831DE: printf (printf.c:35)
==5190==    by 0x4052112: (below main) (libc-start.c:226)
==5190== 
==5190== Conditional jump or move depends on uninitialised value(s)
==5190==    at 0x4078B33: _itoa_word (_itoa.c:195)
==5190==    by 0x407CE55: vfprintf (vfprintf.c:1619)
==5190==    by 0x40831DE: printf (printf.c:35)
==5190==    by 0x4052112: (below main) (libc-start.c:226)
==5190== 
==5190== Conditional jump or move depends on uninitialised value(s)
==5190==    at 0x407CC10: vfprintf (vfprintf.c:1619)
==5190==    by 0x40831DE: printf (printf.c:35)
==5190==    by 0x4052112: (below main) (libc-start.c:226)
==5190== 
==5190== Conditional jump or move depends on uninitialised value(s)
==5190==    at 0x407C742: vfprintf (vfprintf.c:1619)
==5190==    by 0x40831DE: printf (printf.c:35)
==5190==    by 0x4052112: (below main) (libc-start.c:226)
==5190== 
I am 0 years old.
I am 68882420 inches tall.
==5190== 
==5190== HEAP SUMMARY:
==5190==     in use at exit: 0 bytes in 0 blocks
==5190==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5190== 
==5190== All heap blocks were freed -- no leaks are possible
==5190== 
==5190== For counts of detected and suppressed errors, rerun with: -v
==5190== Use --track-origins=yes to see where uninitialised values come from
==5190== ERROR SUMMARY: 22 errors from 4 contexts (suppressed: 11 from 6)

I'm using Ubuntu 11.10 in a VirtualBox VM.

Thank you for any help.

Update

It seems that if I call a function from main() and that function contains a mistake (eg an uninitialized variable), then I do get a trace to the place that function was called in main(). However errors within main() remain unspecified. See this paste for an example.

Answer

user811773 picture user811773 · Mar 5, 2012

The output you provided in your question contains the following line:

==5190== Use --track-origins=yes to see where uninitialised values come from

Per this message you should run ./ex4 like this:

valgrind --track-origins=yes ./ex4

To avoid some problems with Valgrind unable to find debug information, you can use static linking:

gcc -static -g  -o ex4  ex4.c 

Valgrind's output will then contain messages like Uninitialised value was created by a stack allocation:

==17673== Memcheck, a memory error detector
==17673== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==17673== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==17673== Command: ./ex4
...
==17673== Use of uninitialised value of size 4
==17673==    at 0x805CA7B: _itoa_word (in /home/user/ex4)
==17673==    by 0x8049D5F: printf (in /home/user/ex4)
==17673==    by 0x8048ECD: main (ex4.c:8)
==17673==  Uninitialised value was created by a stack allocation
==17673==    at 0x8048EFA: bad_function (ex4.c:17)
...
==17673== Use of uninitialised value of size 4
==17673==    at 0x805CA7B: _itoa_word (in /home/user/ex4)
==17673==    by 0x8049D5F: printf (in /home/user/ex4)
==17673==    by 0x80490BE: (below main) (in /home/user/ex4)
==17673==  Uninitialised value was created by a stack allocation
==17673==    at 0x8048EBE: main (ex4.c:4)
...
I am -1094375076 years old.
...
I am -1094369310 inches tall.
...
==17673== 
==17673== HEAP SUMMARY:
==17673==     in use at exit: 0 bytes in 0 blocks
==17673==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17673== 
==17673== All heap blocks were freed -- no leaks are possible
==17673== 
==17673== For counts of detected and suppressed errors, rerun with: -v
==17673== ERROR SUMMARY: 83 errors from 21 contexts (suppressed: 0 from 0)

File ex4.c:

 1  #include <stdio.h>
 2
 3  int main()
 4  {
 5          int age = 10;
 6          int height;
 7
 8          bad_function();
 9
10          printf("I am %d years old.\n");
11          printf("I am %d inches tall.\n", height);
12
13          return 0;
14  }
15
16  int bad_function() 
17  {
18          int x;
19          printf("%d\n", x);
20  }

Valgrind's output isn't ideal. It identifies the stack frame (function) containing the uninitialized variable, but it does not print the name of the variable.

Running Linux under VirtualBox has no effect on Valgrind.