您的位置:首页 > 其它

valgrind快速入门手册

2012-10-23 16:20 381 查看
最近空闲时间比较多,于是,决定自行研究点东西。
话不多说,这个系列是翻译valgrind官网的文档手册,第一次做这样的事情,尽量吧~
先介绍下valgrind是什么东东:
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。Valgrind这个名字取自北欧神话中英灵殿的入口(摘自wiki百科)
那么下面就开始吧。
valgrind快速入门指南
1、介绍:
这个valgrind工具系列提供若干调试和分析工具以帮助你的程序更快、更健壮。这其中的佼佼者就是memcheck了,它能检测到许多内存相关的错误,这些错误存在于你写的c/c++程序当中,并且这些错误可能导致程序崩溃或者出现一些不可预知的行为。
本指引提供让你运用memcheck上手去检测你编写的程序的内存错误的最少的信息,如果要了解更多关于Memcheck的文档信息或者其它工具,请参考官网的usermanual。
2、准备你的程序:
让你的程序带有-g的编译选项,这样可以让memcheck工具能精准的标识行号等信息。如果你能容忍程序稍微慢点,加上-00就更好了。如果是-01选项,那么行号的错误信息可能不是很准确,虽然整体来说memcheck工具在这个编译选项下也工作的很好并且相比-00速度更快。-02的编译选项就不推荐了,因为这样会容易导致memcheck误报错。
3、让你的程序在memcheck下运行:
如果你是这样运行你的程序的:
myprogarg1arg2
那么可以运行这个命令行
valgrind--leak-check=yesmyprogarg1arg2
memchekc是默认的工具,--leak-chekc选项是打开具体的内存泄漏探测器。
运行memcheck之后,你的程序会比原来的慢20-30倍,并且占用更多内存,memcheck会对探测到的内存错误或者泄漏进行消息显示。
4、打断memcheck的输出:
这里有一个示例程序叫a.c,有内存错误和内存泄漏
#include<stdlib.h>
voidf(void)
{
int*x=malloc(10*sizeof(int));
x[10]=0;//problem1:heapblockoverrun
//problem2:memoryleak--xnotfreed



}
intmain(void){f();return0;}



多数错误信息如下所示,用来描述problem1的,堆内存越界。

==19182==Invalidwriteofsize4
==19182==at0x804838F:f(example.c:6)
==19182==by0x80483AB:main(example.c:11)
==19182==Address0x1BA45050is0bytesafterablockofsize40alloc'd
==19182==at0x1B8FF5CD:malloc(vg_replace_malloc.c:130)
==19182==by0x8048385:f(example.c:5)
==19182==by0x80483AB:main(example.c:11)
以下事项是需要注意的:

这里有大量的错误信息,需要仔细读。

19182是进程id,通常这是没有用的。

第一行的错误提示(invalidwrite)告诉你这是什么样的错误,这里是指程序写了堆中的越界非法内存。

第一行以下的是这个错误发生的一些堆栈跟踪信息。这些堆栈跟踪可能很大,可能让你迷惑,尤其是你运用了c++STL之后。

代码地址比如0x804838F通常是没用的,但是有时对一些奇怪的错误又是关键性的信息。

但是,memcheck泄漏信息却是类似这样的:

==19182==40bytesin1blocksaredefinitelylostinlossrecord1of1
==19182==at0x1B8FF5CD:malloc(vg_replace_malloc.c:130)
==19182==by0x8048385:f(a.c:5)==19182==by0x80483AB:main(a.c:11)


这里的堆栈跟踪告诉你泄漏的内存是在哪里分配的,很遗憾的是,memcheck不能告诉你为什么会造成内存泄漏。

这里可能有几种内存泄漏,最重要的两种如下所示:

definitelylost:那么这表明你的程序存在内存泄漏,修复它

probablylost:那么这表明你的程序存在内存泄漏,除非是你正在使用指针(比如用指针向堆中内存move数据)

memchekc同样会报对未初始化变量的使用,一般会显示这样的信息“"Conditionaljumpormovedependsonuninitialisedvalue(s)"”,这很难定位错误根源,可以尝试使用--track-origins=yes来得到额外的信息,不过这会导致程序运行的更慢,不过这些额外的信息能帮助你比较快速定位的未初试化变量的来源。

5、警告:

memcheck不是完美的,它偶尔会报错误的错,不过这里有机制压抑它,详细见usermanual。

不过,它能保证99%的正确率,所以你应该警惕它的报错信息,毕竟,就像你不会忽略编译器的错误信息,对吗?

memchekc不能侦探到程序的每个内存错误,举例说明,它不能检测到越界读写栈中静态分配的数组的错误,但是它还是可以帮助你找到很多可能导致你程序崩溃的内存错误的

努力尝试使你的程序很干净,让memcheck都不会报任何错误信息。一旦你达到这个状态,当你的程序发生变更,你就很容易知道memcheck报的新错误了。几年以上的memcheck使用经验可以让你,即使很大的程序都能做到memcheck不报任何错误,也就是memcheck-clean.这里有不少这样的例子,比如BSD/Firefox/OpenOffice.org,这些项目都是memcheck-clean.

6、更多信息:

更多信息请咨询FAQ或者浏览Usermanual。链接为:http://valgrind.org/docs/manual/manual.html,英文版,有时间继续翻译。














                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: