Valgrind的快速入门指南

译至:http://www.valgrind.org/docs/manual/quick-start.html

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的输出

下面是一个名为
a.c 的C程序示例,包含一个内存错误和内存泄漏。

  #include <stdlib.h>

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

  int main(void)
  {
     f();
     return 0;
  }

大多数的错误信息看起来像下面的问题1堆块溢出的描述:

  ==19182== Invalid write of size 4
  ==19182==    at 0x804838F: f (example.c:6)
  ==19182==    by 0x80483AB: main (example.c:11)
  ==19182==  Address 0x1BA45050 is 0 bytes after a block of size 40 alloc‘d
  ==19182==    at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)
  ==19182==    by 0x8048385: f (example.c:5)
  ==19182==    by 0x80483AB: main (example.c:11)

要注意事项:

  • 关于每个错误消息有很多的信息;
    仔细阅读。
  • 19182是进程ID; 它通常是不重要的。
  • 第一行(“Invalid write...”)告诉你它是什么样的错误。这里,程序写到一些因堆块溢出而不应该写的内存上。
  • 第一行的下面是一个堆栈跟踪来告诉您发生问题的地方。堆栈跟踪可以变得相当大,而且会造成混淆,尤其是如果你使用C++
    STL的时候。从下往上看它们可以提供一些帮助。如果堆栈跟踪不够大,使用--num-callers来使之变得更大。
  • 代码的地址(如0x804838F)通常并不重要,但对于跟踪怪异的bug偶尔至关重要。
  • 某些错误消息有第二个部分来描述所涉及到的内存地址。上述说明了内存写的位置越过了在example.c的第5行使用malloc()分配的块的末尾处。

按错误报告的顺序来依次修改错误是值得去做的,因为后来的错误可能是由先前的错误导致的。如果不这样做,这是Memcheck难于使用的一个常见原因。

内存泄漏的消息是这样的:

  ==19182== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
  ==19182==    at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)
  ==19182==    by 0x8048385: f (a.c:5)
  ==19182==    by 0x80483AB: main (a.c:11)

堆栈跟踪告诉你泄漏的内存在哪里被分配。很遗憾,Memcheck不能告诉你为什么内存泄漏了。(忽略“vg_replace_malloc.c”,这是一个实现细节。)

有几种类型的泄漏; 最重要的两个类型是:

  • “肯定丢失”:你的程序的内存正在泄漏 - 修复它!
  • “可能丢失”:你的程序正在泄漏内存,除非你正在使用指针做有趣的事情(如移动它们指向的堆块的中间)。

Memcheck也报告未初始化值的使用,最常见的消息是"Conditional jump or move depends on uninitialised value(s)"。可以难以确定这些错误的根源。尝试使用--track-origins=yes 来获得额外的信息。这使得Memcheck运行得更慢,但你得到的额外的信息常常节省了大量的时间去搞清楚了未初始化值是从哪里来的。

如果你不理解某一错误信息,请查阅 Valgrind User Manual 的 Explanation
of error messages from Memcheck
,里面有所有Memcheck产生的错误消息的示例。

5. 注意事项

Memcheck是不完美的; 它有时会产生误报,并有抑制这些误报的机制(参见Valgrind的用户手册的 Suppressing
errors
 )。但是,它在99%的时候通常是正确的,所以你应该警惕忽视了错误信息。毕竟,你不会不理警告由编译器生成的消息,对不对?如果Memcheck报告库代码中的错误,而这些代码是你不能改变的,那么抑制机制也是有用的。默认的抑制设置隐藏了很多这样的错误,但是你可能会遇到更多。

Memcheck无法检测到你的程序的每一个内存错误。例如,它不能检测出超出范围的数组读取或写入,如果这些数组是静态分配或在栈上分配。但它能检测出许多错误,这些错误可能使你的程序崩溃(例如导致段错误)。

