gpt4 book ai didi

c - 为什么 valgrind memcheck 找不到错误?

转载 作者:行者123 更新时间:2023-12-02 09:05:19 26 4
gpt4 key购买 nike

我以前没有使用过 valgrind,但我认为它应该可以检测到一些内存错误。

我的代码:

#include <stdio.h>
unsigned int a[2];

int main()
{
a[-1] = 21;

printf("%d,", a[-1]);

return 1;
}

如您所见,我正在访问我不应该访问的 a[-1]

我如何使用 valgrind?

我正在使用 gcc -g -O0 codeFile.c 进行编译

并执行:valgrind -s ./a.out

结果是:

==239== Memcheck, a memory error detector

==239== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

==239== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info

==239== Command: ./a.out

==239== 21,==239==

==239== HEAP SUMMARY:

==239== in use at exit: 0 bytes in 0 blocks

==239== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated

==239==

==239== All heap blocks were freed -- no leaks are possible

==239==

==239== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

valgrind 不应该发现这些错误,还是我用错了?

编辑:似乎 valgrind memcheck 对全局变量没有做任何事情,并且正如答案/评论中所建议的那样,它应该使用远离指针的索引,因此:我删除了全局声明并将其添加到 main 中,并访问了 a[-10] 而不是 a[1]。相同的行为。

int main()
{
unsigned int a[2];
a[-10] = 21;

printf("%d,", a[-10]);

return 1;
}

不过,如果我使用 [-100],它实际上会抛出错误。怎么回事?

编辑 2

此外,为什么这没有错误

while (i <= 2)
{
j = a[i];
i++;
}

但是这样

while (i <= 2)
{
printf("%d,", a[i]);
i++;
}

最佳答案

Valgrind 通常 can't find memory errors其中被修改的内存与当前堆栈指针或内存的负偏移量与内存中的另一个变量重合。

例如,如果 a 在堆栈上,a[3] 将触发 memchecka[-1] 不会,因为据 Valgrind 所知,它很容易成为有效内存。

为了进一步说明这一点,这里引用了文档中我强调的内容:

In this example, Memcheck can't identify the address. Actually the address is on the stack, but, for some reason, this is not a valid stack address -- it is below the stack pointer and that isn't allowed.

这句话实际上是部分不正确的;当它说“低于堆栈指针”时,它实际上意味着与堆栈指针的正偏移,或者干扰另一个函数的堆栈内存。

我还应该注意到(从您的第二次编辑)Valgrind 实际上并没有提示,直到以某种有意义的方式使用该值。在 Valgrind 看来,赋值并不是以有意义的方式使用值。这是我强调的另一句话来支持这一点:

It is important to understand that your program can copy around junk (uninitialised) data as much as it likes. Memcheck observes this and keeps track of the data, but does not complain. A complaint is issued only when your program attempts to make use of uninitialised data in a way that might affect your program's externally-visible behaviour.

因为 a 是一个全局变量,你将很难检查它的内存。我之前使用过的一个 Valgrind 工具是 exp-sgcheck (实验性静态和全局变量检查),尽管我发现它不可靠(很可能是因为它是实验性的)。

检测这些问题的一种更简单、更好的方法是启用编译器警告或使用静态分析器(我最喜欢的是 LLVM 的 scan-build)。

关于c - 为什么 valgrind memcheck 找不到错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59338783/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com