valgrind安装使用

本文介绍了如何下载、安装Valgrind,并通过一个简单的C程序示例展示了如何使用Valgrind进行内存错误检查,包括数组越界和内存未释放的问题。
摘要由CSDN通过智能技术生成

下载与安装

#wget http://www.valgrind.org/downloads/valgrind-3.8.1.tar.bz2
#tar xvf valgrind-3.8.1.tar.bz2
#cd valgrind-3.8.1
#./configure --prefix=/usr/local/webserver/valgrind
#make
#make install

 

测试代码

  1. #include <stdlib.h>  
  2. int* func(void)  
  3. {  
  4.    int* x = malloc(10 * sizeof(int));  
  5.    x[10] = 0;  //问题1: 数组下标越界  
  6. }                    
  7.  int main(void)  
  8. {  
  9.    int* x=NULL;  
  10.    x=func();  
  11.    //free(x);    
  12.    x=NULL;  
  13.    return 0;   //问题2: 内存没有释放  
  14.  }  


编译

#gcc -g -o test test.c

 

内存检查
#valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./test


检测什么

    1. 动态内存使用
 
 2. 检测未初始化变量使用
     与使用未初始化内存类似
 3. 内存重叠
 4. 文件未关闭


■ 例子
1.   动态内存使用
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

//===================================================================
// Use of uninitialised memory
void f_use_uninit()
{
   int *x;
   x[0] = 10;
   cout << x[0] <<endl;
}

//Reading/writing off the end of malloc’d block
void f_use_after_buffer()
{
   int *x = (int*)malloc(10 * sizeof(int));
   x[10] = 12;
   cout << x[10] <<endl;
   free(x);
}

//Memory leaks -- where pointers to malloc’d blocks are lost foreve
void f_no_free()
{
   int *x = (int*)malloc(10 * sizeof(int));
}

//Mismatched use of malloc/new/new [] vs free/delete/delete []
void f_malloc_del()
{
   int *x = (int*)malloc(10 * sizeof(int));
   delete x;
}

//Reading/writing memory after it has been free’d
void f_use_double_free()
{
   int *x = (int*)malloc(10 * sizeof(int));
   free(x);
   free(x);
}

//Reading/writing memory after it has been free’d
void f_use_after_free()
{
   int *x = (int*)malloc(10 * sizeof(int));
   free(x);
   x[0] = 10;
   cout << x[0] <<endl;
}

//===================================================================
//Overlapping src and dst pointers in memcpy() and related functions
void f_src_dst_Overlapping()
{
char src[10] = "123456789";
memcpy(src, &src[4], 6);
cout << src << endl;
}

//===================================================================

void f_param_noinit()
{
// int i;
// cout << i << endl;
int my_array[10];
cout << my_array[0] << endl;
}

//===================================================================
void f_file_not_close(int i)
{
    FILE *fp = fopen("test.txt", "w");
    if (i == 1)
    {
    fclose(fp);
    return ;
    }
}


int main(void)
{
f_use_uninit();

f_use_after_buffer();

f_no_free();
f_malloc_del();
f_use_double_free();

f_use_after_free();


  return 0;
 }

