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. 转:Selenium借助AutoIt识别上传(下载)详解

    AutoIt目前最新是v3版本,这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)中进行自动化操作.它利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动 ...

  2. Java socket通信

    首先抛开语言层面,简单介绍一下socket通信过程: 1.服务器端开启监听端口,阻塞进程  等待客户端连接 2.客户端连接,这时就产生了一个socket socket就相当于一个传递消息的通道,一般都 ...

  3. python+mysql抓取百度新闻的标题存到数据库

    #!usr/bin/python# -*- coding:utf-8 -*-import urllib2 import re import MySQLdb class BaiDuNews: def _ ...

  4. 极光推送集成——iOS10 接受消息问题及解决

    iOS10升级后极光推送发生了很大的变化,要求Xcode更新到8.0及以上版本才可以实现iOS10接受消息的方法 常见错误 这个问题困扰了我一天,辛亏好友盼神帮我解决,在此再次感谢盼神.一下是解决办法 ...

  5. Python3基础 定义无参数无返回值函数 调用会输出hello world的函数

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  6. jsp设置footer底部内容

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. ural1671 Anansi's Cobweb

    Anansi's Cobweb Time limit: 1.0 secondMemory limit: 64 MB Usatiy-Polosatiy XIII decided to destroy A ...

  8. ecos资源探测器

    两种类型的资源探测器 xml文件资源探测器 目录资源探测器 系统内置的资源探测器(核心) 数据库定义目录资源探测器 -base_application_datable 关注dbschema servi ...

  9. 控制流之for

    for..in是另外一个循环语句,它在一序列的对象上 递归 即逐一使用队列中的每个项目.我们会在后面的章节中更加详细地学习序列.使用for语句~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  10. 解决SSh连接过慢

    ssh 连接的时候特别慢 解决方法: 修改配置文件 /etc/ssh/sshd_config GSSAPIAuthentication yes --->no 81行左右 #UseDNS yes ...