本文转自:http://qa.alibaba.com/?p=59

一、valgrind介绍

Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件(plug-in),利用内核提供的服务完成各种特定的内存调试任务。

Valgrind的体系结构如下图所示:

Valgrind包括以下工具:
Memcheck

Memcheck 工具主要检查下面的程序错误:
使用未初始化的内存(Use of uninitialised memory)
使用已经释放了的内存(Reading/writing memory after it has been free'd)
使用超过malloc分配的内存空间(Reading/writing off the end of malloc'd blocks)
对堆栈的非法访问(Reading/writing inappropriate areas on the stack)
申请的空间是否有释放(Memory leaks – where pointers to malloc'd blocks are lost forever)
malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)
Callgrind

Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache 模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式
Cachegrind

它模拟CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助
Helgrind

它主要用来检查多线程程序中出现的竞争问题。Helgrind 寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为" Eraser" 的竞争检测算法,并做了进一步改进,减少了报告错误的次数
Massif

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率
二、valgrind使用

1. 使用选项-g编译程序,-g参数可以包含进调试信息,这样memcheck的error message中就可以包含进行号。也可以使用-O0。使用-O1性能相比-O0有较大提升,但是行号可能不准确。不推荐使用-O2。
2. 调用valgrind:valgrind [valgrind-options] your-prog [your-prog-options]常用公共选项:参 数 说 明 默 认 设 置
–tool=<name> 使用名为<name>Valgrind工具 [memcheck]
–version 显示版本信息
-q –quiet 只打印错误信息
-v –verbose 显示详细信息
–trace-children=no|yes 跟踪子进程 [no]
–track-fds=no|yes 跟踪文件描述符 [no]
–time-stamp=no|yes 添加时间戳到日志文件 [no]
–log-fd=<number> 日志信息写入到文件描述符 [2=stderr]
–log-file=<file> 日志信息写入到文件
–log-file-exactly=<file> 日志信息写入到外部文件 <file>

具体选项信息可以后面的附录
3. 产生valgrind日志

针对valgrind日志可以进行针对性的分析
三、Valgrind(memcheck)报错分类解析

参考:valgrind manual
Valgrind(memcheck)包含这7类错误(高亮部分),黑体为一般的错误提示:
1.illegal read/illegal write errors
Invalid read of size 4
2.use of uninitialised values
Conditional jump or move depends on uninitialised value(s)
3.use of uninitialised or unaddressable values in system calls
Syscall param write(buf) points to uninitialised byte(s)
4.illegal frees
Invalid free()
5.when a heap block is freed with an inappropriate deallocation function
Mismatched free() / delete / delete []
6.overlapping source and destination blocks
Source and destination overlap in memcpy(0xbffff294, 0xbffff280, 21)
7.memory leak detection

7.1 Still reachable (cover case 1,2)
A start-pointer or chain of start-pointers to the block is found.memcheck won’t report unless –show-reachable=yes is specified
内存指针还在还有机会使用或者释放,指针指向的动态内存还没有被释放就退出了
7.2 Definitely lost (cover case 3)
no pointer to the block can be found memcheck won't report such blocks individually unless –show-reachable=yes is specified
确定的内存泄露,已经不能够访问这块内存
7.3 Indirectly lost (cover case 4,9)
the block is lost, not because there are no pointers to it, but rather because all the blocks that point to it are themselves lost
指向该内存的指针都位于内存泄露处
7.4 Possibly lost (cover case 5,6,7,8)
a chain of one or more pointers to the block has been found, but at least one of the pointers is an interior-pointer
可能的内存泄露,仍然存在某个指针能够访问某快内存,但该指针指向的已经不是该内存首位置
There are two ways a block can be reached. The first is with a "start-pointer", i.e. a pointer to the start of the block. The second is with an "interior-pointer", i.e. a pointer to the middle of the block. There are three ways we know of that an interior-pointer can occur:
The pointer might have originally been a start-pointer and have been moved along deliberately (or not deliberately) by the program.
It might be a random junk value in memory, entirely unrelated, just a coincidence.
It might be a pointer to an array of C++ objects (which possess destructors) allocated with new[]. In this case, some compilers store a "magic cookie" containing the array length at the start of the allocated block, and return a pointer to just past that magic cookie, i.e. an interior-pointer.
四、Valgrind原理简介(这部分大家根据兴趣了解)

参考:
Ibm developerworks
valgrind manual

Memcheck检测内存问题的原理如下图所示:

Memcheck 能够检测出内存问题,关键在于其建立了两个全局表。
Valid-Value 表:

对于进程的整个地址空间中的每一个字节(byte),都有与之对应的8 个bits;对于CPU 的每个寄存器,也有一个与之对应的bit 向量。这些bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值。
2. Valid-Address 表
对于进程整个地址空间中的每一个字节(byte),还有与之对应的1 个bit,负责记录该地址是否能够被读写。
检测原理:
当要读写内存中某个字节时,首先检查这个字节对应的A bit。如果该A bit显示该位置是无效位置,memcheck 则报告读写错误。
内核(core)类似于一个虚拟的CPU 环境,这样当内存中的某个字节被加载到真实的CPU 中时,该字节对应的V bit 也被加载到虚拟的CPU 环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则memcheck 会检查对应的V bits,如果该值尚未初始化,则会报告使用未初始化内存错误。

具体实现:
a synthetic CPU which is identical to a real CPU
synthetic CPU ——"valid-value" bit says whether or not the accompanying bit has a legitimate value
Valid-value (V) bits
copying values around does not cause Memcheck to check for, or report on, errors
when a value which might conceivably affect your program's externally-visible behaviour,the associated V bits are checked.if any of these indicate that the value is undefined, an error is reported.
Most low level operations, such as adds, cause Memcheck to use the V bits for the operands to calculate the V bits for the result. Even if the result is partially or wholly undefined, it does not complain.
Checks on definedness only occur in three places: when a value is used to generate a memory address, when control flow decision needs to be made, and when a system call is detected, Memcheck checks definedness of parameters as required.
If a check should detect undefinedness, an error message is issued. The resulting value is subsequently regarded as well-defined.once Memcheck reports an undefined value error, it tries to avoid reporting further errors derived from that same undefined value.

Valid-address (A) bits
all bytes in memory, but not in the CPU, have an associated valid-address (A) bit.This indicates whether or not the program can legitimately read or write that location
Every time your program reads or writes memory, Memcheck checks the A bits associated with the address. If any of them indicate an invalid address, an error is emitted. Note that the reads and writes themselves do not change the A bits, only consult them.
When the program starts, all the global data areas are marked as accessible.
When the program does malloc/new, the A bits for exactly the area allocated, and not a byte more, are marked as accessible. Upon freeing the area the A bits are changed to indicate inaccessibility.
When the stack pointer register (SP) moves up or down, A bits are set. The rule is that the area from SP up to the base of the stack is marked as accessible, and below SP is inaccessible. (If that sounds illogical, bear in mind that the stack grows down, not up, on almost all Unix systems, including GNU/Linux.) Tracking SP like this has the useful side-effect that the section of stack used by a function for local variables etc is automatically marked accessible on function entry and inaccessible on exit.
When doing system calls, A bits are changed appropriately. For example, mmap magically makes files appear in the process' address space, so the A bits must be updated if mmap succeeds.
Optionally, your program can tell Memcheck about such changes explicitly, using the client request mechanism described above.

五、附录
5.1 valgrind选项

用法: valgrind [options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具

常用选项
–tool=[default: memcheck]
–tool=memcheck:要求用 memcheck这个工具对程序进行分析
–log-file=filename
将输出的信息写入到filename.PID 的文件里,PID是运行程序的进行ID
–log-file-exactly=filename
指定就输出到 filename文件
–log-socket=IP:PORT
把输出信息发送到网络中指定的IP:PORT 去
–leak-ckeck=yes
要求对leak给出详细信息
–leak-check=full
完全检查内存泄漏
–xml=[default: no]
将信息以xml格式输出,只有 memcheck可用
–gen-suppressions=[default: no]
如果为yes, valgrind会在每发现一个错误便停下让用户做选择是继续还是退出
–leak-check=[default: summary]
Leak是指,存在一块没有被引用的内存空间,或没有被释放的内存空间,如 summary,只反馈一些总结信息,告诉你有多少个malloc ,多少个free 等;如果是full 将输出所有的leaks,也就是定位到某一个malloc/free 。
–show-reachable=[default: no]
如果为 no,只输出没有引用的内存leaks,或指向 malloc返回的内存块中部某处的leaks
–undef-value-errors=[default: yes]
如果为 yes,memcheck将对无定义值错进行检查

可以把一些默认选项编辑在 ~/.valgrindrc文件里

valgrind详细说明相关推荐

  1. 【调试】Linux下超强内存检测工具Valgrind

    [调试]Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么? Valgrind的使用 Valgrind详细教程 1. Valgrind是什么? Valgrind是一套Lin ...

  2. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历

    Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...

  3. 在Ubuntu 14.04 64bit上安装Valgrind并检查内存泄露

    valgrind官网:http://valgrind.org/ 1.安装方法 第一种方式:下载目前最新的源码,编译安装,在服务器上推荐这种方式 wget http://valgrind.org/dow ...

  4. linux valgrind 安装和使用

    linux valgrind 安装和使用 安装过程没这么复杂. 直接命令行: sudo apt-get install valgrind Valgrind 是个开源的工具,功能很多.例如检查内存泄漏工 ...

  5. linux valgrind Memcheck--内存检查工具

    linux valgrind Memcheck–内存检查工具 使用方法: 注意,这里要用debug版本,如果是release的运行文件,则用debug编译出来的可执行文件替换 输出到终端: valgr ...

  6. 使用valgrind分析C程序调用线路图

    Valgrind可以检测内存泄漏和内存违例,但是用Valgrind生成的日志信息结合kcachegrind就可以查看C程序的执行线路图,调用时间,是做性能优化和查看代码的非常好的工具. 1.下载安装 ...

  7. 内存问题分析的利器——valgrind的memcheck

    在<内存.性能问题分析的利器--valgrind>一文中我们简单介绍了下valgrind工具集,本文将使用memcheck工具分析各种内存问题.(转载请指明出于breaksoftware的 ...

  8. Ubuntu下内存泄露检测工具Valgrind的使用

    在VS中可以用VLD检测是否有内存泄露,可以参考http://blog.csdn.net/fengbingchun/article/details/44195959,下面介绍下Ubuntu中内存泄露检 ...

  9. 【linux】Valgrind工具集详解(八):Memcheck命令行参数详解

    [linux]Valgrind工具集详解(五):命令行详解中不够全,在此专门针对Memcheck工具中的命令行参数做一次详细的解释. Memcheck命令行选项 –leak-check=<no| ...

最新文章

  1. 如何提高网站的访问速度
  2. Dubbo负载均衡机制
  3. IntelliJ IDEA 添加项目后编译显示包不存在的解决方案
  4. CVPR 2021 | 跨模态点云补全新框架ViPC:用单一视图推断完整信息
  5. flask-01-http通信的回顾
  6. RocketMQ事务消息及消息索引设计原理
  7. Centos在线安装nginx
  8. 在防御方面应如何选择服务器?
  9. 纽约出租车计费问题:一个简单的线性模型
  10. 中国计算机学会(CCF)推荐国际学术会议和期刊目录(2019年版,官网转载)
  11. java xcap_java实现发布订阅
  12. 音频噪声抑制_音频编辑入门指南:基本噪声消除
  13. 计算机电池电源转换,整套解决方案:笔记本电脑的外部电源和电池如何实现无缝切换?...
  14. 期权定价_强化学习的期权定价
  15. JavaScript复习二
  16. 武音硕士研究生《计算机音乐作曲》培训,武汉音乐学院2013年硕士研究生招生计算机音乐作曲科目考试大纲及参考书目...
  17. Linux服务器期末复习总结
  18. php奖状生成器源码,PHP生成奖状
  19. 知乎点赞过万留学生自述:我们为什么需要代写???
  20. 解决xcode doesn‘t support iphone’s ios 14.6 (18f72)

热门文章

  1. 手机上的python怎么运行,python在手机上怎么操作
  2. 高等数学笔记:导函数与原函数关于函数性质的研究
  3. 细节决定孩子成长的成败
  4. 有关漫入和漫出的概念
  5. 乐高式微服务化改造(上)
  6. NBA篮球图文直播室之数据排行榜设计
  7. Pytorch的model.train() model.eval() torch.no_grad() 为什么测试的时候不调用loss.backward()计算梯度还要关闭梯度
  8. SpringCloud学习记录 | 第十五篇:SpringCloud Alibaba Nacos集群版
  9. 准备VB或C#开发环境(Visual Studio)
  10. jQuery.on() 函数详解