我使用 --track-origins=yes 运行 valgrind,所以我假设它会显示有关未初始化变量的错误,如下所示: valgrind --track-origins=是 ./指针 还可以在各种文件中永久编辑 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)
我期待这样的事情(来自“艰难地学习 c”)
==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)
最佳答案
一般来说,我认为不能保证 Valgrind 会检测到此类事情。如果获取但未传递的可变参数来自堆栈,则堆栈的该部分可能只是“意外”被初始化。
但是,在这种特殊情况下,您可能会看到 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
规范应该已经足够了,但是,考虑到格式字符串本身如何消耗一个寄存器。我不太清楚解释一下这种效果。除非,正如我上面提到的,第一个非寄存器参数恰好已在内存中初始化。)
关于c - 让 valgrind 显示常见错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21641333/