结果:
root@ubuntu:/home/naviwork/test# g++ test.cpp -g
root@ubuntu:/home/naviwork/test# valgrind --leak-check=full --track-fds=yes ./a.out 
==3165== Memcheck, a memory error detector
==3165== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3165== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3165== Command: ./a.out
==3165== 
==3165== Use of uninitialised value of size 4
==3165==    at 0x80488FD: f_use_uninit() (test.cpp:12)
==3165==    by 0x8048B13: main (test.cpp:89)
==3165== 
==3165== Use of uninitialised value of size 4
==3165==    at 0x8048906: f_use_uninit() (test.cpp:13)
==3165==    by 0x8048B13: main (test.cpp:89)
==3165== 
10
==3165== Invalid write of size 4
==3165==    at 0x8048945: f_use_after_buffer() (test.cpp:20)
==3165==    by 0x8048B18: main (test.cpp:91)
==3165==  Address 0x42d2050 is 0 bytes after a block of size 40 alloc'd
==3165==    at 0x40265DC: malloc (vg_replace_malloc.c:270)
==3165==    by 0x804893B: f_use_after_buffer() (test.cpp:19)
==3165==    by 0x8048B18: main (test.cpp:91)
==3165== 
==3165== Invalid read of size 4
==3165==    at 0x8048951: f_use_after_buffer() (test.cpp:21)
==3165==    by 0x8048B18: main (test.cpp:91)
==3165==  Address 0x42d2050 is 0 bytes after a block of size 40 alloc'd
==3165==    at 0x40265DC: malloc (vg_replace_malloc.c:270)
==3165==    by 0x804893B: f_use_after_buffer() (test.cpp:19)
==3165==    by 0x8048B18: main (test.cpp:91)
==3165== 
12
==3165== Mismatched free() / delete / delete []
==3165==    at 0x4025BD6: operator delete(void*) (vg_replace_malloc.c:480)
==3165==    by 0x80489B6: f_malloc_del() (test.cpp:35)
==3165==    by 0x8048B22: main (test.cpp:94)
==3165==  Address 0x42d20d8 is 0 bytes inside a block of size 40 alloc'd
==3165==    at 0x40265DC: malloc (vg_replace_malloc.c:270)
==3165==    by 0x80489A8: f_malloc_del() (test.cpp:34)
==3165==    by 0x8048B22: main (test.cpp:94)
==3165== 
==3165== Invalid free() / delete / delete[] / realloc()
==3165==    at 0x4025FE9: free (vg_replace_malloc.c:446)
==3165==    by 0x80489E3: f_use_double_free() (test.cpp:43)
==3165==    by 0x8048B27: main (test.cpp:95)
==3165==  Address 0x42d2130 is 0 bytes inside a block of size 40 free'd
==3165==    at 0x4025FE9: free (vg_replace_malloc.c:446)
==3165==    by 0x80489D8: f_use_double_free() (test.cpp:42)
==3165==    by 0x8048B27: main (test.cpp:95)
==3165== 
==3165== Invalid write of size 4
==3165==    at 0x8048A09: f_use_after_free() (test.cpp:51)
==3165==    by 0x8048B2C: main (test.cpp:97)
==3165==  Address 0x42d2188 is 0 bytes inside a block of size 40 free'd
==3165==    at 0x4025FE9: free (vg_replace_malloc.c:446)
==3165==    by 0x8048A05: f_use_after_free() (test.cpp:50)
==3165==    by 0x8048B2C: main (test.cpp:97)
==3165== 
==3165== Invalid read of size 4
==3165==    at 0x8048A12: f_use_after_free() (test.cpp:52)
==3165==    by 0x8048B2C: main (test.cpp:97)
==3165==  Address 0x42d2188 is 0 bytes inside a block of size 40 free'd
==3165==    at 0x4025FE9: free (vg_replace_malloc.c:446)
==3165==    by 0x8048A05: f_use_after_free() (test.cpp:50)
==3165==    by 0x8048B2C: main (test.cpp:97)
==3165== 
10
==3165== 
==3165== FILE DESCRIPTORS: 3 open at exit.
==3165== Open file descriptor 2: /dev/pts/0
==3165==    <inherited from parent>
==3165== 
==3165== Open file descriptor 1: /dev/pts/0
==3165==    <inherited from parent>
==3165== 
==3165== Open file descriptor 0: /dev/pts/0
==3165==    <inherited from parent>
==3165== 
==3165== 
==3165== HEAP SUMMARY:
==3165==     in use at exit: 40 bytes in 1 blocks
==3165==   total heap usage: 5 allocs, 5 frees, 200 bytes allocated
==3165== 
==3165== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3165==    at 0x40265DC: malloc (vg_replace_malloc.c:270)
==3165==    by 0x8048991: f_no_free() (test.cpp:28)
==3165==    by 0x8048B1D: main (test.cpp:93)
==3165== 
==3165== LEAK SUMMARY:
==3165==    definitely lost: 40 bytes in 1 blocks
==3165==    indirectly lost: 0 bytes in 0 blocks
==3165==      possibly lost: 0 bytes in 0 blocks
==3165==    still reachable: 0 bytes in 0 blocks
==3165==         suppressed: 0 bytes in 0 blocks
==3165== 
==3165== For counts of detected and suppressed errors, rerun with: -v
==3165== Use --track-origins=yes to see where uninitialised values come from
==3165== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 17 from 6)

 2. 检测未初始化变量使用
     与使用未初始化内存类似
     内存重叠
     文件未关闭


代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
//===================================================================
//Overlapping src and dst pointers in memcpy() and related functions
void f_src_dst_Overlapping()
{
char src[10] = "123456789";
memcpy(src, &src[4], 6);
cout << src << endl;
}

//===================================================================

void f_param_noinit()
{
// int i;
// cout << i << endl;
int my_array[10];
cout << my_array[0] << endl;
}

