简介
valgrind是一套代码运行动态分析工具集,它是用于debug调试应用程序的一套工具集合,基于模块化的设计,包含一个framework核心框架层和各个moudule组件,新的功能模块可以方便的加入其中,而不影响旧的模块功能。
valgrind包含如下工具组件:
- Memcheck
这是一个memory错误检测工具,帮助开发者库快速排查内存问题。适用于C和C++。 - Cachegrind
一个cache和分支预测分析工具,用于检测cache使用的问题,优化程序运行速度。 - Callgrind
一个函数调用分析工具,用于分析函数调用过程出现的问题。 - Helgrind
多线程分析工具 - Massif
堆栈分析工具,帮助开发者优化内存使用,从而优化内存的占用量。
valgrind能够对应用进行调试的原理是什么呢?实际上核心框架层模拟了一个应用程序运行环境,我们要调试的应用是在valgrind环境中运行的,因此valgrind才可以探测到程序运行中出现的问题。
使用方法
安装:
sudo apt-get install valgrind
valgrind最基本的命令格式如下:
valgrind --tool=<toolname> [default: memcheck]
tool可以选择使用的调试组件,默认为memcheck,更详细的参数命令参考valgrind --help打印。valgrind在使用前要求程序必须是经过-g编译选项编译后的程序,这类程序带有足够的调试信息。
下面举例说明valgrind的使用方法,首先编译写一个有内存泄露和越界访问问题的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* This test program include two error:
* 1. malloc but don't free (mem leak)
* 2. mem access violation, heap block overrun
*/
int main (int argc, char *argv[])
{
char *buf;
buf = (char *)malloc(10); // problem 1
buf[10] = 0; //problem 2
return 0;
}
采用如下命令编译:
gcc -g -Wall mem_leak.c mem_leak
最后开始最关键的调试运行步骤:
valgrind --tool=memcheck --leak-check=full ./mem_leak
这条命令主要是使用valgrind的memcheck功能,这也是valgrind最为常用的一个功能。打印出的错误信息如下:
==605== Memcheck, a memory error detector
==605== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==605== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==605== Command: ./mem_leak
==605==
==605== Invalid write of size 1
==605== at 0x10866F: main (mem_leak.c:15)
==605== Address 0x522d04a is 0 bytes after a block of size 10 alloc'd
==605== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==605== by 0x108662: main (mem_leak.c:14)
==605==
==605==
==605== HEAP SUMMARY:
==605== in use at exit: 10 bytes in 1 blocks
==605== total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==605==
==605== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==605== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==605== by 0x108662: main (mem_leak.c:14)
==605==
==605== LEAK SUMMARY:
==605== definitely lost: 10 bytes in 1 blocks
==605== indirectly lost: 0 bytes in 0 blocks
==605== possibly lost: 0 bytes in 0 blocks
==605== still reachable: 0 bytes in 0 blocks
==605== suppressed: 0 bytes in 0 blocks
==605==
==605== For counts of detected and suppressed errors, rerun with: -v
==605== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)