1. 介绍

Valgrind工具组提供了一套调试与分析错误的工具包,能够帮助你的程序工作的更加准确,更加快速。这些工具之中最有名的是Memcheck。它能够识别很多C或者C++程序中内存相关的错误,这些错误会导致程序崩溃或者出现不可预知的行为。

接下来会以最短的篇幅告诉你如何使用Memcheck来识别你写的程序中的内存错误。你可以从用户手册中获取Memcheck的完整文档以及其他工具的使用说明。

2. 准备你的程序

在编译程序时开启-g选项来引入调试信息,这样Memcheck的错误信息中能够准确的显示问题代码的序号。如果你能够容忍一些性能损失,请使用-O0选项来编译程序.使用-O1方式来编译程序错误信息可能会不准确,虽然大体而言在使用-O1方式编译的程序上使用Memcheck没有问题,而且相比-O0方式编译的程序而言性能大为提升.不推荐使用-O2或者更高级别来编译程序,因为Memcheck偶尔会误报值未初始化的错误.

3.在Memcheck下运行你的程序

如果你的程序按照以下方式运行:

myprog arg1 arg2

请使用下述命令来执行内存检查:

valgrind --leak-check=yes myprog arg1 arg2

Memcheck是默认的工具,开启--leak-check选项会启动内存泄露检查.

你的程序会比正常运行慢很多(大概20到30倍),并且会使用更多的内存.Memcheck会记录检测到的内存错误和内存泄露信息.

4.解释Memcheck的输出信息

这是我们的用于示例的C程序代码,其文件名为a.c,这段代码中有一个内存错误和内存泄露问题.

#include <stdio.h>

void f(){
int * x = malloc(10 * sizeof(int));
x[10] = 0; //problem 1: heap block overrun
//problem 2: memory leak -- x not freed
}
int main(){
f();
return 0;
}

下面是使用上述C代码生成程序的makefile文件.

example:example.o
gcc -o example example.o example.o:a.c
gcc -c -O0 -g -Wall a.c -o example.o .PHONY:clean
clean:
-rm -rf *.o example

使用下述命令检查程序中的内存错误:

valgrind --leak-check=yes ./example

大多数的错误信息和下面的一致,下面展示了内存越界的错误:

==5753== Invalid write of size 4
==5753== at 0x40053B: f (a.c:5)
==5753== by 0x40054B: main (a.c:9)
==5753== Address 0x51fc068 is 0 bytes after a block of size 40 alloc'd
==5753== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5753== by 0x40052E: f (a.c:4)
==5753== by 0x40054B: main (a.c:9)

注意:

  • 每一个错误有很多信息, 请认真阅读
  • 5732是进程ID,这一般不重要
  • 第一行Invalid write告诉你出现了哪一种错误.因为内存泄露,程序向本不能访问的内存进行了写入操作.
  • 在第一行之后紧跟的堆栈轨迹信息告诉你问题出现的位置. 堆栈轨迹信息可能会非常大,非常令人迷惑,特别是当你使用C++ STL的时候.推荐按照从下到上的顺序进行阅读.如果堆栈轨迹信息不够,可以使用--num-callers选项来扩充堆栈轨迹信息.
  • 代码地址(例如:0x40054B) 一般不重要,但是有时在追踪神秘的bug时会很有用.
  • 一些错误信息有第二个部分描述了涉及到的内存地址.这一段表明了写入的内存正好在malloc函数分配的内存的后面,对应代码中的第9行.

推荐按照提示的顺序来修复错误.因为后面的错误可能因为前面的错误导致.否则你会觉得Memcheck不好用.

内存泄露信息如下所示:

==5753== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5753== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5753== by 0x40052E: f (a.c:4)
==5753== by 0x40054B: main (a.c:9)

堆栈追踪信息告诉你泄露的内存在哪里分配的.Memcheck不能告诉你为什么内存会泄露.

