安装Valgrind并检查内存泄露

转自: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并检查内存泄露_第1张图片


Valgrind使用方法
用法: valgrind [options] prog-and-args [options]: 
常用选项,适用于所有Valgrind工具
-tool= 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
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使用举例

安装Valgrind并检查内存泄露_第2张图片

下面是一段明显有问题的代码文件valgrind_demo.c,我们使用Valgrind来查找它的错误。

 

 
  1. //gcc -Wall -g valgrind_demo.c -o valgrind_demo

  2. //

  3. #include

  4.  
  5. void f(void){

  6. int* x = malloc(10 * sizeof(int));

  7. x[10] = 0; //问题1:内存越界

  8. //问题2:内存泄露

  9. }

  10.  
  11. int main(int argc, char* argv[]){

  12. f();

  13. return 0;

  14. }

首先编译程序

 

gcc -Wall -g valgrind_demo.c -o valgrind_demo

这里使用-Wall是开启编译过程中所有的warning, -g是便于我们更仔细地调试程序.

然后运行程序,使用valgrind来检查该程序的bug

valgrind --tool=memcheck --leak-check=full valgrind_demo

下面是valgrind检查效果截图

安装Valgrind并检查内存泄露_第3张图片
从截图的最后一个标注处看出,该程序有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的诊断信息来更进一步定位错误代码出处.

你可能感兴趣的:(linux系统)