Valgrind检测内存泄漏

概述

任何长期运行的应用程序都必须正确地管理内存,否则它最终会耗尽所有可用内存并崩溃,如果你使用的是自动为你管理内存的语言,那么祝贺你,如果你用C/C++则需要你负责内存管理,这里有一个valgrind的简短教程,这个工具将对你的程序的任何内存泄漏出具报告。

Valgrind是用于构建动态分析工具的仪器框架。有Valgrind工具可以自动检测许多内存管理和线程错误,并详细描述程序。您也可以使用Valgrind构建新工具。
Valgrind发行版当前包括六个生产质量工具:一个内存错误检测器,两个线程错误检测器,一个缓存和分支预测探查器,一个生成调用图的缓存和分支预测探查器以及一个堆探查器。它还包括三个实验工具:堆栈/全局数组溢出检测器,第二个堆分析器(用于检查堆块的使用方式)以及SimPoint基本块向量生成器。它可在以下平台上运行:X86 / Linux,AMD64 / Linux,ARM / Linux,ARM64 / Linux,PPC32 / Linux,PPC64 / Linux,PPC64LE / Linux,S390X / Linux,MIPS32 / Linux,MIPS64 / Linux,X86 / Solaris ,AMD64 / Solaris,ARM / Android(2.3.x和更高版本),ARM64 / Android,X86 / Android(4.0和更高版本),MIPS32 / Android,X86 / Darwin和AMD64 / Darwin(Mac OS X 10.12)。

官网:
http://valgrind.org
当前最新版本valgrind-3.15.0

安装

要在Ubuntu或者debian操作系统上安装valgrind,可以输入

sudo apt-get update
sudo apt-get install valgrind

Valgrind 命令介绍:
用法: valgrind [options] prog-and-args
[options]: 常用选项,适用于所有Valgrind工具
–tool= 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
memcheck ------> 这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。
callgrind ------> 它主要用来检查程序中函数调用过程中出现的问题,检测程序代码的运行时间和调用过程,以及分析程序性能。
cachegrind ------> 它主要用来检查程序中缓存使用出现的问题,分析CPU的cache命中率、丢失率,用于进行代码优化。
helgrind ------> 它主要用来检查多线程程序中出现的竞争问题,用于检查多线程程序的竞态条件。
massif ------> 它主要用来检查程序中堆栈使用中出现的问题。堆栈分析器,指示程序中使用了多少堆内存等信息。
extension ------> 可以利用core提供的功能,自己编写特定的内存调试工具
-h –help 显示帮助信息。
-version 显示valgrind内核的版本,每个工具都有各自的版本。
-q –quiet 安静地运行,只打印错误信息。
-v –verbose 更详细的信息, 增加错误数统计。
-trace-children=no|yes 跟踪子线程? [no]
-track-fds=no|yes 跟踪打开的文件描述?[no]
-time-stamp=no|yes 增加时间戳到LOG信息? [no]
-log-fd= 输出LOG到描述符文件 [2=stderr]
-log-file= 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
-log-file-exactly= 输出LOG信息到 file
-log-file-qualifier= 取得环境变量的值来做为输出信息的文件名。 [none]
-log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port

LOG信息输出
-xml=yes 将信息以xml格式输出,只有memcheck可用
-num-callers= show callers in stack traces [12]
-error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
-error-exitcode= 如果发现错误则返回错误代码 [0=disable]
-db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
-db-command= 启动调试器的命令行选项[gdb -nw %f %p]

适用于Memcheck工具的相关选项:
-leak-check=no|summary|full 要求对leak给出详细信息? [summary]
-leak-resolution=low|med|high how much bt merging in leak check [low]
-show-reachable=no|yes show reachable blocks in leak check? [no]

最常用的命令格式:

valgrind --tool=memcheck --leak-check=full ./test

测试用例:
testValgrind.cpp

#include 
#include 

int main()
{
    char* p = new char(10);
    
    //delete p;
    
    return 0;
}
g++ -g -o test testValgrind.cpp
valgrind --tool=memcheck --leak-check=full ./test

==1179== Memcheck, a memory error detector
==1179== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1179== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1179== Command: ./test
==1179==
==1179== error calling PR_SET_PTRACER, vgdb might block
==1179==
==1179== HEAP SUMMARY:
==1179==     in use at exit: 1 bytes in 1 blocks
==1179==   total heap usage: 2 allocs, 1 frees, 72,705 bytes allocated
==1179==
==1179== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1179==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1179==    by 0x10868B: main (testValgrind.cpp:8)
==1179==
==1179== LEAK SUMMARY:
==1179==    definitely lost: 1 bytes in 1 blocks
==1179==    indirectly lost: 0 bytes in 0 blocks
==1179==      possibly lost: 0 bytes in 0 blocks
==1179==    still reachable: 0 bytes in 0 blocks
==1179==         suppressed: 0 bytes in 0 blocks
==1179==
==1179== For counts of detected and suppressed errors, rerun with: -v
==1179== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

原理:
Memcheck将内存泄露分为两种,一种是可能的内存泄露(Possibly lost),另外一种是确定的内存泄露(Definitely lost)。Possibly lost 是指仍然存在某个指针能够访问某块内存,但该指针指向的已经不是该内存首地址。Definitely lost 是指已经不能够访问这块内存。而Definitely lost又分为两种:直接的(direct)和间接的(indirect)。直接和间接的区别就是,直接是没有任何指针指向该内存,间接是指指向该内存的指针都位于内存泄露处。在上述的例子中,根节点是directly lost,而其他节点是indirectly lost。

下图(转载自互联网,侵权删)可能更直观点:
Valgrind检测内存泄漏_第1张图片
Valgrind检测内存泄漏_第2张图片

Valgrind检测内存泄漏_第3张图片

The end …

你可能感兴趣的:(linux,C/C++,linux,内存泄露,Valgrind,泄露,内存)