文章目录
一、ubuntu环境下valgrind的安装
ubuntu下安装很简单
sudo apt-get install valgrind
二、valgrind快速使用
2.1 valgrind介绍
Valgrind工具套件提供了许多调试和分析工具,可帮助您加快程序运行速度
更正确。这些工具中最流行的是Memcheck。它可以检测到许多与内存相关的错误
在C和C++程序中很常见,这可能导致崩溃和不可预测的行为。
本指南的其余部分提供了开始检测程序中内存错误所需的最低信息
Memcheck。有关Memcheck和其他工具的完整文档,请阅读用户手册
2.2 代码准备
当准备您的程序时,请使用-g编译程序以包括调试信息,这样Memcheck的错误消息将包含精确的行号。如果可以容忍速度降低,使用-O0也是一个好主意。使用-O1时,错误消息中的行号可能不准确,尽管一般来说在-O1上编译的代码运行Memcheck效果相当不错,并且与在-O0上运行相比速度提升相当显著。不建议使用-O2及以上,因为Memcheck有时会报告不存在的未初始化值错误。
2.3 valgrind运行待测程序
当您通常这样运行程序:
myprog arg1 arg2
请使用以下命令行:
valgrind --leak-check=yes myprog arg1 arg2
Memcheck是默认工具。–leak-check选项打开了详细的内存泄漏检测器。
您的程序将比正常情况下运行慢得多 (例如,20到30倍),并且会使用更多内存。Memcheck将发出有关它检测到的内存错误和泄漏的消息。
2.4 查看valgrind输出报告
这里提供一个测试程序,里面有两个错误,内存泄漏,越界访问。
#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;
}
使用gcc编译,加入-g -O0编译选项
gcc -g -O0 main.c -o main
valgrind输出报告
(base) jordi@jordi-PowerEdge-T30:~/workspace/3rdlibary/valgrind/test/1_memoryerr$ valgrind --leak-check=yes ./main
==54644== Memcheck, a memory error detector
==54644== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==54644== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==54644== Command: ./main
==54644==
==54644== Invalid write of size 4
==54644== at 0x401164: f (main.c:6)
==54644== by 0x401175: main (main.c:10)
==54644== Address 0x4a63068 is 0 bytes after a block of size 40 alloc'd
==54644== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==54644== by 0x401157: f (main.c:5)
==54644== by 0x401175: main (main.c:10)
==54644==
==54644==
==54644== HEAP SUMMARY:
==54644== in use at exit: 40 bytes in 1 blocks
==54644== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==54644==
==54644== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==54644== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==54644== by 0x401157: f (main.c:5)
==54644== by 0x401175: main (main.c:10)
==54644==
==54644== LEAK SUMMARY:
==54644== definitely lost: 40 bytes in 1 blocks
==54644== indirectly lost: 0 bytes in 0 blocks
==54644== possibly lost: 0 bytes in 0 blocks
==54644== still reachable: 0 bytes in 0 blocks
==54644== suppressed: 0 bytes in 0 blocks
==54644==
==54644== For lists of detected and suppressed errors, rerun with: -s
==54644== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
需要注意的事项:
- 错误消息中包含大量信息,请仔细阅读。
- 54644是进程ID,通常不重要。
- 第8行(“无效写入…”)告诉您错误类型。在这里,程序写入了一些不应属于它的内存,这是由于堆块溢出造成的。
- 第8行以下是堆栈跟踪,它会告诉您问题发生的位置。堆栈跟踪可能会非常大,并且可能会很混乱,尤其是在使用C++ STL时。从底部向上阅读可以帮助理解它。如果堆栈跟踪不够大,请使用 --num-callers 选项来扩大它。
- 代码地址(例如 0x401164)通常不重要,但偶尔对于追踪更奇怪的错误至关重要。
- 一些错误消息会显示内存越界访问。
根据错误报告的顺序修复错误是值得的,因为后面的错误可能是由早期的错误引起的。
内存泄漏消息类似于:
==54644== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==54644== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==54644== by 0x401157: f (main.c:5)
==54644== by 0x401175: main (main.c:10)
堆栈跟踪告诉您泄漏的内存是在哪里分配的。遗憾的是,Memcheck 不能告诉您为什么内存泄漏了。(忽略“vg_replace_malloc.c”,这是实现细节。)
泄漏有几种类型,其中最重要的两个类别是:
- “肯定丢失”:您的程序正在泄漏内存 - 请修复它!
- “可能丢失”:除非您正在使用指针做一些有趣的事情(例如将它们移动到指向堆块的中间),否则您的程序正在泄漏内存。
Memcheck还会报告未初始化的值的使用,最常见的是以下消息:“Conditional jump or move depends on uninitialised value(s)”。
2.5 注意事项
Memcheck并不完美,偶尔会产生误报,并且存在控制这些误报的机制(请参见Valgrind用户手册中的Suppressing errors)。但是,它通常99%的时间内是正确的,所以你应该谨慎地忽略其错误消息。毕竟,你不会忽略编译器产生的警告消息,对吧?如果Memcheck报告您无法更改的库代码中的错误,则抑制机制非常有用。默认抑制设置隐藏了很多这些,但你可能会遇到更多。
Memcheck无法检测到程序中存在的每个内存错误。例如,它不能检测到范围之外的读取或写入到静态分配或堆栈上的数组。但是,它应该能够检测到许多可能使程序崩溃的错误(例如,导致分段错误)。
尽量使您的程序保持清洁(笔者认为有内存泄漏说明有垃圾没有清除,是不干净的
),以使Memcheck不报告任何错误。
理想状态
==59371== Memcheck, a memory error detector
==59371== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==59371== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==59371== Command: ./main
==59371==
==59371==
==59371== HEAP SUMMARY:
==59371== in use at exit: 0 bytes in 0 blocks
==59371== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==59371==
==59371== All heap blocks were freed -- no leaks are possible
==59371==
==59371== For lists of detected and suppressed errors, rerun with: -s
==59371== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
一旦达到这种状态,当对程序进行更改导致Memcheck报告新错误时,就可以更容易地看到。使用Memcheck几年的经验表明,即使是庞大的程序也可以保持清洁。例如,KDE,OpenOffice.org和Firefox的很大一部分是清洁的,或者非常接近它。
好,最后希望的加写的程序无BUG,无泄漏。