valgrind的使用

这篇具有很好参考价值的文章主要介绍了valgrind的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 简述valgrind是什么,为何能进行内存泄露
valgrind是一个程序调试及性能分析的工具集,涵盖memcheck, cachegrind,helgrind,callgrind,启动valgrind时通过–tool来指定具体要调用的工具。不论使用哪个工具,通过valgrind来启动程序时都会取得对程序的控制权,从关联库中读取调试信息。然后在valgrind核心提供的虚拟CPU上运行程序,根据选择的工具处理代码,该工具会向代码中植入检测代码,并把这些代码作为最终代码返回给valgrind核心,最后valgrind核心运行这些代码。

我们最常用valgrind进行内存泄露检查,通过–tool = memcheck --leak-check=yes指定。需要注意的是,memcheck会加入代码检查每一片内存的访问和进行值运算,导致整体代码大小至少增加12倍,运行速度比平时慢25-50倍,所以使用valgrind时,保证机器环境有足够多的内存,如果进程本身启动内存有十几G,那用valgrind启动程序时,一般启动特别慢,可能1h才能启动程序。或者,valgrind根本就拉不起来程序,此时,需要修改程序的相关配置参数,想办法将程序启动的进程内存减小。

二.编译程序时的注意

  1. 编译时,打开调试模式(gcc编译器的-g选项)。

  2. 编译时,关闭编译优化选项。一些编译优化选项(比如-O2或者更高的优化选项),可能会使得memcheck提交错误的未初始化报告,因此,为了使得valgrind的报告更精确,在编译的时候最好不要使用优化选项。

  3. 如果程序有对tcmalloc编译依赖的话,需要将tcmalloc从编译依赖中去掉,否则valgrind扫描可能会遗漏一些报警信息。

  4. 当检查的是C++程序的时候,还应该考虑另一个选项 -fno-inline。它使得函数调用链很清晰,这样可以减少你在浏览大型C++程序时的混乱。比如在使用这个选项的时候,用memcheck检查openoffice就很容易。当然,你可能不会做这项工作,但是使用这一选项使得valgrind生成更精确的错误报告和减少混乱。

三. valgrind下载 & 安装
—> 下载:wget http://www.valgrind.org/downloads/valgrind-3.8.1.tar.bz2

目前最新的版本是:Release 3.12.0 20 October 2016

—> 解压:bzip2 -d valgrind-3.8.1.tar.bz2; tar -xvf valgrind-3.8.1.tar

—> 安装: cd valgrind-3.8.1; ./configure --prefix=/home/work/tools/valgrind-3.8.1.install;make;make install

安装好后在valgrind-3.8.1.install目录里有: bin, lib, include, share 4个子目录

—> 确认是否安装正确:valgrind --version

—> 编辑/etc/profile,将valgrind工具加入PATH,再source /etc/profile,这样每次使用时都是新安装的valgrind

四、valgrind memcheck选项
参见手册http://www.valgrind.org/docs/manual/mc-manual.html

valgrind的选项非常的多,可以参考翻译手册中的说明进行选用,下面列出几个比较常用的:

Option :–leak-check=no|summary|full|yes  [default summary]

Purpose : 当这个选项打开时,会当客户程序结束时查找内存泄露。如果设置为summary,Valgrind会报告有多少内存泄露发生了。如果设置为full或yes,Valgrind给出每一个独立的泄露的详细信息。

Option :–leak-resolution=high|med|low  [default low]

Purpose :在做内存泄漏检查时,确定memcheck将怎么样考虑不同的栈是相同的情况。当设置为low时,只需要前两层栈匹配就认为是相同的情况;当设置为med,必须要四层栈匹配,当设置为high时,所有层次的栈都必须匹配。

注意–leak-resolution= 设置并不影响memcheck查找内存泄漏的能力。它只是改变了结果如何输出。

Option: --show-reachable=yes|no  [default no]

