почему valgrind обнаруживает неинициализированные значения только так поздно - PullRequest
0 голосов
/ 01 марта 2020

Я хочу понять сообщения журнала valgrind и использовать следующий код

#include <iostream>

int main()
{
 int numbers[] = {1,2,3,4,5,6,7,8,9,10};
 int length = sizeof(numbers) / sizeof(numbers[0]);
 std::cout << "length: " << length << std::endl;
 for (int i = 0; i < length + 10; ++i)
 {
     int number = numbers[i];
     if (number > 5)
     {
         std::cout << number << " is greater than 5" << std::endl;
     } else {
         std::cout << number << " is less or equal 5" << std::endl;
     }

 }

}

для получения неинициализированных значений. Если я запускаю программу в valgrind, я не получаю соответствующего сообщения. Если я запускаю for-l oop для длины + 10, valgrind обнаруживает неинициализированные значения.

Почему valgrind обнаруживает неинициализированные значения только так поздно?

==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x108A3C: main (arrays.cpp:11)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F43C0A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Use of uninitialised value of size 8
==2484==    at 0x4F4370E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F4371B: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F43C66: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)

РЕДАКТИРОВАТЬ: я изменил код. Это весь код, который я использовал. компилировать: массивы g ++ - c -g3. * массивы 1015 *. cpp valgrind: valgrind --tool = memcheck --track-originins = yes --num-callers = 100 --log-file = uv_log.txt ./arrays

РЕДАКТИРОВАТЬ 2:

length: 10
1 is less or equal 5
2 is less or equal 5
3 is less or equal 5
4 is less or equal 5
5 is less or equal 5
6 is greater than 5
7 is greater than 5
8 is greater than 5
9 is greater than 5
10 is greater than 5
-882498304 is less or equal 5
-188984184 is less or equal 5
1084208 is greater than 5
0 is less or equal 5
85879703 is greater than 5
0 is less or equal 5
0 is less or equal 5

1 Ответ

1 голос
/ 01 марта 2020

Вы на самом деле не проверяете неинициализированный доступ. Вы проверяете индекс за пределами доступа. В вашем случае доступ вне границ находится в стеке, поэтому вы получаете доступ к некоторой памяти, которая находится в стеке. И вам повезло, потому что вся доступная область находится в стеке, поэтому вы не получите неверное чтение. Ваша программа считывает некоторые данные из стека, которые инициализируются для случая length+1 (потому что в него записана какая-то другая вещь, например, это может быть параметр функции, другая локальная переменная или адрес возврата функции), поэтому valgrind не может сообщить о какой-либо ошибке.

Но для случая length+10 он достаточно велик для чтения из неинициализированной памяти. Бьюсь об заклад, если вы увеличите 10 до гораздо большего числа, вы получите недопустимое чтение (что вызывает ошибку сегментации).

...