转自:https://blog.csdn.net/tao_627/article/details/38304903
valgrind官网:http://valgrind.org/
1.安装方法
第一种方式:下载目前最新的源码,编译安装,在服务器上推荐这种方式
wget http://valgrind.org/downloads/valgrind-3.9.0.tar.bz2
tar xvf valgrind-3.9.0.tar.bz2
cd valgrind-3.9.0/
./configure
make
make install
第二种方式:使用二进制包安装,以Ubuntu 14.04 64bit为例,输入下面的安装命令
sudo apt-get install valgrind
这个可能需要下载很大的安装文件,如果在下载过程中中断了,会造成以后无法再安装其他的软件,除非你下次升级软件之前,先完成上面的安装。
所以最好的方法,我选择下面的第三种方法:
第三种方式:为了加快速度,现在chrome浏览器中下载二进制包,在ubuntu下是.deb包。这是我采用的方法。
下载地址为:http://pkgs.org/download/valgrind,注意不同的系统和版本,对应的包是不一样的。
ubuntu 14.04 64bit的deb包下载地址:
http://archive.ubuntu.com/ubuntu/pool/main/v/valgrind/valgrind_3.6.1-0ubuntu1_i386.deb
下载完成后双击,默认用software center安装即可!参见下面的截图
Valgrind使用方法
用法: valgrind [options] prog-and-args [options]:
常用选项,适用于所有Valgrind工具
-tool=
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-file=
-log-file-exactly=
-log-file-qualifier= 取得环境变量的值来做为输出信息的文件名。 [none]
-log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port
LOG信息输出
-xml=yes 将信息以xml格式输出,只有memcheck可用
-num-callers=
-error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
-error-exitcode=
-db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
-db-command=
适用于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使用举例
下面是一段明显有问题的代码文件valgrind_demo.c,我们使用Valgrind来查找它的错误。
//gcc -Wall -g valgrind_demo.c -o valgrind_demo
//
#include
void f(void){
int* x = malloc(10 * sizeof(int));
x[10] = 0; //问题1:内存越界
//问题2:内存泄露
}
int main(int argc, char* argv[]){
f();
return 0;
}
首先编译程序
gcc -Wall -g valgrind_demo.c -o valgrind_demo
这里使用-Wall是开启编译过程中所有的warning, -g是便于我们更仔细地调试程序.
然后运行程序,使用valgrind来检查该程序的bug
valgrind --tool=memcheck --leak-check=full valgrind_demo
下面是valgrind检查效果截图
从截图的最后一个标注处看出,该程序有2处错误, 分别位于代码的两个地方:
先看第一个问题, 是有4个字节的非法写入, valgrind检查到valgrind_demo.c文件的main函数12行调用了f函数, f函数在第6行代码处调用malloc分配了40个字节的内存; 接着在f的第7行代码处, 在分配的40个字节的后面紧接着要写入4字节,这显然是非法的, 因为40字节以外的内存我们没有分配,的确是非法写入(数组越界).
再看第二个问题, 说40字节的一个内存块肯定会丢失,也就是内存泄露, 这个内存是在main函数的12行, 调用f函数中的malloc来进行分配的(内存空间没有释放).
从上面可以看出, valgrind提供的诊断信息还是非常准确的, 在实际调试代码过程中, 很值得我们使用它来检测大型程序的内存泄露问题.
如果在大型程序中会输出大量的诊断信息到控制台上, 我们可以采用将诊断信息输入进本地文件的方法, 使用下面的命令
valgrind --tool=memcheck --leak-check=full --log-file=mem_leak.log valgrind_demo
这样会在当前目录下自动创建一个文件mem_leak.log来保存诊断信息,如果该文件已经存在,它会被overwrite
也可以边gdb调试, 边使用valgrind检测内存错误
valgrind --tool=memcheck --leak-check=full --log-file=mem_leak.log gdb valgrind_demo
这个好处是,当程序有段错误时,可以使用bt查看栈帧中的变量, 便于分析问题, 同时又可以查看本地日志信息, 根据valgrind的诊断信息来更进一步定位错误代码出处.