//===================================================================
void f_file_not_close(int i)
{
    FILE *fp = fopen("test.txt", "w");
    if (i == 1)
    {
    fclose(fp);
    return ;
    }
}


int main(void)
{

f_src_dst_Overlapping();
f_param_noinit();
f_file_not_close(1);
f_file_not_close(0);

  return 0;
 }

结果:
root@ubuntu:/home/naviwork/test# g++ test.cpp -g
root@ubuntu:/home/naviwork/test# valgrind --leak-check=full --track-fds=yes ./a.out 
==3190== Memcheck, a memory error detector
==3190== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3190== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3190== Command: ./a.out
==3190== 
==3190== Source and destination overlap in memcpy(0xbe9ea6d2, 0xbe9ea6d6, 6)
==3190==    at 0x4028693: memcpy (mc_replace_strmem.c:878)
==3190==    by 0x8048895: f_src_dst_Overlapping() (test.cpp:11)
==3190==    by 0x8048934: main (test.cpp:41)
==3190== 
56789
==3190== Conditional jump or move depends on uninitialised value(s)
==3190==    at 0x40B8F68: 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/libstdc++.so.6.0.13)
==3190==    by 0x40B91EC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB7B4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB943: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x80488E4: f_param_noinit() (test.cpp:22)
==3190==    by 0x8048939: main (test.cpp:43)
==3190== 
==3190== Use of uninitialised value of size 4
==3190==    at 0x40B2B4E: ??? (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40B8F98: 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/libstdc++.so.6.0.13)
==3190==    by 0x40B91EC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB7B4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB943: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x80488E4: f_param_noinit() (test.cpp:22)
==3190==    by 0x8048939: main (test.cpp:43)
==3190== 
==3190== Conditional jump or move depends on uninitialised value(s)
==3190==    at 0x40B2B57: ??? (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40B8F98: 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/libstdc++.so.6.0.13)
==3190==    by 0x40B91EC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB7B4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB943: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x80488E4: f_param_noinit() (test.cpp:22)
==3190==    by 0x8048939: main (test.cpp:43)
==3190== 
==3190== Conditional jump or move depends on uninitialised value(s)
==3190==    at 0x40B8FBF: 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/libstdc++.so.6.0.13)
==3190==    by 0x40B91EC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB7B4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x40CB943: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.6.0.13)
==3190==    by 0x80488E4: f_param_noinit() (test.cpp:22)
==3190==    by 0x8048939: main (test.cpp:43)
==3190== 
-1096898840
==3190== 
==3190== FILE DESCRIPTORS: 4 open at exit.
==3190== Open file descriptor 3: test.txt
==3190==    at 0x4000832: ??? (in /lib/ld-2.11.1.so)
==3190==    by 0x41DF077: _IO_file_fopen (in /lib/tls/i686/cmov/libc-2.11.1.so)
==3190==    by 0x41D33EC: ??? (in /lib/tls/i686/cmov/libc-2.11.1.so)
==3190==    by 0x41D344B: fopen (in /lib/tls/i686/cmov/libc-2.11.1.so)
==3190==    by 0x8048910: f_file_not_close(int) (test.cpp:29)
==3190==    by 0x8048951: main (test.cpp:46)
==3190== 
==3190== Open file descriptor 2: /dev/pts/0
==3190==    <inherited from parent>
==3190== 
==3190== Open file descriptor 1: /dev/pts/0
==3190==    <inherited from parent>
==3190== 
==3190== Open file descriptor 0: /dev/pts/0
==3190==    <inherited from parent>
==3190== 
==3190== 
==3190== HEAP SUMMARY:
==3190==     in use at exit: 352 bytes in 1 blocks
==3190==   total heap usage: 2 allocs, 1 frees, 704 bytes allocated
==3190== 
==3190== LEAK SUMMARY:
==3190==    definitely lost: 0 bytes in 0 blocks
==3190==    indirectly lost: 0 bytes in 0 blocks
==3190==      possibly lost: 0 bytes in 0 blocks
==3190==    still reachable: 352 bytes in 1 blocks
==3190==         suppressed: 0 bytes in 0 blocks
==3190== Reachable blocks (those to which a pointer was found) are not shown.
==3190== To see them, rerun with: --leak-check=full --show-reachable=yes
==3190== 
==3190== For counts of detected and suppressed errors, rerun with: -v
==3190== Use --track-origins=yes to see where uninitialised values come from
==3190== ERROR SUMMARY: 23 errors from 5 contexts (suppressed: 17 from 6)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值