让valgrind显示常见错误

时间:2014-02-08 02:55:38

标签: c debugging valgrind

我用--track-origins = yes运行valgrind,所以我假设它会显示有关未初始化变量的错误,如下所示: valgrind --track-originins = yes ./pointer 还可以在各种文件中永久编辑valgrind的设置吗?

我运行的代码是:

#include <stdio.h>
int main(){
   int age = 10;
   int height;
   printf("I am %d years old.\n");
   printf("I am %d inches tall.\n");

return 0;

}

这是我从valgrind

的结果
==12005== Memcheck, a memory error detector
==12005== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==12005== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==12005== Command: ./pointer
==12005== 
I am -16776936 years old.
I am 2147483633 inches tall.
==12005== 
==12005== HEAP SUMMARY:
==12005==     in use at exit: 0 bytes in 0 blocks
==12005==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==12005== 
==12005== All heap blocks were freed -- no leaks are possible
==12005== 
==12005== For counts of detected and suppressed errors, rerun with: -v
==12005== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

我期待这样的事情(来自'艰难的学习')

==3082== Memcheck, a memory error detector
==3082== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3082== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3082== Command: ./ex4
==3082== 
I am -16775432 years old.
==3082== Use of uninitialised value of size 8
==3082==    at 0x4E730EB: _itoa_word (_itoa.c:195)
==3082==    by 0x4E743D8: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E730F5: _itoa_word (_itoa.c:195)
==3082==    by 0x4E743D8: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E7633B: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s)
==3082==    at 0x4E744C6: vfprintf (vfprintf.c:1613)
==3082==    by 0x4E7E6F9: printf (printf.c:35)
==3082==    by 0x40052B: main (ex4.c:11)
==3082== 
I am 0 inches tall.
==3082== 
==3082== HEAP SUMMARY:
==3082==     in use at exit: 0 bytes in 0 blocks
==3082==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3082== 
==3082== All heap blocks were freed -- no leaks are possible
==3082== 
==3082== For counts of detected and suppressed errors, rerun with: -v
==3082== Use --track-origins=yes to see where uninitialised values come from
==3082== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)

2 个答案:

答案 0 :(得分:0)

一般来说,我不认为Valgrind会检测到这些东西是保证。如果获取但未传递的varargs来自堆栈,那么堆栈的那部分可能只是“偶然”初始化。

但是,在这种特殊情况下,您可能会看到AMD64 ABI的影响,而您引用的示例似乎是x86(从地址不大于32位判断)。由于AMD64 ABI在寄存器中最多传递六个参数,printf甚至不会触及内存来获取参数,直到你给它更多。

例如,我尝试了这个程序:

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%i %i %i %i %i %i %i\n");
    return(0);
}

只有六个%i规格,Valgrind没有任何警告,而有七个,我收到警告。我很确定这是因为参数在寄存器中传递。

(但我承认,我认为6 %i规范应该已经足够了,但是看看格式字符串本身如何消耗一个寄存器。我无法解释这种效果。除非,正如我上面提到的,第一个非寄存器参数恰好已经在内存中初始化了。)

答案 1 :(得分:0)

我忍不住注意到你的printf调用实际上并没有使用这些变量。你注意到了吗?

这可能是它无法正常工作的原因。