Purpose : 当这个选项关闭时,内存泄露检测器只显示没有指针指向的内存块,或者只能找到指向块中间的指针。当这个选项打开时,内存泄露检测器还报告有指针指向的内存块。这些块是最有可能出现内存泄露的地方。你的程序可能,至少在原则上,应该在退出前释放这些内存块。这些有指针指向的内存块和没有指针指向的内存块,或者只有内部指针指向的块,都可能产生内存泄露,因为实际上没有一个指向块起始的指针可以拿来释放,即使你想去释放它。

Option: -v

Purpose : 显示详细信息。在各个方面显示你的程序的额外信息,例如:共享对象加载,使用的重置,执行引擎和工具的进程,异常行为的警告信息。重复这个标记可以增加详细的级别。

Option : -fno-inline

Purpose : 当检查的是C++程序的时候,可考虑这个选项-fno-inline。它使得函数调用链很清晰

Option : --max-stackframe=[default: 2000000]

Purpose : 栈的最大值,默认2000000。如果栈指针的偏移超过这个数量,valgrind则会认为程序是切换到了另外一个栈执行。

五. 内存泄露扫描过程
—> 程序启动(如果程序本身内存十几个G,启动非常慢,可能1h多才启动):

nohup valgrind–tool=memcheck --leak-check=full --show-reachable=yes

–max-stackframe=8000000 --log-file=./valgrind.log [程序启动命令] &

—> 判断程序是否启动成功:

搜索程序端口是否被监听来判断程序是否被valgrind拉起

netstat -anlp|grep 9600|grep LISTEN   ##如果进程名是valgrind,则表示程序已经在valgrind环境中启动成功。

—> 给程序放一些请求,请求尽可能覆盖到程序的各个分支

—> 程序优雅退出,不要让服务在valgrind环境里core掉了。尽量服务有捕获kill信号能力,一般kill -9 pid会导致服务core掉。

—> 退出等待个几分钟,让valgrind收集退出信息输出到valgrind.log。最后分析valgrind.log

六. valgrind.log 报告分析
见手册http://www.valgrind.org/docs/manual/mc-manual.html ,关注关注definitely lost和possible lost处可能的内存泄露。

1)首先搜关键字『LEAK SUMMARY』,看『definitely lost』对应是否有值,如果不为0,肯定有内存泄露。

2)如果有内存泄露,往上搜报告中『definitely lost in loss』的报警处,对照程序代码一一排查。

3)常见内存泄露警告

—> a. Illegal read / Illegal write errors

已释放后的内存进行读/写或数组的越界访问等,valgrind报告程序在尝试读写非法内存,造成的后果是程序易发生segmentation fault(吐core)风险。

Invalid write of size X,访问超出了范围的内存,试图从该内存读取数据

—> b. Use of uninitialised values

检测使用未初始化变量,可以检测在条件判断语句中使用未初始化变量,因此应该养成在声明变量时就进行初始化的习惯

Conditional jump or move depends on uninitialised value(s)

—> c. When a heap block is freed with an inappropriate deallocation function

使用不正确的方法释放内存,比如new/delete , malloc/free使用混淆了,new分配的地方用free释放了

Mismatched free() / delete / delete []

—> d. Illegal frees

重复内存释放,比如2次使用free释放同一块内存

Invalid free() / delete / delete[]

—> e. Overlapping source and destination blocks

针对C语言常见的memcpy, strcpy, strncpy, strcat, strncat拷贝类函数,出现源串和目标串地址重叠

Source and destination overlap in memcpy(0xbffff294, 0xbffff280, 21)

—> f. Fishy argument values

所有内存分配类函数在分配内存时,都会传入一个内存分配大小的数,如果你传入的数大于机器所能分配的最大数时,如64位机器上,你传入的size大于了2**63

Argument ‘size’ of function malloc has a fishy (possibly negative) value: -3

—> g. Leak detecion

HEAP SUMMARY:

如果指定–show-reachable=yes,在程序退出时memcheck会收集reachable and indirectly lost blocks

LEAK SUMMARY:

memcheck会记录由malloc/new等函数创建的所有的heap blocks,因此在程序退出时,memcheck能够知道哪些block没有free。如下:

definitely lost: 4 bytes in 1 blocks

indirectly lost: 0 bytes in 0 blocks

possibly lost: 0 bytes in 0 blocks

still reachable: 95 bytes in 6 blocks

definitely lost:如果一个block在程序在退出后,memcheck找不到指向它的pointer,一般是由于在代码中对该block没有free造成的,要重点关注。

possibly lost:在程序退出时,memcheck发现仍有 interior pointer(如果一个pointer指向一个block的中间某个位置)指向一个block,那么该block被认为是possibly lost。

still reachable:如果memcheck发现仍有start pointer指向一个block,那么该block就是still reachable。

4)valgrind不能查出哪些错误?

valgrind不对静态数组(分配在栈上)进行边界检查。如果在程序中声明了一个数组:

int main()

{

char x[10];

x[11] = ´a´;

}

valgrind则不会警告你,出于测试目的,你可以把数组改为动态在堆上分配的数组,这样就可能进行边界检查了。这个方法好像有点得不偿失的感觉。

七. 安装或使用中踩得各种坑
1)valgrind: failed to start tool ‘memcheck’ for platform ‘amd64-linux’

解决办法:

该错误是valgrind启动时,无法找到相关工具文件,有可能是安装好后相关lib的path未设置,也有可能是一开始安装就有问题。解决办法如下:

如果已经安装成功,试一下导出VALGRIND_LIB路径,用法如下(假设valgrind已经被安装到/home/work/tools/valgrind目录):##亲测有效##

export VALGRIND_LIB=/home/work/tools/valgrind3.8.1/lib/valgrind

2)valgrind --version报错

valgrind: mmap((nil), 134512640) failed during startup.

valgrind: is there a hard virtual memory limit set?

解决办法:

见下,版本太老,里边有bug,重新安装一下较新版本应该能解决。https://twiki.cern.ch/twiki/bin/view/LHCb/CodeAnalysisTools

3)vg_alloc_ThreadState: no free slots available

Increase VG_N_THREADS, rebuild and try again.

valgrind: the ‘impossible’ happened:

VG_N_THREADS is too low

解决办法:

a) 修改VG_N_THREADS和NTHREADS的值,安装用的是3.8.1版本,默认VG_N_THREADS是500,现在改为5000,同时NTHREADS由498改成4998。

include/pub_tool_threadstate.h: #define VG_N_THREADS 5000

./memcheck/tests/err_disable4.c: #define NTHREADS 4998  // VG_N_THREADS - 2

b) 按照1进行重新安装。

  1. Valgrind: FATAL: VG_N_SEGMENTS is too low.

解决办法:

VG_N_SEGMENTS默认是5000。修改coregrind/m_aspacemgr/aspacemgr-linux.c: VG_N_SEGMENTS从5000改到50000,VG_N_NAME从1000改到5000。

按照1进行重新安装。

5)valgrind.log报告中,在definitely lost的代码处全是?????全写花了,看不出具体泄露的是在哪一行代码

解决办法:

加上-g,打开调试信息重新编译程序;

valgrind扫描时加上–show-reachable=yes。

参考:

  1. http://www.xlgps.com/article/216977.html

  2. 如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测

3. 用Valgrind查找内存泄漏和无效内存访问

4. valgrind介绍

作者:Shirley_奋进中的虾米
链接:https://www.jianshu.com/p/9c732c91dc79
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章来源地址https://www.toymoban.com/news/detail-677913.html

