Valgrind 没有显示错误

问题描述

我正在尝试检查此代码中的内存错误

#include <stdio.h>
#include <stdlib.h>

void test1() {
    int i;
    int max = 4;
    int *a = (int *)malloc(max*sizeof(*a));

    for (i=0; i<max; i++) {
        a[i] = i*i;
        printf ("%d  %d\n",i,a[i]);
    }
    free(a); }

char *getString() {
    char message[100] = "Hello World";
    char *ret = message;

    return ret; }

void test2() {
    printf ("String : %s\n",getString()); }

int main() {
    test1();
    test2();
    
    return 0; }

我知道函数 test2() 会出错,因为 getString() 返回了一个指向无效内存位置的指针(因为当 getString() 完成时内存已经被释放,因为 message[] 数组被分配在堆栈上,即局部变量)。 但是当我只调用 test2() 时,valgrind 没有显示任何错误。即当我在 main() 中注释掉对 test1() 的调用时。

==26998== Memcheck,a memory error detector
==26998== copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.
==26998== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==26998== Command: ./a.out
==26998== 
String : 
==26998== 
==26998== HEAP SUMMARY:
==26998==     in use at exit: 0 bytes in 0 blocks
==26998==   total heap usage: 1 allocs,1 frees,1,024 bytes allocated
==26998== 
==26998== All heap blocks were freed -- no leaks are possible
==26998== 
==26998== For lists of detected and suppressed errors,rerun with: -s
==26998== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

但是当我让 test1() 和 test2() 一个一个地执行时,我从 valgrind 得到了所需的错误

==27200== Memcheck,a memory error detector
==27200== copyright (C) 2002-2017,by Julian Seward et al.
==27200== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==27200== Command: ./a.out
==27200== 
0  0
1  1
2  4
3  9
==27200== Conditional jump or move depends on uninitialised value(s)
==27200==    at 0x48447B5: strlen (vg_replace_strmem.c:469)
==27200==    by 0x48E3FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200==    by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200==    by 0x1092C7: test2 (a.c:24)
==27200==    by 0x1092E2: main (a.c:29)
==27200== 
==27200== Conditional jump or move depends on uninitialised value(s)
==27200==    at 0x48447C8: strlen (vg_replace_strmem.c:469)
==27200==    by 0x48E3FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200==    by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200==    by 0x1092C7: test2 (a.c:24)
==27200==    by 0x1092E2: main (a.c:29)
==27200== 
==27200== Conditional jump or move depends on uninitialised value(s)
==27200==    at 0x48F8077: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48E3D32: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200==    by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200==    by 0x1092C7: test2 (a.c:24)
==27200==    by 0x1092E2: main (a.c:29)
==27200== 
==27200== Syscall param write(buf) points to uninitialised byte(s)
==27200==    at 0x4966907: write (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F79CC: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F6D45: new_do_write (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F8A68: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F8015: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48E270F: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200==    by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200==    by 0x1092C7: test2 (a.c:24)
==27200==    by 0x1092E2: main (a.c:29)
==27200==  Address 0x4a46099 is 9 bytes inside a block of size 1,024 alloc'd
==27200==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==27200==    by 0x48EB563: _IO_file_doallocate (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F9DAF: _IO_doallocbuf (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F8F67: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48F8015: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.33.so)
==27200==    by 0x48E2F55: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==27200==    by 0x48CF2DE: printf (in /usr/lib/libc-2.33.so)
==27200==    by 0x1091E0: test1 (a.c:11)
==27200==    by 0x1092D8: main (a.c:28)
==27200== 
String : Hello World
==27200== 
==27200== HEAP SUMMARY:
==27200==     in use at exit: 0 bytes in 0 blocks
==27200==   total heap usage: 2 allocs,2 frees,040 bytes allocated
==27200== 
==27200== All heap blocks were freed -- no leaks are possible
==27200== 
==27200== Use --track-origins=yes to see where uninitialised values come from
==27200== For lists of detected and suppressed errors,rerun with: -s
==27200== ERROR SUMMARY: 24 errors from 4 contexts (suppressed: 0 from 0)

我还注意到一件事 -
如果我先调用 test2(),然后调用 test1()(即 test2() 是从 main() 调用的第一个函数),我不会从 valgrind 中得到任何错误
如果我不将 test2() 作为第一个函数调用(即,如果我在 test2() 之前调用 test1() 并且在此之后再次调用 test1() 无关紧要)我收到错误消息。

那么,为什么我会遇到这个问题? (我知道代码中的内存错误)我的意思是为什么 valgrind 在某些情况下不显示错误
(我在 manjaro Linux 上使用 Valgrind 3.17。我的一些同学在 Fedora 和 Redhat 上使用 Valgrind 也遇到同样的问题,而其他一些使用 Ubuntu 的同学没有遇到这个问题。)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)