Valgrind是一个工具框架,可以检测许C和C++程序中与内存相关的错误,这些错误很常见,可能会导致程序崩溃和不可预测的行为。该框架由许多工具组成,每个工具执行某种类型的调试、分析等任务。对于Valgrind来说,其内部设计是高度模块化的,所以可以很容易创建出新的工具而不会影响已经存在的工具。
在实际工程项目开发设计的全生命周期中,Valgrind工具会经常使用到。
目前Valgrind发行版主要包括7个产品级别的工具:
一个内存错误检测器:Memcheck
两个线程错误检测器:DRD
和Helgrind
一个缓存和分支预测分析器:Cachegrind
一个调用图生成缓存和分支预测分析器:Callgrind
两个不同的堆分析器:Massif
和DHAT
还包括一个实验性的SimPoint基本块向量生成器。
Valgrind可以在以下平台上运行:
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。ARM64/Android, X86/Android(4.0及后续版本),MIPS32/Android, X86/FreeBSD, AMD64/FreeBSD, X86/Darwin和AMD64/Darwin (Mac OS x 10.12)。
本文将在ubuntu 18.04版本上安装Valgrind。
从下列地址下载安装包,小生这里选择最新的版本:3.19.0
Valgrind最新发布地址:https://valgrind.org/downloads/current.html
下载完后将获取到一个压缩包:valgrind-3.19.0.tar.bz2
tar -jxvf valgrind-3.19.0.tar.bz2
cd valgrind-3.19.0/
./autogen.sh
./configure
配置完成后,会输出平台相关信息:
(7)在终端输入make -j4
执行valgrind脚本构建操作。
(8)在终端输入sudo make install
安装valgrind。
(9)验证
经过以上步骤后,valgrind就安装成功了,接着我们可以在终端键入:
valgrind --version
如果看见输出了对应版本信息,则证明valgrind安装成功,反之则没有安装成功啦!
至此,valgrind就成功安装完成,接下来让我们写个具体示例尝尝鲜…
首先我们设计一个简单的C语言程序:
#include
#include
void demo()
{
printf("valgrind test demo\r");
int * pint = malloc(5 * sizeof(int));
pint[5] = 1;
}
int main()
{
demo();
return 0;
}
上述代码是一个在main函数中调用demo函数,完成一个信息的打印操作,然后使用malloc
分配内容,然后来了一行错误的代码,接着就完了。就这样一个简单的C语言程序,下面让我们来实际使用Vargrind的Memcheck来进行内存检测和分析。
编译构建该份代码:
gcc -o test valgrand_test.c
使用valgrind的memcheck工具进行内存分析(valgrind默认情况下会使用memcheck
工具),在终端键入以下命令:
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./test
输出结果如下:
当valgrind memcheck工具运行完成后,会输出许多信息,我们需要仔细分析这些信息,从中获取到关于我们自己开发的软件中内存相关信息。
在上图中:
20223是进程id,该信息一般不重要。
有一个Invalid write of size 4信息:
出现这条信息,是由于上述代码中的:pint[5] = 1;
这行错误操作导致的。
上图中显示了应用软件总共使用的heap大小,分配的数量,释放的数量。
上图中,检测报告显示出现了一次内存泄漏,泄漏内存的大小为20字节。出现该条信息由以下代码导致:
int * pint = malloc(5 * sizeof(int));
上述代码操作将使用malloc
分配5*4 = 20字节的heap内存,然而却没有使用free
释放,从而导致内存泄漏。从valgrind中检测结果来看,与实际代码的问题相符。
本文描述了一个使用vargrind进行应用程序内存检测的过程,大致如下:
(1)编译构建自己的C/C++应用程序。(需要将应用程序构建成调试版本的,vargrind需要使用到其中的调试信息)
(2)使用vargrind工具检测应用程序。
(3)结束应用程序,生成检测报告。(结束memcheck检查需要发送SIGINT信号,即按下Ctrl + c
。不要发送SIGKILL信息结束进程,也不要使用Ctrl + z
暂停进程,否则将无法生成相应的检测报告)