【问题标题】:valgrind gives a wrong size of uninitialisedvalgrind 给出了错误的未初始化大小
【发布时间】:2019-02-19 10:02:23
【问题描述】:

我从博客中看到的 sample2.c 代码用于说明使用 valgrind 的未初始化值。这是代码: 样本2.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-origins=yes ./sample2

我得到了下面的 valgrind 检查信息。

我不明白为什么在我的机器中由于 sizeof(int) == 4 而使用大小为 8 的未初始化值?我在 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

【问题讨论】:

    标签: c valgrind


    【解决方案1】:

    您有一个 64 位处理器。即使值本身是 32 位,它也会被传递到 64 位 寄存器 中的printf;这来自 x86-64 的 System-V 调用约定。

    但是它似乎直到稍后才触发错误,此时 valgrind 似乎只知道该值已符号扩展为 64 位,并且最初来自您的 main 函数(甚至那里的行号也是错误的.


    如果你用-m32 编译它并设法在 valgrind 下运行它(我需要在 Ubuntu 上安装额外的 32 位软件包),你确实可以在这里看到 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== 
    

    这里需要注意的一点是inta[2] 中的值是不确定的,但是没有int 类型的陷阱值,并且它的地址已被占用,因此将其传递给函数不会具有未定义的行为 - 但它在库函数中的使用确实如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多