微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Valgrind 没有显示错误

如何解决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 举报,一经查实,本站将立刻删除。