#下载 wget http://valgrind.org/downloads/valgrind-3.14.0.tar.bz2
#解压 tar xvf valgrind-3.14.0.tar.bz2
#进入指定目录 cd valgrind-3.14.0/
#指定路径 ./configure --prefix=/home/yuanzhihong/valgrind/valgrind-3.14.0
make
make install #若安装不成功,重新make时,记得make clean
#检查是否安装成功
cd bin
./valgrind --version
#配置环境变量 vim ~/.bashrc
#将bin文件夹的路径放置.bashrc文件最后
#使改变生效 source ~/.bashrc
至此,完成valgrind的安装。
使用编译命令生成可执行程序
gcc -Wall main.c -g -o test
-Wall 表示生成警告信息
main.c 代表要编译的源文件
-g 生成调试信息
-o file 生成可执行文件
-O0 、-O1 、-O2 、-O3 编译器的优化选项的 4 个级别,-O0 表示没有优化, -O1 为默认值,-O3 优化级别最高。
注意:
(1)打开调试模式(gcc编译器的-g选项)。如果没有调试信息,即使最好的valgrind工具也将只能够猜测特定的代码是属于哪一个函数。打开调试选项进行编译后再用valgrind检查,valgrind将会给出具体到某一行的详细报告。
(2)关闭编译优化选项(比如-O2或者更高的优化选项)。这些优化选项可能会使得memcheck提交错误的未初始化报告,因此,为了使得valgrind的报告更精确,在编译的时候最好不要使用优化选项。
其他关于gcc的参数可参考https://www.runoob.com/w3cnote/gcc-parameter-detail.html
(1)版本信息
==28431== Memcheck, a memory error detector
==28431== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==28431== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==28431== Command: ./val
其中==中间的数字(28431)是valgrind的进程ID,也是program的进程ID,它们是同一个进程。
(2)错误信息
不同的命令出现不同的log内容,不同的错误输出也不同
(3)总结信息
==26787== HEAP SUMMARY:
==26787== in use at exit: 0 bytes in 0 blocks
==26787== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==26787==
==26787== All heap blocks were freed -- no leaks are possible
==26787==
==26787== For counts of detected and suppressed errors, rerun with: -v
==26787== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
memcheck是valgrind tool的一种,是一个细粒度的的内存检查器。它可以检测以下问题:
1)使用未初始化的内存
测试代码
//类型1: 使用未初始化的栈空间
#include <iostream>
using namespace std;
int main()
{
int a;
cout << a + 3 <<endl;
return 0;
}
编译命令
g++ -g -o val 04.cpp
valgrind --log-file=04_1.log --track-origins=yes ./val
--track-origins=yes 表示开启“使用未初始化的内存”的检测功能,并打开详细结果。如果没有这句话,默认也会做这方面的检测,但不会打印详细结果。如:如果只使用1中的命令行,不会显示详细信息。
检测结果
Use of uninitialised value of size 8 #计算出未初始化的空间大小,不过计算错了
==26787== at 0x4F4462E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==26787== by 0x4F44B53: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==26787== by 0x4F51074: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==26787== by 0x1088A5: main (04.cpp:15)
==26787== Uninitialised value was created by a stack allocation #识别出未初始化的值使用栈空间
==26787== at 0x10888A: main (04.cpp:13) #使用栈空间,定位该函数的左括号位置
命令栏详细解读:
--track-origins=<yes|no> [default: no]
控制Memcheck是否跟踪未初始化值的来源。默认为no
设置yes为时,Memcheck会跟踪所有未初始化值的来源。然后,当报告未初始化的值错误时,Memcheck将尝试显示值的来源。
对于源自堆的未初始化值,Memcheck将显示堆的分配位置。
对于源自栈分配的未初始化值,Memcheck可以告诉您哪个函数分配了该值,它会向您显示该函数的左括号的位置。因此,应该仔细检查函数的所有局部变量是否已正确初始化。
性能:使Memcheck的速度减半,并将内存使用量至少增加100MB,甚至可能更多。
其他未初始化内存示例可参考:
http://windmissing.github.io/linux/2016-02/valgrind-memcheck-uninitialized.html
2)内存泄漏
内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
测试代码
#include <iostream>
using namespace std;
int main()
{
int *p = new int;
return 0;
}
编译命令
g++ -g -o memleak 05.cpp
valgrind --log-file=05_1.log --leak-check=full ./memleak
检测结果
==29197== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==29197== at 0x4C3042A: operator new(unsigned long) (vg_replace_malloc.c:334)
==29197== by 0x10879B: main (05.cpp:13) #详细错误信息,定位到行号
命令栏详细解读:
--leak-check=<no|summary|yes|full>[default: summary]
no 不报告
summary 显示简要信息,有多少个内存泄漏。summary是缺省值。
yes 和 full 显示每个泄漏的内存在哪里分配。
--show-leak-kinds=<set> [default: definite,possible]
其他未初始化内存示例可参考:
http://windmissing.github.io/linux/2016-02/valgrind-memcheck-memleak.html
3)使用malloc/new/new[]和free/delete/delete[]不匹配
http://windmissing.github.io/linux/2016-02/valgrind-memcheck-mismatch.html
4)src和dst的重叠
5)读/写已经被释放的内存
http://windmissing.github.io/linux/2016-02/valgrind-memcheck-deleted.html
6)读/写内存越界
7)读/写不恰当的内存栈空间
valgrind --log-file=03_8.log --tool=memcheck ./test
valgrind ./test #通用命令
其他命令行使用方法
参考链接:https://www.valgrind.org/docs/manual/mc-manual.html
definitely lost:内存没有被释放,且没有任何指针指向这里。肯定泄漏了。报告给出的堆栈是内存被分配时的调用堆栈,它可以基本明确内存是由什么业务逻辑创建的。
still reachable:是说内存没有被释放,尽管如此仍有指针指向,内存仍在使用中,这可以不算泄露。(程序退出时仍在工作的异步系统调用?)
possibly lost:是说可能有泄漏,一般是有二级指针(指针的指针)等复杂情况不易于追踪时出现。
suppressed:统计了使用valgrind的某些参数取消了特定库的某些错误,会被归结到这里
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。