valgrind дает неправильный размер неинициализированного - PullRequest
0 голосов
/ 19 февраля 2019

Код sample2.c, который я вижу в блоге для иллюстрации неинициализированного значения с использованием valgrind.Вот код: sample2.c:

 1  #include <stdio.h>
 2  
 3  int main()
 4  {
 5      int a[5];
 6      int i,s;
 7      a[0]=a[1]=a[3]=a[4]=0;
 8      
 9      printf("%d\n",a[2]);
10      for(i=0;i<5;i++)
11      s += a[i];
12      
13      if(s == 377)
14      printf("sum is %d\n",s);
15      return 0;
16  }

с использованием gcc -g -o sample2 sample2.c

valgrind --leak-check = full --track-originins = yes./ sample2

Ниже я получил информацию о проверке valgrind.

Я не понимаю, почему в моей машине используется неинициализированное значение размера 8 из-за sizeof (int) == 4?Я запустил программу на компьютере x64, так что это будет указатель?

==31419== Use of uninitialised value of size 8
==31419==    at 0x4E7F1CB: _itoa_word (in /usr/lib64/libc-2.17.so)
==31419==    by 0x4E83450: vfprintf (in /usr/lib64/libc-2.17.so)
==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
==31419==    by 0x400561: main (sample2.c:9)
==31419==  Uninitialised value was created by a stack allocation
==31419==    at 0x40052D: main (sample2.c:4)

Сообщение о полной проверке ниже:

 ==31419== Memcheck, a memory error detector
    ==31419== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==31419== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
    ==31419== Command: ./sample2
    ==31419== 
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x4E81AFE: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== Use of uninitialised value of size 8
    ==31419==    at 0x4E7F1CB: _itoa_word (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E83450: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x4E7F1D5: _itoa_word (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E83450: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x4E8349F: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x4E81BCB: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x4E81C4E: vfprintf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x4E8A338: printf (in /usr/lib64/libc-2.17.so)
    ==31419==    by 0x400561: main (sample2.c:9)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    4195392
    ==31419== Conditional jump or move depends on uninitialised value(s)
    ==31419==    at 0x400588: main (sample2.c:13)
    ==31419==  Uninitialised value was created by a stack allocation
    ==31419==    at 0x40052D: main (sample2.c:4)
    ==31419== 
    ==31419== 
    ==31419== HEAP SUMMARY:
    ==31419==     in use at exit: 0 bytes in 0 blocks
    ==31419==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
    ==31419== 
    ==31419== All heap blocks were freed -- no leaks are possible
    ==31419== 
    ==31419== For counts of detected and suppressed errors, rerun with: -v

1 Ответ

0 голосов
/ 19 февраля 2019

У вас есть 64-битный процессор.Даже если само значение составляет 32 бита, оно передается в printf в 64-битном регистре ;это вытекает из соглашения о вызовах System-V для x86-64.

Однако, похоже, что оно не вызывает ошибку до тех пор, пока в этой точке valgrind не знает, что значение расширено до 64 бити изначально пришел из вашей main функции (даже номер строки там неправильный.


Если вы скомпилируете это с -m32 и каким-то образом сможете запустить его под valgrind (мне нужно было установить дополнительные 32-битные пакеты в Ubuntu), вы действительно можете увидеть 4 здесь:

==4854== Use of uninitialised value of size 4
==4854==    at 0x48A3CAB: _itoa_word (_itoa.c:179)
==4854==    by 0x48A85C5: vfprintf (vfprintf.c:1642)
==4854==    by 0x48AF2F5: printf (printf.c:33)
==4854==    by 0x1085D0: main (sample2.c:9)
==4854== 
==4854== Conditional jump or move depends on uninitialised value(s)
==4854==    at 0x48A3CB3: _itoa_word (_itoa.c:179)
==4854==    by 0x48A85C5: vfprintf (vfprintf.c:1642)
==4854==    by 0x48AF2F5: printf (printf.c:33)
==4854==    by 0x1085D0: main (sample2.c:9)
==4854== 

Здесь следует отметить, что значение в int a[2] является неопределенным, но нетЗахватывает значения типа int и его адрес берется, поэтому передача его в функцию не имеет неопределенного поведения - но его использование в библиотечной функции имеет.

...