有几种不同的内存泄露方式,其中最重要的两种类别是:

  • "definitely lost": 你的程序泄露了内存,请修复这个错误.
  • "probably lost": 你的程序泄露了内存,除非你在"玩弄"指针(例如移动指针到分配的内存块的中间位置)

如果你不理解错误信息,请查询用户手册中关于Memcheck错误信息的说明,其中举例说明了Memcheck产生的所有类型的错误信息.

5.警告

Memcheck并不完美,它偶尔会误报,有些机制可以抑制这些误报.(请参考用户手册中的减少出错章节).然而,他在99%的情况下都不会出错,所以你需要谨慎地忽略它报告的错误信息.毕竟,你也不会忽略编译器的报警信息.抑制机制对于你不能修改的库代码也有用.默认的抑制会影响库代码中的内存错误.

Memcheck不能够侦测你程序中的所有内存错误.比如,他不能识别越界读,或者对分配到栈区的数组的越界写入.但是它能够识别能导致你程序崩溃的大多数错误.

尝试使你的程序更加清晰,这样Memcheck检测不出错误.当你达到这种状态,你会更容易发现对程序的哪些修改导致Memcheck报告了新的错误.数年的Memcheck使用经验说明,大型程序也能够使用Memcheck. 比如KDE,Firefox等.

6.更多信息

请查询 Valgrind FAQ Valgrind User Manual.使用--tool选项可以使用Valgrind中的其他工具.

Valgrind 快速入门的更多相关文章

  1. Valgrind的Memcheck快速入门

    一.前言        对于C/C++程序员来说,关于内存问题真是让人头痛不已,尤其是内存泄露.使用未初始化的局部变量进行跳转或移动等隐形问题.要求程序员养成良好的编码习惯确实很重要,但是人总会出现稀 ...

  2. Web Api 入门实战 (快速入门+工具使用+不依赖IIS)

    平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...

  3. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  4. 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)

    今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...

  5. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  6. 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  7. Mybatis框架 的快速入门

    MyBatis 简介 什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果 ...

  8. grunt快速入门

    快速入门 Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. Grunt 0.4.x 必须配合Node.js >= 0.8.0版本使用.:奇数版本 ...

  9. 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

随机推荐

  1. Python中括号的区别及用途

    python语言最常见的括号有三种,分别是:小括号( ).中括号[ ]和大括号也叫做花括号{ }.其作用也各不相同,分别用来代表不同的python基本内置数据类型. python中的小括号( ):代表 ...

  2. edittext判断获取焦点 有焦点显示clear

    mPhoneEt.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange( ...

  3. ASP.NET WEB开发,实现上传图片

    protected void btnUp_Click(object sender, EventArgs e) { Boolean fileOK = false; String path = Serve ...

  4. android Service Activity三种交互方式(付源码)(转)

    android Service Activity三种交互方式(付源码) Android应用服务器OSBeanthread  android Service Binder交互通信实例 最下边有源代码: ...

  5. FragmentActivity与Fragment两者交互方法简介(转)

    FragmentActivity与Fragment两者交互方法简介 分类: Fragment 2014-07-07 18:17 88人阅读 评论(0) 收藏 举报 在Android4.0后很多时候我们 ...

  6. pycharm 安装venv的依赖包

    (venv)$ pip install -r requirements.txt

  7. Swift中异常处理(续集.正则)

    正则表达式 1.创建正则表达式的规则 let pattern = "abc" 2.创建正则表达式对象 // 方式一:try方式 do { let regex = try NSReg ...

  8. POJ 2482 Stars in Your Window

    线段树+离散化+扫描线 AC之后,又认真读了一遍题目,好文章. #include<cstdio> #include<map> #include<algorithm> ...

  9. ASP.NET MVC 5 WEB API 用户验证

    参考博客:ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1) 参考博客:MVC WebApi 用户验证 (2)构建ASP.NET MVC5+E ...

  10. 卷积神经网络在tenserflow的实现

    卷积神经网络的理论基础看这篇:http://blog.csdn.net/stdcoutzyx/article/details/41596663/ 卷积神经网络的tenserflow教程看这里:http ...