「条件付きジャンプまたは移動は初期化されていない値に依存します」という valgrind メッセージの特定 質問する

「条件付きジャンプまたは移動は初期化されていない値に依存します」という valgrind メッセージの特定 質問する

そのため、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 は初期化されていない float でした。ただし、その時点では報告されず、値が印刷されるまでエラーは発生しませんでした。この動作を変更する Valgrind の設定はありますか?

ベストアンサー1

valgrindオプションを使用する--track-origins=yes to have it track the origin of uninitialized values. This will make it slower and take more memory, but can be very helpful if you need to track down the origin of an uninitialized value.

Update: Regarding the point at which the uninitialized value is reported, the valgrind manual states:

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.

From the Valgrind FAQ:

As for eager reporting of copies of uninitialised memory values, this has been suggested multiple times. Unfortunately, almost all programs legitimately copy uninitialised memory values around (because compilers pad structs to preserve alignment) and eager checking leads to hundreds of false positives. Therefore Memcheck does not support eager checking at this time.

おすすめ記事