找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3974|回复: 0

valgrind快速开始指南 |mociml

[复制链接]
发表于 2011-12-15 13:56:41 | 显示全部楼层 |阅读模式
1、介绍
valgrind工具套件提供了许多调试和探测工具,帮助你改进你的程序更快更准确。这些工具中最受欢迎的是memcheck,它可以检测内存相关错误,这些错误在C或C++程序中很常见,将导致崩溃或不可预期错误。本指南其他部分将提供你所需要的最简信息,使用memcheck开始检测你程序中的内存错误。memcheck所有文档及其他工具,请阅读使用手册。
2、准备程序
使用-g参数编译程序,包含调试信息,以便memcheck的错误信息包含准确的行数。使用-O0也是好办法,如果你能忍受速度慢。虽然总的来说,运行memcheck在使用-O1编译的代码上工作很好,但是使用-O1错误信息中的行号可能是不精确的,速度改进相比较于-O0是很大的。使用-O2及以上是不推荐的,因为memcheck偶尔报告实际并不存在的初始值错误。
3、运行
如果你通常运行程序按以下方式:
myprog arg1 arg2
使用命令行:valgrind --leak-check=yes myprog arg1 arg2memcheck是默认工具,--leak-check选项打开会进行详细的内存泄露检测。你的程序将会跟正常相比运行得较慢(例如:20-30倍),并使用很多内存。memcheck将会给出它检测到的内存错误和泄露信息。

4、解释memcheck输出
这里有一个示例C程序,文件为a.c,有内存错误和内存泄露。
  1. #include <stdlib.h>
  2. void f(void)
  3. {
  4. int* x = malloc(10 * sizeof(int));
  5. x[10] = 0; // problem 1: heap block overrun
  6. } // problem 2: memory leak -- x not freed
  7. int main(void)
  8. {
  9. f();
  10. return 0;
  11. }
复制代码


最重要的错误信息类似如下,描述问题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 b==19182== at 0x1B8FF5CD: malloc (vg_replace_ma==19182== by 0x8048385: f (example.c:5)==19182== by 0x80483AB: main (example.c:11)说明:

每行错误信息中有很多信息,需要认真阅读。
19182是进程ID,通常不重要。
第一行("Invalid write...")告诉你错误类型,因此说明程序写内存到不应该位置,导致堆栈溢出。
第一行以下是栈追踪信息问题发生在哪,栈追踪信息可能很丰富,令人迷惑,特别是你如果使用C++ STL。从底部倒着读更有帮助,如果栈追踪信息不够丰富,使用--num-callers 选项
代码地址(例如:0x804838F)通常不重要,但是偶尔对追踪奇怪问题是很重要的。
某些错误信息通常还有第二个组成部分,描述内存地址相关。这个描述了例子example.c中第5行写内存时超过了malloc分配的块。
根据错误报告的顺序修复错误较好,因为后面的错误可能是由于前面的错误导致的

内存泄露信息类似如下:
==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不能告诉你为什么导致内存泄露。

有许多中类型的泄露,最重要的两类:
"definitely lost": 你的程序在内存泄露,需要修复;

"probably lost": 你的程序正在泄漏内存,除非你做有趣的事情,用指针(如移动它们指向的堆块的中间)

memcheck也会报告没有初始化的变量,最常见信息是"Conditional jump or move depends on uninitialised value(s)".可能很困难去判断错误的原因,尝试使用--track-origins=yes可以获得额外信息,这会使memcheck运行较慢,但是额外信息会帮助你节省很多时间去那些未初始化的值。



作者:mociml 发表于2011-12-14 21:37:36 原文链接
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-22 18:03 , Processed in 0.016890 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表