尽量使你的程序干净,不让Memcheck报告任何错误。一旦你达到这样的状态,当程序改变而使Memc??heck报告新的错误时,很容易发现问题。这几年Memcheck的使用经验表明,甚至能够使巨大的程序运行Memcheck而没有报告任何错误。举例来说,KDE,OpenOffice.org和Firefox的大部分都是Memcheck-clean,或者非常的接近。

6. 更多信息

请参阅 Valgrind
FAQ
 和 Valgrind User Manual,其中有更多的信息。另外,Valgrind发布版的其它工具可以使用--tool选项调用。

时间: 2024-09-26 14:53:34

Valgrind的快速入门指南的相关文章

JWPlayer快速入门指南(中文)

将JW Player嵌入到网页中非常的简单,只需要进行如下3个步骤: 1.解压mediaplayer-viral.zip文件,将jwplayer.js和player.swf文件拷贝到工程中: 2.在页面引入jwplayer.js文件: <script type="text/javascript" src="/jwplayer/jwplayer.js"></script> 3.将下面代码粘贴在body标签内,如下所示: <div id=&

Chapter 0.SymmetricDS快速入门指南( Quick Start Guide)

本文档是SymmetricDS3.6.14文档的第一章节Quick Start Guide文档的翻译,的目的是帮助读者快速搭建一个SymmetricDS集群并普及一些基本概念术语. 本文档描述了如何在两个SymmetricDS节点之间同步两个相同schema的数据库.下面的例子构建了一个分销业务模型,有一个中央数据库(我们叫它root或者corp节点)和多个零售商店的数据库(我们叫它client或者store节点).对于本教程,我们将只有一个store(商店)节点,如下图.如果你愿意,可以再教程

AngularJS快速入门指南20:快速参考

thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table.reference>thead>tr>td, table.reference>tbody>tr>td, table.reference>tfoot>tr>td { padding: 8px; line-height: 1.42857143; vertic

AngularJS快速入门指南05:控制器

AngularJS控制器用来控制AngularJS applications的数据. AngularJS控制器就是普通的JavaScript对象. AngularJS控制器 AngularJS applications通过控制器进行控制. ng-controller指令定义了一个application的控制器. 一个控制器就是一个JavaScript对象,它可以通过标准的JavaScript对象构造函数来创建. <div ng-app="myApp" ng-controller=

[转] Clojure 快速入门指南:1/3

[From] http://huangz.iteye.com/blog/1325228 导读 本文的目标是为熟悉 Ruby.Python或者其他类似语言.并对 Lisp 或者函数式编程有一定程度了解的程序员写的 Clojure 快速入门指南. 为了让文章尽可能地精炼且简单易懂,本文有以下三个特点: 一:不对读者的知识水平作任何假设,当遇上重要的知识点时,只给出 wikipedia 等网站的链接引用而不对知识点进行解释,有需要的读者可以沿着链接查看,没需要的直接略过就行了. 二:和第一条类似,没有

AngularJS快速入门指南15:API

thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table.reference>thead>tr>td, table.reference>tbody>tr>td, table.reference>tfoot>tr>td { padding: 8px; line-height: 1.42857143; vertic

AngularJS快速入门指南14:数据验证

thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table.reference>thead>tr>td, table.reference>tbody>tr>td, table.reference>tfoot>tr>td { padding: 8px; line-height: 1.42857143; vertic

AngularJS快速入门指南17:Includes

使用AngularJS,你可以在HTML中包含其它的HTML文件. 在HTML中包含其它HTML文件? 当前的HTML文档还不支持该功能.不过W3C建议在后续的HTML版本中增加HTML imports功能,以支持在HTML中包含其它的HTML文件. <link rel="import" href="/path/navigation.html"> 在服务端包含文件 大部分的web服务器都支持服务端包含文件(Server Side Includes).通过

AngularJS快速入门指南16:Bootstrap

thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table.reference>thead>tr>td, table.reference>tbody>tr>td, table.reference>tfoot>tr>td { padding: 8px; line-height: 1.42857143; vertic