精确定位“条件跳转或移动取决于未初始化的值”的缬草消息

所以我一直收到一些神秘的未初始化的价值观信息,从瓦尔格伦和它一直是相当神秘的坏价值从何而来。

看起来瓦尔格林展示了统一化值最终被使用的地方,而不是未初始化值的起源。

==11366== Conditional jump or move depends on uninitialised value(s)
==11366==    at 0x43CAE4F: __printf_fp (in /lib/tls/i686/cmov/libc-2.7.so)
==11366==    by 0x43C6563: vfprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366==    by 0x43EAC03: vsnprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366==    by 0x42D475B: (within /usr/lib/libstdc++.so.6.0.9)
==11366==    by 0x42E2C9B: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366==    by 0x42E31B4: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366==    by 0x42EE56F: std::ostream& std::ostream::_M_insert<double>(double) (in /usr/lib/libstdc++.so.6.0.9)
==11366==    by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
==11366==    by 0x810B9F1: Snake::Snake::update() (snake.cpp:257)
==11366==    by 0x81113C1: SnakeApp::updateState() (snakeapp.cpp:224)
==11366==    by 0x8120351: RoenGL::updateState() (roengl.cpp:1180)
==11366==    by 0x81E87D9: Roensachs::update() (rs.cpp:321)

可以看出,它变得相当神秘。.特别是当它说到 Class: : MethodX 时,它有时直接指向 ostream 等。也许这是由于优化?

==11366==    by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)

就像这样。有什么我不知道的吗?什么是抓住不良价值观的最佳方法,而不必诉诸于超长的 printf 侦查工作?

< em > 更新:

我发现了问题所在,但奇怪的是,当坏价值第一次被使用时,瓦尔格林并没有报告。它被用在一个乘法函数中:

movespeed = stat.speedfactor * speedfac * currentbendfactor.val;

Speedfac 是一个统一的浮动。但是,当时没有报告这个错误,直到要打印这个值时,我才得到这个错误。.有没有什么方法可以改变他的这种行为?

277229 次浏览

这意味着您正在尝试打印/输出一个至少部分未初始化的值。你能缩小一下范围,这样你就能准确地知道它的价值了吗?之后,跟踪代码以查看其初始化位置。您可能会看到它没有被完全初始化。

如果您需要更多的帮助,发布源代码的相关部分可能会让某人提供更多的指导。

剪辑

看来你找到问题所在了。请注意,基于单一化变量的 条件跳跃或移动值表。这意味着,如果程序的执行由于未初始化的值(即。例如,程序在 if 语句中使用不同的分支)。由于实际的算术没有涉及到条件跳跃或移动,瓦尔格林没有警告你这一点。相反,它将“未初始化”状态传播到使用它的语句的结果。

看起来似乎有点违反直觉,它并没有立即发出警告,但是正如 Mark4o指出的那样,它这样做是因为未初始化的值一直在 C 语言中使用(例如: 结构中的填充,realloc()调用,等等) ,所以由于错误的正频率,这些警告不会很有用。

使用 valgray 选项 --track-origins=yes让它跟踪未初始化值的原点。这将使它变慢并占用更多内存,但是如果您需要跟踪未初始化值的原点,这将非常有帮助。

关于报告未初始化值的点,《瓦尔冈手册》规定:

了解您的程序可以随心所欲地复制垃圾(未初始化)数据,这一点很重要。Memcheck 注意到这一点,并跟踪数据,但没有抱怨。只有当程序试图以一种可能影响程序外部可见行为的方式使用未初始化的数据时,才会发出投诉。

来自 瓦尔冈常见问题解答:

对于未初始化内存值的副本的急切报告,已经多次提出这种建议。不幸的是,几乎所有的程序都合法地复制未初始化的内存值(因为编译器垫结构来保持对齐) ,并且急切地检查会导致数百个错误的结果。因此 Memcheck 此时不支持热切检查。