Valgrind сообщает об «использовании неинициализированного значения размера 4» при использовании strlen

#c #raspberry-pi #valgrind

#c #raspberry-pi #valgrind

Вопрос:

Я пытаюсь использовать Valgrind на Raspberry Pi. Я анализирую следующую программу:

 #include <string>
#include <cstring>

int main() {
    std::string blaat = "blaat";
    const char * buf = blaat.c_str();
    size_t l = 0;
    l = strlen(buf);
    printf("string size %un", l);
}
  

Компиляция:

 g   -g -Wall -O0 test.cpp
  

Анализ (valgrind-3.16.1):

 valgrind --leak-check=yes ./a.out
  

Результат:

 ==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4866210: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x48662DC: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==29572==
==29572== Use of uninitialised value of size 4
==29572==    at 0x4AABF6C: _itoa_word (_itoa.c:179)
==29572==    by 0x4AB0727: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4AABF74: _itoa_word (_itoa.c:179)
==29572==    by 0x4AB0727: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4AAF8FC: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4AAF99C: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4AAFA00: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
==29572==
==29572== Conditional jump or move depends on uninitialised value(s)
==29572==    at 0x4AAFA7C: vfprintf (vfprintf.c:1637)
==29572==    by 0x4AB646F: printf (printf.c:33)
==29572==    by 0x1088F: main (test.c:10)
  

Как только я использую «strlen», Valgrind, похоже, выдает мне предупреждения о неинициализированных значениях. Почему?

Комментарии:

1. Имеет ли значение, используете ли вы %zu для size_t вместо %u для unsigned int? В качестве альтернативы, static_cast<unsigned int>(l) .

2. Обе альтернативы не изменили вывод Valgrind — по-прежнему выдаются предупреждения

3. предполагая, что вы хотите заставить их замолчать: wiki.wxwidgets.org/Valgrind_Suppression_File_Howto

4. Именно так работает glibc на ARM, я постоянно получаю эти ошибки. Я предполагаю, что это из соображений производительности. Страницы всегда выравниваются по размеру, кратному 4 байтам, поэтому обычно не помешает проверить сразу 4 байта на strlen() . Мы используем подавление valgrind в качестве обходного пути.

5. Вывод strlen используется, например. в качестве параметра для функции sendbuffer (data, sz). Теперь Valgrind также сообщит, что эта функция использует неинициализированные байты. Поэтому вместо добавления strlen в файл suppressions я должен добавить sendbuffer в файл suppressions. Однако именно эти функции я хочу проверить.