определение "условный переход или перемещение зависит от неинициализированных значений" valgrind сообщение
Итак, я получаю какое-то таинственное неинициализированное сообщение Valgrind, и это было довольно загадочно, откуда взялось плохое значение.
кажется, что valgrind показывает место, где используется unitialized значение, но не происхождение неинициализированного значения.
==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)
как видно, он становится довольно загадочным.. тем более, что когда он говорит по классу::MethodX, он иногда указывает прямо на ostream и т. д. Возможно, это за счет оптимизации?
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
просто так. Есть ли что-то, что я упускаю? Каков наилучший способ поймать плохие ценности, не прибегая к сверхдлинной детективной работе printf?
обновление:
я узнал, что было не так, но странная вещь, valgrind не сообщил об этом, когда плохое значение было впервые использовано. Он был использован в функции умножения:
movespeed = stat.speedfactor * speedfac * currentbendfactor.val;
где speedfac был unitialized плыть. Однако в то время это не было сообщено и не до тех пор, пока значение не будет напечатано, что я получаю ошибку.. Есть ли параметр для valgrind, чтобы изменить это поведение?
2 ответов:
используйте опцию valgrind
--track-origins=yesчтобы он отслеживал происхождение неинициализированных значений. Это сделает его медленнее и займет больше памяти, но может быть очень полезно, если вам нужно отследить происхождение неинициализированного значения.обновление: относительно точки, в которой сообщается неинициализированное значение,в руководстве valgrind указано:
важно понимать, что ваша программа может копировать вокруг мусора (неинициализированные) данные столько, сколько ему нравится. Memcheck наблюдает за этим и отслеживает данные, но не жалуется. Жалоба выдается только тогда, когда ваша программа пытается использовать неинициализированные данные таким образом, что это может повлиять на внешне видимое поведение вашей программы.
С Valgrind FAQ:
что касается нетерпеливого сообщения копий неинициализированных значений памяти, это было предложено несколько раз. К сожалению, почти все программы законно копируют неинициализированные значения памяти вокруг (потому что компиляторы накладывают структуры для сохранения выравнивания), и нетерпеливая проверка приводит к сотням ложных срабатываний. Поэтому Memcheck не поддерживает нетерпеливую проверку в это время.
это означает, что вы пытаетесь распечатать/вывести значение, которое по крайней мере частично неинициализировано. Можете ли вы сузить его, чтобы точно знать, что это такое? После этого проследите свой код, чтобы увидеть, где он инициализируется. Скорее всего, вы увидите, что он не полностью инициализирован.
Если вам нужна дополнительная помощь, размещение соответствующих разделов исходного кода может позволить кому-то предложить больше руководство.
EDIT
Я вижу, вы нашли проблему. Обратите внимание, что valgrind часы для условный переход или переезд на основе unitialized переменных. Это означает, что он будет выдавать предупреждение только в том случае, если выполнение программы изменяется из-за неинициализированного значения (т. е. например, программа принимает другую ветвь в операторе if). Поскольку фактическая арифметика не включала в себя условный прыжок или перемещение, valgrind не делал этого предупреждаю тебя об этом. Вместо этого он распространил статус "неинициализированный" на результат оператора, который его использовал.
может показаться нелогичным, что он предупреждает вас не сразу, а как mark4o указано, что это происходит потому, что неинициализированные значения используются в C все время (примеры: заполнение в структурах,
realloc()звонок и т. д.) таким образом, эти предупреждения не будут очень полезны из-за ложной положительной частоты.
Comments