当前位置: 首页 > 工具软件 > Valgrind > 使用案例 >

Valgrind基本用法

曹君墨
2023-12-01

介绍

valgrind 是一套linux下的开源仿真调试工具集,遵循GPLv2许可协议,可以用于内存调试,内存泄漏检测以及性能分析。

valgrind包含下列一些工具:

Memcheck:内存错误检测器,这是最常用的工具,用于检测程序中的内存问题,如泄露、越界、非法指针等。memcheck会检测所有对内存的去写操作,一切对malloc()/free()/new/delete的调用都会被捕获,所以能检测以下问题:

  • 对未初始化内存的使用;

  • 读/写释放后的内存块;

  • 读/写超出 malloc 分配的内存块;

  • 读/写不适当的栈中内存块;

  • 内存泄漏,指向一块内存的指针永远丢失;

  • 不正确的 malloc/free 或 new/delete 匹配;

  • memcpy() 相关函数中的 dst 和 src 指针重叠。

Helgrind:它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发觉的错误。Helgrind实现了名为Eraser的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验状态。

Massif:堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。

Massif对内存的分配和释放做profile。程序开发者通过它可以深入了解程序的内存使用行为,从而对内存使用进行优化。这个功能对C++尤其有用,因为C++有很多隐藏的内存分配和释放。

安装

 linux安装口令
 Debian 和 Ubuntu 可使用 apt 安装
 sudo apt install valgrind

实例

实例1:

1.新建一个memoryleak.c文件

新建一个c文件memoryleak.c,使用malloc申请一块内存空间,但是不释放,如下:

 #include <stdio.h>
 #include <stdlib.h>
 ​
 int main() 
 {
     int *arr = malloc(sizeof(int) * 100);
     return 0;
 }

2.编译c文件

 gcc -g -o memoryleak memoryleak.c

3.运行valgrind

 valgrind 默认是运行memcheck
 valgrind ./memoryleak

4.运行结果显示

 ==320== Memcheck, a memory error detector
 ==320== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
 ==320== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
 ==320== Command: ./memoryleak
 ==320== 
 ==320== 
 ==320== HEAP SUMMARY:
 ==320==     in use at exit: 400 bytes in 1 blocks
 ==320==   total heap usage: 1 allocs, 0 frees, 400 bytes allocated
 ==320== 
 ==320== LEAK SUMMARY:
 ==320==    definitely lost: 400 bytes in 1 blocks
 ==320==    indirectly lost: 0 bytes in 0 blocks
 ==320==      possibly lost: 0 bytes in 0 blocks
 ==320==    still reachable: 0 bytes in 0 blocks
 ==320==         suppressed: 0 bytes in 0 blocks
 ==320== Rerun with --leak-check=full to see details of leaked memory
 ==320== 
 ==320== For lists of detected and suppressed errors, rerun with: -s
 ==320== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

可以看到第9行显示,申请了1个 400 字节的内存空间,但是没有释放。

添加--leak-check=full参数,可以看到内存泄漏的更多细节。

 ==426== Memcheck, a memory error detector
 ==426== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
 ==426== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
 ==426== Command: ./memoryleak
 ==426== 
 ==426== 
 ==426== HEAP SUMMARY:
 ==426==     in use at exit: 400 bytes in 1 blocks
 ==426==   total heap usage: 1 allocs, 0 frees, 400 bytes allocated
 ==426== 
 ==426== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
 ==426==    at 0x483F7B5: malloc (vg_replace_malloc.c:381)
 ==426==    by 0x10914A: main (memoryleak.c:6)
 ==426== 
 ==426== LEAK SUMMARY:
 ==426==    definitely lost: 400 bytes in 1 blocks
 ==426==    indirectly lost: 0 bytes in 0 blocks
 ==426==      possibly lost: 0 bytes in 0 blocks
 ==426==    still reachable: 0 bytes in 0 blocks
 ==426==         suppressed: 0 bytes in 0 blocks
 ==426== 
 ==426== For lists of detected and suppressed errors, rerun with: -s
 ==426== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

可以看到第13行显示,内存泄漏发生在 memoryleak.c 的第6行代码。

实例2:

接着,我们增加一行代码修复内存泄漏

 #include <stdio.h>
 #include <stdlib.h>
 ​
 int main() 
 {
     int *arr = malloc(sizeof(int) * 100);
 ​
     free(arr);
     return 0;
 }

1.编译

 gcc -g -o memoryleak memoryleak.c

2.运行valgrind

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

可以看到内存泄漏已经消除。

 类似资料: