Есть ли в любом случае сообщение valgrind «Условный переход или перемещение зависит от неинициализированного значения» может быть так называемым «ложным срабатыванием» - PullRequest
9 голосов
/ 08 декабря 2011

Большинство вопросов, которые я нахожу здесь, содержат фрагмент кода, на который кто-то указывает на фактическую ошибку.Мой вопрос об условных переходах на неинициализированные значения в целом.Я могу понять, что часть памяти не обязательно очищать в конце программы, если кто-то уверен, что это выделение выполняется только один раз и, вероятно, потребуется в течение жизни программы.Насколько я помню, система GType оставляет много несвободной памяти при завершении программы.Эти несвободные блоки можно рассматривать как «ложные срабатывания».Но может ли «условный переход или переход к неинициализированному значению» быть ложноположительным?Единственное, что я могу придумать, - это кто-то, реализующий (плохую) функцию рандомизации, просто читая случайный адрес (где сам случайный адрес является сложной частью;).Другим примером может быть аппаратное сопоставление части памяти, которая затем читается, но в основном это выполняется драйверами, а не обычными пользовательскими приложениями.Есть ли другой пример (предпочтительно C), который может вызвать такой ложный положительный результат?

Ответы [ 2 ]

7 голосов
/ 08 декабря 2011

Что сообщает valgrind, так это то, что он видит скачок на основе чтения из местоположения, для которого он знает, что он был выделен программой, но для которого он не видел инициализацию. Это может произойти, если объект инициализируется некой магией, о которой не знает Вэлгринд. Архитектура постоянно развивается, и, возможно, у вас есть инструкция или тип регистра, о котором valgrind не знает достаточно.

Другим трудным источником таких неинициализаций являются union с. Два источника:

  • По умолчанию для них инициализируется только первый элемент и так когда другое поле выходит за пределы этого первого члена, эта часть может быть неинициализированный.
  • Если члены union являются struct, они могут иметь отступы байты в разных местах, и поэтому часть члена может быть неинициализирован, если вы назначены другому участнику.

В некоторых случаях может быть законным даже прочитать эти вещи (например, через unsigned char[]), поэтому, если вы считаете такие вещи ошибкой (ложное срабатывание) или нет, это вопрос перспективы.

5 голосов
/ 09 декабря 2011

Абсолютно!Однажды у меня был C-код вида

// compute a and, possibly, b
if (a && b) {
    // do stuff
}

, в котором b гарантированно инициализировался, если a было истиннымТаким образом, не было способа, чтобы неинициализированное значение b могло вызвать проблему.Однако gcc при достаточно агрессивной оптимизации решил сначала проверить значение b.Это было приемлемо, так как ни у одной проверки не было побочных эффектов, но это все еще заставляло valgrind жаловаться.

...