前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >valgrind使用介绍

valgrind使用介绍

原创
作者头像
yzh
修改2020-09-07 17:40:28
2.8K0
修改2020-09-07 17:40:28
举报
文章被收录于专栏:YZh学习记录YZh学习记录

一、valgrind 安装步骤(linux)

代码语言:javascript
复制
#下载                 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 
安装完成
安装完成
代码语言:javascript
复制
 #配置环境变量              vim ~/.bashrc 

#将bin文件夹的路径放置.bashrc文件最后

环境变量配置
环境变量配置
代码语言:javascript
复制
#使改变生效               source ~/.bashrc

至此,完成valgrind的安装。

二、 valgrind工具介绍

  1. Memcheck是内存错误检测器。它可以帮助您使程序,尤其是用C和C ++编写的程序更加正确。
  2. Cachegrind是一个缓存和分支预测探查器。它可以帮助您使程序运行更快。
  3. Callgrind是一个生成调用图的缓存分析器。它与Cachegrind有一些重叠,但也收集了Cachegrind没有的一些信息。
  4. Helgrind是线程错误检测器。它可以帮助您使多线程程序更正确。
  5. DRD还是线程错误检测器。它类似于Helgrind,但是使用不同的分析技术,因此可能会发现不同的问题。
  6. Massif是堆分析器。它可以帮助您减少程序使用的内存。
  7. DHAT是另一种堆分析器。它可以帮助您了解模块寿命,模块利用率和布局效率低下的问题。
  8. BBV是一个实验性的SimPoint基本块矢量生成器。这对从事计算机体系结构研究和开发的人员很有用。

三、 编译程序

使用编译命令生成可执行程序

代码语言:javascript
复制
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

四、log内容组成介绍:

(1)版本信息

代码语言:javascript
复制
==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)总结信息

代码语言:javascript
复制
==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)

五、 用valgrind运行程序,输出log

memcheck是valgrind tool的一种,是一个细粒度的的内存检查器。它可以检测以下问题:

1)使用未初始化的内存

测试代码

代码语言:javascript
复制
//类型1: 使用未初始化的栈空间
#include <iostream>
using namespace std;

int main()
{
    int a;
    cout << a + 3 <<endl;
    return 0;
}

编译命令

代码语言:javascript
复制
g++ -g -o val 04.cpp
valgrind --log-file=04_1.log --track-origins=yes ./val

--track-origins=yes 表示开启“使用未初始化的内存”的检测功能,并打开详细结果。如果没有这句话,默认也会做这方面的检测,但不会打印详细结果。如:如果只使用1中的命令行,不会显示详细信息。

检测结果

代码语言:javascript
复制
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)     #使用栈空间,定位该函数的左括号位置

命令栏详细解读:

代码语言:javascript
复制
--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)内存泄漏

内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

测试代码

代码语言:javascript
复制
#include <iostream>
using namespace std;

int main()
{
    int *p = new int;
    return 0;
}

编译命令

代码语言:javascript
复制
g++ -g -o memleak 05.cpp
valgrind --log-file=05_1.log --leak-check=full ./memleak

检测结果

代码语言:javascript
复制
==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)           #详细错误信息,定位到行号

命令栏详细解读:

代码语言:javascript
复制
--leak-check=<no|summary|yes|full>[default: summary]
  • --leak-check 指定如何报告内存泄漏(memcheck能检查多种内存使用错误,内存泄漏是其中常见的一种),可选值有:

no 不报告

summary 显示简要信息,有多少个内存泄漏。summary是缺省值。

yes 和 full 显示每个泄漏的内存在哪里分配。

代码语言:javascript
复制
--show-leak-kinds=<set> [default: definite,possible]
  • show-leak-kinds 配合内存泄漏使用,指定显示内存泄漏的类型的组合。类型包括definite, indirect, possible,reachable。
  • 也可以指定all或none。

其他未初始化内存示例可参考:

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)读/写不恰当的内存栈空间

五、Memcheck 命令行选项解读

代码语言:javascript
复制
valgrind --log-file=03_8.log --tool=memcheck   ./test
  • --log-file 报告文件名。如果没有指定,输出到stderr。
  • --tool=memcheck 指定Valgrind使用的工具。Valgrind是一个工具集,包括Memcheck、Cachegrind、Callgrind等多个工具。memcheck是默认项。
代码语言:javascript
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、valgrind 安装步骤(linux)
  • 二、 valgrind工具介绍
  • 三、 编译程序
  • 四、log内容组成介绍:
  • 五、 用valgrind运行程序,输出log
  • 五、Memcheck 命令行选项解读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档