优化如何避免 valgrind 误报?

问题描述 投票:0回答:2

引用 Valgrind 教程:

优化的代码可能会导致 valgrind 错误地报告未初始化值错误。作者知道如何解决这个问题,但这会使 valgrind 变慢(而且它已经相当慢了)。建议的修复方法是在尝试使用 valgrind 调试代码时不进行优化。无论如何,调试时不优化是一个很好的经验法则。

(来源:https://people.gnome.org/~newren/tutorials/developing-with-gnome/html/ch03s03.html

什么类型的优化会导致这种情况,它们为什么不是真正的问题?

optimization valgrind
2个回答
6
投票

什么类型的优化会导致这种情况,它们为什么不是真正的问题?

一个具体实例:glibc 有

strlen()

  • 确定指针是 4 字节对齐的并且
  • 一次读取 4 个字节,然后使用位旋转技巧来确定这 4 个字节中是否有一个是 0。

这是“安全的”,因为它永远不会导致崩溃(从 4 字节对齐指针读取 4 个字节永远不会跨越页边界),但它可能会“过度读取”超过已分配块的末尾(例如如果字符串来自

strdup("hello")
- 这里只分配了 6 个字节,但
strlen
将读取 8)。

现在,这个特定实例对于 Valgrind 来说不是问题,因为它将

strlen
重定向到它自己的副本。

但是类似的循环展开可能会发生在您自己的优化代码中,然后 Valgrind 会报告误报。


0
投票

请参阅我在 Reddit 上写的这篇文章:

有关 Valgrind 误报的 Reddit 帖子

我只知道一种情况,优化会导致彻头彻尾的误报。

这是两个链接 std::g++ 可选std::可选的 clang++

问题代码如下

if (f && *f != a)

其中

f
std::optional
。编译器知道
std::optional
位于堆栈上,因此内存是可寻址的。编译器(clang++ 和 g++)通过交换
&&
操作数的顺序来优化这一点。
*f
可能未初始化,但它是可寻址的。当未初始化时,
f
为 false。

Valgrind 尝试恢复原始

if
的语义,但如果原始 RHS 是指针,它(还)无法做到这一点。结果是误报“条件跳转或移动取决于未初始化的值”错误。

© www.soinside.com 2019 - 2024. All rights reserved.