Linux C/C++下内存泄露检查神器Valgrind

项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务起不来。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上。为以后更方便的检测内存泄漏问题,于是学习使用了valgrind来对内存泄漏进行检测。

Valgrind是linux环境下的一款功能齐全的内存调试和性能分析工具集,它包括Memcheck、Callgrind、Cachegrind、Helgrind、Massif等工具。本文旨在介绍Valgrind工具集中的内存检测工具Memcheck的用法,以提高内存错误的查找效率。

下载与安装valgrind

下面带大家介绍一下如何下载与安装:

valgrind官网

https://www.valgrind.org/

在这里插入图片描述
用户也可在valgrind home网站上下载安装包:

https://www.valgrind.org/downloads/

在这里插入图片描述下载完成后:

tar xvf valgrind-3.16.1.tar.bz2
cd valgrind-3.16.1
./configure --prefix=/usr/local/valgrind–指定安装目录
make
make install

或者可以这样下载:

wget https://sourceware.org/pub/valgrind/valgrind-3.16.1.tar.bz2

Valgrind概述

Valgrind具是一个用于调试和分析Linux程序的GPL系统。使用Valgrind的工套件,您可以自动检测许多内存管理和线程错误,使程序更稳定。还可以执行详细的分析以帮助加速程序的执行。下面我们介绍Valgrind工具集中的内存检测工具Memcheck的用法,以提高内存错误的查找效率。

Memcheck

所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获

未释放内存的使用
对释放后内存的读/写
对已分配内存块尾部的读/写
内存泄露
不匹配的使用malloc/new/new[] 和 free/delete/delete[]
重复释放内存

应用实践

下面通过介绍几个范例来说明如何使用Memcheck,示例仅供参考:

#include <stdlib.h>
#include <malloc.h>
#include <string.h>
  
void test()
{
    int *ptr = malloc(sizeof(int)*10);
  
    ptr[10] = 7; // 内存越界
  
    memcpy(ptr +1, ptr, 5); // 踩内存
  
    free(ptr); 
    free(ptr);// 重复释放
  
    int *p1;
    *p1 = 1; // 非法指针
}
  
int main(int argc ,char *argv[])
{
    test();
    return 0;
}

编译:
在这里插入图片描述

在编译程序的时候打开调试模式(gcc编译器的-g选项)。如果没有调试信息,即使最好的valgrind工具也将中能够猜测特定的代码是属于哪一个函数。打开调试选项进行编译后再用valgrind检查,valgrind将会给你的个详细的报告,比如哪一行代码出现了内存泄漏。

使用Valgrind检查程序Bug:

==4056 == Memcheck, a memory error detector
==4056 == Copyright © 2002-2010, and GNU GPL’d, by Julian Seward et al.
==4056 == Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==4056 == Command: ./tmp
==4056 ==

内存越界:

=4056== Invalid write of size 4
==4056 == at 0x804843F: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == Address 0x41a6050 is 0 bytes after a block of size 40 alloc’d
==4056 == at 0x4026864: malloc (vg_replace_malloc.c:236)
==4056 == by 0x8048435: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)

踩内存:

==4056 == Source and destination overlap in memcpy(0x41a602c, 0x41a6028, 5)
==4056 == at 0x4027BD6: memcpy (mc_replace_strmem.c:635)
==4056 == by 0x8048461: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in/home/minger/share/tencent/Memory_Leak/memory_leak_test)

重复释放:

==4056 == Invalid free() / delete / delete[]
==4056 == at 0x4025BF0: free (vg_replace_malloc.c:366)
==4056 == by 0x8048477: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == Address 0x41a6028 is 0 bytes inside a block of size 40 free’d
==4056 == at 0x4025BF0: free (vg_replace_malloc.c:366)
==4056 == by 0x804846C: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)

非法指针

==4056 == Use of uninitialised value of size 4
==4056 == at 0x804847B: test (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)
==4056 == by 0x804848D: main (in /home/minger/share/tencent/Memory_Leak/memory_leak_test)

从valgrind的检测输出结果看,这几个错误都找了出来。

总结

虽然C/C++是一种非常有用且功能强大的语言,但很难调试。 某些时候可能遇到内存错误。 如果知道出错 ,或者程序一直崩溃,我们可以用gdb去调试。 但是,有时遇到的问题是由于内存错误造成的,但它不出段错误,很多时候,我们不希望海里捞针,在gdb中设置很多断点,逐步盘查。 还有可能会遇到的另一个问题是内存泄漏:在某个地方,调用malloc分配的内存没有调用free来释放。 Valgrind是一个可以帮助解决这些问题的程序。

在这里插入图片描述

欢迎关注微信公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值