69

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.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
djb
  • 5,591
  • 5
  • 41
  • 47
  • Please create a new, empty directory, and place into that directory what you find at http://pastebin.com/A6bK2hdw ; it's a bash script which attempts to recreate the problem. When I run it, I get output like what you can see at http://pastebin.com/JncWz2GF , which is what your tutorial says you should get. Run it yourself. If you get the proper output, then determine how the way you did it differs from this shell script. If you run this shell script and get the improper output as you show us above, come back and let's discuss it. – Bill Evans at Mariposa Feb 17 '12 at 04:53
  • Hi @Bill, thank you for your help. On running your script I get the same output plus a warning about clock skew. [http://pastebin.com/fjfPrLts](http://pastebin.com/fjfPrLts) – djb Feb 17 '12 at 10:01
  • You mean "the same output" as you got before, or "the same output" as I got? – Bill Evans at Mariposa Feb 17 '12 at 11:49
  • 3
    I'm having the same problem, same OS, same VirtualBox VM. I've tried valgrind 3.6.1 and 3.7.0 and neither displays line numbers with the -g option. – Chris Feb 17 '12 at 15:43
  • 1
    I'm guessing that the problem has something to do with VirtualBox itself. I'm not familiar with VirtualBox. I recommend that you add the VirtualBox tag to your question and see whether something surfaces. If that doesn't help, see whether the folks at http://forums.virtualbox.org can help. Wish I could be of more assistance. Sorry. – Bill Evans at Mariposa Feb 18 '12 at 00:11
  • 1
    Just tested the same version on Mac OSX as my Ubuntu/VBox set up, and it works perfectly on the Mac. I think Bill might be right, it's either something with VBox or something with Ubuntu. – Chris Feb 18 '12 at 00:34
  • Have the same problem here, this is not linked to virtualbox at all. – Benoit Mar 03 '12 at 12:06
  • I'm running Ubuntu 11.10 not in a virtualbox, but installed on the PC. I'm getting "(below main)" as well. I found something related in the valgrind documentation (http://valgrind.org/docs/manual/manual-core.html#manual-core.erropts): `--show-below-main=`. It might have to do with the way glibc works on Ubuntu/GNU..? – Victor Zamanian Mar 03 '12 at 13:06
  • try `-g3` instead of just `-g` [gcc debugging options](http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options) – Trevor Boyd Smith Mar 03 '12 at 13:55
  • Valgrind worked fine for me in Ubuntu 11.10. Using valgrind version valgrind-3.6.1-Debian. gcc version is 4.4.6. glibc version is 2.13-20ubuntu5 I believe. – Justin Peel Mar 03 '12 at 16:08
  • Thanks @Trevor, but I get the same results with `-g3` – djb Mar 04 '12 at 10:50
  • http://stackoverflow.com/questions/8795871/how-to-link-against-debug-versions-of-libc-and-libstdc-in-gcc – Prof. Falken Mar 05 '12 at 09:19
  • Were you using ubuntu(x86)? I've tried valgrind on ubuntu(x64) and it runs perfectly. I think the author of the "learn c the hard way" were also using valgrind on a x64 platform, because his article shows the size of int is 8. – jason May 03 '12 at 02:20

7 Answers7

65

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.

  • 19
    Even if you've had reading lessons you still wouldn't have solved your problem. This answer doesn't solve anything. Valgrind's output in the tutorial gives the line at which the uninitialized variable is being used. That's very different from the output given through --track-origins=yes... and since the original problem was how to get the same output as the tutorials on Ubuntu, the question should still be open... btw same issue exactly running on Ubuntu 11.10 (not through a VM) using valgrind 3.7.0. – justin Jun 08 '12 at 17:38
19

I too was compiling with the -g flag and still not getting line numbers. After removing the .dSYM directory for my app, and running valgrind with the --dsymutil=yes option, I finally got line numbers.

James M
  • 18,506
  • 3
  • 48
  • 56
Jason Denney
  • 3,191
  • 1
  • 18
  • 14
2

I chased this problem and none of the other answers worked. My output displayed the correct symbols, but line numbers were not present.

In my case, it was due to the library in question using .zdebug compressed line number info, and the version of valgrind I was using was old and did not yet have the needed patch [0].

The solution was to upgrade valgrind to the latest version.

[0] https://bugs.kde.org/show_bug.cgi?id=303877

feedbackloop
  • 491
  • 1
  • 6
  • 15
2

On many distros the default version of glibc doesn't contain debug symbols.

Try installing the libc6-dbg package.

wilsaj
  • 21
  • 2
1

you should compile it with "-g" . gcc -g test.c -o test and then valgrind --track-origins=yes --leak-check=full ./test

sam
  • 1,363
  • 1
  • 20
  • 32
1

Note that running valgrind with the --dsymutil=yes solution es just for Mac OS X.

According to the docs:

--dsymutil=no|yes [no] This option is only relevant when running Valgrind on Mac OS X.

Mac OS X uses a deferred debug information (debuginfo) linking scheme. When object files containing debuginfo are linked into a .dylib or an executable, the debuginfo is not copied into the final file. Instead, the debuginfo must be linked manually by running dsymutil, a system-provided utility, on the executable or .dylib. The resulting combined debuginfo is placed in a directory alongside the executable or .dylib, but with the extension .dSYM.

pablomtz
  • 129
  • 7
0

try gcc not cc

cc does not provide the line numbers, but gcc does

Mujju
  • 25
  • 1