首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >精确定位“条件跳转或移动取决于未初始化的值”valgrind消息

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

Stack Overflow用户
提问于 2010-04-10 14:10:26
回答 2查看 241.2K关注 0票数 184

所以我从valgrind得到了一些神秘的未初始化的值消息,关于坏值是从哪里来的,这是相当神秘的。

似乎valgrind显示了使用单一化值的位置,但没有显示未初始化值的来源。

==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侦测工作的最佳方法是什么?

更新:

我发现了问题所在,但奇怪的是,valgrind在第一次使用坏值时没有报告它。它被用在乘法函数中:

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

其中speedfac是一个单一化的浮动。但是,当时没有报告,直到要打印该值时,我才得到错误。是否有针对valgrind的设置来更改此行为?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-10 14:40:49

使用valgrind选项--track-origins=yes让它跟踪未初始化值的来源。这将使它变得更慢并占用更多内存,但如果您需要跟踪未初始化值的来源,则会非常有用。

更新:关于报告未初始化值的点,the valgrind manual states

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

Valgrind FAQ

对于未初始化内存值的副本的急切报告,这已经被多次建议。不幸的是,几乎所有的程序都会合法地复制未初始化的内存值(因为编译器会填充结构以保持对齐),而急切的检查会导致数百次误报。因此,Memcheck目前不支持即时检查。

票数 254
EN

Stack Overflow用户

发布于 2010-04-10 14:14:03

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

如果你需要更多的帮助,张贴源代码的相关部分可能会让别人提供更多的指导。

编辑

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

它没有立即警告您,这似乎有悖于直觉,但正如mark4o指出的那样,它之所以这样做,是因为在C中总是使用未初始化的值(例如:结构中的填充、realloc()调用等)。因此,由于误报频率的原因,这些警告将不是很有用。

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2612447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档