我正在学习"艰苦学习C",特别是the chapter on Valgrind.本章为您提供了一个故意错误的程序来展示Valgrind的工作原理.

当我在Valgrind下运行这个练习时,我不会在堆栈跟踪中获得行号,只是针对错误的"(在main下方)".

我是definitely岁,带着-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虚拟机中使用Ubuntu11.10.

谢谢你的帮助.

Update

似乎如果我从main()调用一个函数,而该函数包含错误(例如,一个未初始化的变量),那么我do就会跟踪到main()中调用该函数的位置.但是,main()内的错误仍未指定.有关示例,请参见this paste.

推荐答案

您在问题中提供的输出包含以下行:

==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的yields 并不理想.它标识包含未初始化变量的堆栈帧(函数),但不打印变量的名称.

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

C++相关问答推荐

如何将一个integer与一个数组进行比较?

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

为什么静态说明符为内联函数生成外部定义?

将 typewriter LF打印到Windows终端,而不是隐含的CR+LF

为什么GCC C23中的关键字FALSE不是整数常量表达式?

如何在不使用其他数组或字符串的情况下交换字符串中的两个单词?

在我的代码中,我需要在哪里编写输出函数?

在C语言中,是否可以使枚举数向后计数?

Flose()在Docker容器中抛出段错误

解决S随机内存分配问题,实现跨进程高效数据共享

为什么函数是按照定义的顺序执行的,而不是按照从avr-c中的int main()调用的顺序执行的?

关于scanf()和空格的问题

预处理器宏扩展(ISO/IEC 9899:1999(E)§;6.10.3.5示例3)

如何确保我将使用C标准库函数的函数版本,如&getc";,而不是类似函数的宏版本?

程序如何解释变量中的值

在Ubuntu上使用库部署C程序的最佳实践

x86-64平台上的int_fast8_t大小与int_fast16_t大小

GnuCobol 使用 double 类型的参数调用 C 函数

运行以下 C 程序时出现分段错误

int 与 size_t 与 long