Optimization 优化如何消除误报?

Optimization 优化如何消除误报?,optimization,valgrind,Optimization,Valgrind,引用Valgrind教程: 优化的代码可能会导致valgrind错误地报告未初始化的值错误。作者知道如何解决这个问题,但这会使valgrind的速度慢得多(而且已经相当慢了)。建议的解决方法是在尝试使用valgrind调试代码时不要进行优化。不管怎样,调试时不进行优化是一个很好的经验法则 (来源:) 什么类型的优化会导致这种情况,它们如何不是真正的问题 什么类型的优化会导致这种情况,它们如何不是真正的问题 一个特定的实例:glibc有strlen() 确定指针是4字节对齐的,并且 一次读取4个

引用Valgrind教程:

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

(来源:)

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

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

一个特定的实例:glibc有
strlen()

  • 确定指针是4字节对齐的,并且
  • 一次读取4个字节,然后使用位旋转技巧确定这4个字节中是否有一个是0
这是“安全的”,因为它永远不会导致崩溃(从4字节对齐的指针读取4字节永远不会跨越页面边界),但它可能会“过度读取”超过分配的块的末尾(例如,如果字符串来自
strdup(“hello”)
——这里只分配了6个字节,而
strlen
将读取8个字节)

现在,这个特定实例对Valgrind来说不是问题,因为它将
strlen
重定向到自己的副本


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

“它们怎么不是真正的问题?”Valgrind用于在源代码中查找问题。它是通过查看目标代码来实现这一点的,但是如果源代码中没有问题,并且看起来只有通过查看目标代码才可能有问题,那么这是一个误判,没有什么需要修复的。我的意思是,我希望优化不允许破坏东西。。。因此,警告并不表明存在真正的问题。它们是编译器知道不会影响程序输出的未初始化数据的真正用途,还是Valgrind跟踪事物的方式的人工制品?需要记住的一点是,汇编是“更定义的”汇编指令可以有一个定义良好的含义,即使它们看起来像是C指令的直译,而不是。为了说明(虽然我认为这个例子太简单,不能像ValgReD手册所讨论的那样),但是把指令<代码> XOR Reg,Reg < /C>作为函数的第一个指令,其中代码> Reg < /C> >是一个调用方保存登记器。此装配说明始终是合法的。它可以是
intx的非优化翻译;x^=x(非法C)。或者它可以是
intx=0的优化翻译
Valgrind可能会警告
xor reg,reg
认为它对应于
int x;x^=x,但如果程序是通过优化编译的,则此指令实际上对应于一个安全的源代码级构造
intx=0。(再说一遍,我不认为这是一个实际的例子,但实际的例子可能与此类似。)