valgrind快速开始指南
2011-12-14 21:37
253 查看
1、介绍
valgrind工具套件提供了许多调试和探测工具,帮助你改进你的程序更快更准确。这些工具中最受欢迎的是memcheck,它可以检测内存相关错误,这些错误在C或C++程序中很常见,将导致崩溃或不可预期错误。本指南其他部分将提供你所需要的最简信息,使用memcheck开始检测你程序中的内存错误。memcheck所有文档及其他工具,请阅读使用手册。
2、准备程序
使用-g参数编译程序,包含调试信息,以便memcheck的错误信息包含准确的行数。使用-O0也是好办法,如果你能忍受速度慢。虽然总的来说,运行memcheck在使用-O1编译的代码上工作很好,但是使用-O1错误信息中的行号可能是不精确的,速度改进相比较于-O0是很大的。使用-O2及以上是不推荐的,因为memcheck偶尔报告实际并不存在的初始值错误。
3、运行
如果你通常运行程序按以下方式:
使用命令行:
4、解释memcheck输出
这里有一个示例C程序,文件为a.c,有内存错误和内存泄露。
最重要的错误信息类似如下,描述问题1,堆栈溢出:
每行错误信息中有很多信息,需要认真阅读。
19182是进程ID,通常不重要。
第一行("Invalid write...")告诉你错误类型,因此说明程序写内存到不应该位置,导致堆栈溢出。
第一行以下是栈追踪信息问题发生在哪,栈追踪信息可能很丰富,令人迷惑,特别是你如果使用C++ STL。从底部倒着读更有帮助,如果栈追踪信息不够丰富,使用--num-callers 选项
代码地址(例如:0x804838F)通常不重要,但是偶尔对追踪奇怪问题是很重要的。
某些错误信息通常还有第二个组成部分,描述内存地址相关。这个描述了例子example.c中第5行写内存时超过了malloc分配的块。
根据错误报告的顺序修复错误较好,因为后面的错误可能是由于前面的错误导致的
内存泄露信息类似如下:
有许多中类型的泄露,最重要的两类:
"definitely lost": 你的程序在内存泄露,需要修复;
"probably lost": 你的程序正在泄漏内存,除非你做有趣的事情,用指针(如移动它们指向的堆块的中间)
memcheck也会报告没有初始化的变量,最常见信息是"Conditional jump or move depends on uninitialised value(s)".可能很困难去判断错误的原因,尝试使用--track-origins=yes可以获得额外信息,这会使memcheck运行较慢,但是额外信息会帮助你节省很多时间去那些未初始化的值。
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,有内存错误和内存泄露。
#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 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运行较慢,但是额外信息会帮助你节省很多时间去那些未初始化的值。
相关文章推荐
- MAPublisher9.5快速开始指南 第3章 地图重投影和地图比例尺
- Kubernetes用户指南(一)--快速开始、使用k8s配置文件
- WPF/MVVM 快速开始指南(译)
- 谷歌眼镜GDK开发指南之快速开始
- Valgrind快速入门指南
- Kubernetes用户指南(一)--快速开始、使用k8s配置文件
- Kubernetes用户指南(一)--快速开始、使用k8s配置文件
- pycurl 快速开始指南
- WPF/MVVM 快速开始指南
- MAPublisher9.5快速开始指南 第1章
- MAPublisher9.5快速开始指南 第4章 合并表格到地图属性
- Quartz 企业级任务调度框架(三)之快速开始指南
- Valgrind的快速入门指南
- 翻译-QPKG开发工具快速开始指南
- 百度Apollo1.0快速开始指南
- Weex 入坑指南:快速开始 Weex 之旅
- 谷歌眼镜GDK开发指南之快速开始
- MAPublisher9.5快速开始指南 第5章 符号化和地图专题
- MAPublisher9.5快速开始指南 第9章 导出到Web
- django-registration 0.8 中文文档[原创] ——快速开始指南