Valgrind不显示行号,尽管使用了-g标志(在Ubuntu 11.10 / VirtualBox上)

69

我正在跟随《用最笨的方法学C语言》,具体地说是关于Valgrind的章节。这一章提供了一个故意写错的程序,以展示Valgrind的工作原理。

当我在Valgrind下运行练习时,我的堆栈跟踪中没有行号,只有“(below main)”表示错误。

肯定使用-g标志进行编译。

我的Valgrind输出如下:

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)

我在 VirtualBox VM 中使用的是 Ubuntu 11.10。

感谢任何帮助。

更新

看起来,如果我从 main() 调用一个函数并且该函数包含错误(例如未初始化的变量),那么我会获得一个跟踪到在 main() 中调用该函数的位置。然而,在 main() 中的错误仍未指定。请参见此粘贴板以获取示例。


请创建一个新的空目录,并将您在http://pastebin.com/A6bK2hdw找到的内容放入该目录中;这是一个尝试重新创建问题的bash脚本。当我运行它时,我会得到像http://pastebin.com/JncWz2GF中所看到的输出,这是您的教程应该得到的输出。请自己运行它。如果您得到了正确的输出,请确定您的操作方式与此shell脚本有何不同。如果您运行此shell脚本并得到了错误的输出,就回来让我们讨论一下。 - Bill Evans at Mariposa
3
我遇到了同样的问题,使用相同的操作系统和虚拟机VirtualBox。我尝试了valgrind 3.6.1 和 3.7.0,但都不能在使用-g选项时显示行号。 - Chris
1
我猜问题可能与VirtualBox本身有关。我不熟悉VirtualBox。我建议您在问题中添加VirtualBox标签,看看是否有什么解决方案浮出水面。如果这没有帮助,请尝试联系http://forums.virtualbox.org的专家寻求帮助。很抱歉我无法提供更多帮助。 - Bill Evans at Mariposa
1
刚在我的Mac OSX上测试了与我Ubuntu/VBox设置相同的版本,它在Mac上完美运行。我认为Bill可能是对的,这可能要么是VBox的问题,要么是Ubuntu的问题。 - Chris
你是在使用ubuntu(x86)吗?我已经在ubuntu(x64)上尝试了valgrind,它运行得非常完美。我认为“学习C语言的困难之路”的作者也在x64平台上使用valgrind,因为他的文章显示int的大小为8。 - jason
显示剩余8条评论
7个回答

65
您在问题中提供的输出包含以下行:
==5190== Use --track-origins=yes to see where uninitialised values come from

根据此消息,您应该这样运行./ex4

valgrind --track-origins=yes ./ex4

为了避免 Valgrind 找不到调试信息的一些问题,您可以使用静态链接:
gcc -static -g  -o ex4  ex4.c 

Valgrind的输出将包含类似于未初始化的值是由堆栈分配创建的的消息:

==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)

文件 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的输出并不理想。它可以确定包含未初始化变量的堆栈帧(函数),但不会打印变量的名称。

在VirtualBox下运行Linux对Valgrind没有影响。


19
即使你已经上了阅读课,你仍然不能解决问题。这个答案并没有解决任何问题。在教程中,Valgrind的输出显示了未初始化变量被使用的行数。这与通过--track-origins=yes给出的输出非常不同......由于最初的问题是如何在Ubuntu上获得与教程相同的输出,所以问题应该仍然是开放的......顺便说一下,在Ubuntu 11.10上(不是通过虚拟机)运行valgrind 3.7.0时完全相同的问题。 - justin

19

我也使用了-g标志进行编译,但仍然无法得到行号。删除我应用程序的.dSYM目录,并使用--dsymutil=yes选项运行valgrind后,我最终获得了行号。


1
那只是针对OS X的。 - Lenar Hoyt
1
在Ubuntu中, valgrind --track-origins=yes --dsymutil=yes ./FILE_NAME 可以解决问题,而我使用了 -g 标志进行编译。 - Minh Triet

2

我追踪了这个问题,但其他答案都没有起作用。我的输出显示了正确的符号,但行号不在。

在我的情况下,是由于所使用的库使用了.zdebug压缩的行号信息,而我使用的valgrind版本过旧,尚未安装所需的补丁[0]。

解决方法是升级到最新版本的valgrind。

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


2

在许多发行版中,glibc的默认版本不包含调试符号。

尝试安装libc6-dbg软件包。


1

你应该使用"-g"编译它。 gcc -g test.c -o test 然后运行 valgrind --track-origins=yes --leak-check=full ./test


4
“我 肯定 会使用 -g 标志进行编译。” -- 引用自 OP。 - DevSolar

1
请注意,使用--dsymutil=yes选项运行valgrind仅适用于Mac OS X。
根据文档:
--dsymutil=no|yes [no] 此选项仅在Mac OS X上运行Valgrind时才相关。
Mac OS X使用延迟调试信息(debuginfo)链接方案。 当包含debuginfo的对象文件链接到.dylib或可执行文件时,debuginfo不会被复制到最终文件中。相反,必须手动运行dsymutil,这是一个系统提供的实用程序,对可执行文件或.dylib进行链接。生成的组合debuginfo放置在与可执行文件或.dylib相邻的目录中,但扩展名为.dSYM。

0

尝试使用gcc而不是cc

cc不提供行号,但gcc提供


2
cc 只是系统 C 编译器的符号链接,而这个编译器很可能就是 GCC。 - Oliver Tušla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接