到了这里,关于valgrind的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法 数据结构分类 数据结构类型介绍 数据结构线性非线性结构 算法合集 (一)

     数据结构分为:                            a.线性结构                            b.非线性结构  a.线性结构:                       数据与结构存在一对一的线性关系; a . 线性结构 存储 分为:                                   顺序存储

    2024年02月10日
    浏览(49)
  • 【算法与数据结构】--算法应用--算法和数据结构的案例研究

    一、项目管理中的算法应用 在项目管理中,算法和数据结构的应用涉及项目进度、资源分配、风险管理等方面。以下是一些案例研究,展示了算法在项目管理中的实际应用: 项目进度管理 : 甘特图算法 :甘特图是一种项目进度管理工具,它使用甘特图算法来展示项目任务

    2024年02月08日
    浏览(55)
  • 数据结构与算法设计分析—— 数据结构及常用算法

    1、顺序表与链表 线性表是 线性结构 ,是包含n个数据元素的有限序列,通过顺序存储的线性表称为 顺序表 ,它是将线性表中所有元素按照其逻辑顺序,依次存储到指定存储位置开始的一块连续的存储空间里;而通过链式存储的 链表 中,每个结点不仅包含该元素的信息,还

    2024年02月07日
    浏览(59)
  • 数据结构和算法——数据结构

    目录 线性结构  队列结构的队列 链表结构的队列 链表的面试题 单向链表应用场景 约瑟夫环问题 栈结构 中缀表达式 前缀表达式 后缀表达式 非线性结构 图 递归解决迷宫问题 递归解决八皇后问题 顺序存储方式,顺序表 常见的顺序存储结构有:数组、队列、链表、栈 链式存

    2024年02月07日
    浏览(53)
  • 数据结构与算法 --- 数据结构绪论

    早期人们都把计算机理解为数值计算工具,就是感觉计算机当然是用来计算的,所以计算机解决问题,应该是先从具体问题中抽象出一个适当的数据模型,设计出一个解此数据模型的算法,然后再编写程序,得到一个实际的软件。 可现实中,我们更多的不是解决数值计算的问

    2024年02月14日
    浏览(52)
  • 数据结构与算法——数据结构有哪些,常用数据结构详解

    数据结构是学习数据存储方式的一门学科,那么,数据存储方式有哪几种呢?下面将对数据结构的学习内容做一个简要的总结。 数据结构大致包含以下几种存储结构: 线性表,还可细分为顺序表、链表、栈和队列; 树结构,包括普通树,二叉树,线索二叉树等; 图存储结构

    2024年02月15日
    浏览(60)
  • 数据结构与算法——什么是数据结构

    当你决定看这篇文章,就意味着系统学习数据结构的开始。下面我们先来讲什么是数据结构。 数据结构,直白地理解,就是研究数据的存储方式。 我们知道,数据存储只有一个目的,即为了方便后期对数据的再利用,就如同我们使用数组存储  {1,2,3,4,5}  是为了后期取得它们

    2024年02月15日
    浏览(53)
  • 【数据结构与算法】不就是数据结构

      嗨喽小伙伴们你们好呀,好久不见了,我已经好久没更新博文了!之前因为实习没有时间去写博文,现在已经回归校园了。我看了本学期的课程中有数据结构这门课程(这么课程特别重要),因为之前学过一点,所以就想着深入学习一下子。毕竟这门课程对于 考研 和 就业

    2024年02月07日
    浏览(48)
  • 【数据结构与算法】1.数据结构绪论

    📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢迎各位大佬指点,相互学习进步! 数据结构是计算机中存储、组织数据的方式。 数据结构是一种具有一定逻辑关系,

    2024年01月23日
    浏览(52)
  • 【数据结构与算法】一、数据结构的基本概念

    抽象数据类型(ADT)定义举例:Circle的定义 如何处理杂乱无章且多样化的数据: 数据元素 :数据中的个体被称为数据元素。 数据对象 :性质相同的数据元素组成的集合。 数据结构 :数据元素加上数据元素之间的关系,就形成了数据结构。 逻辑结构 :数据结构的逻辑模型。

    2023年04月17日
    浏览(96)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包