一.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能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率
二.安装
1) tar -xjvfvalgrind-3.13.0.tar.bz2 (注意你下载的版本号是否和我的一样)
2) ./autogen.sh (在对应的目录下执行命令)
3) ./configure--prefix=/usr/local/valgrind
4) make
5) make install
6) makeinstall-recursive
7) valgrind的bin目录路径添加到环境变量PATH中,打开~.bashrc文件,在最后一行加入PATH=${PATH}:/usr/local/valgrind/bin
8)结束
三.使用
用法: valgrind [options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具
常用选项
1. –tool=[default: memcheck]
–tool=memcheck:要求用 memcheck这个工具对程序进行分析
2. –log-file=filename
将输出的信息写入到filename.PID 的文件里,PID是运行程序的进行ID
3. –log-file-exactly=filename
指定就输出到 filename文件
4. –log-socket=IP:PORT
把输出信息发送到网络中指定的IP:PORT 去
5. –leak-ckeck=yes
要求对leak给出详细信息
6. –leak-check=full
完全检查内存泄漏
7. –xml=[default: no]
将信息以xml格式输出,只有 memcheck可用
8. –gen-suppressions=[default: no]
如果为yes, valgrind会在每发现一个错误便停下让用户做选择是继续还是退出
9. –leak-check=[default: summary]
Leak是指,存在一块没有被引用的内存空间,或没有被释放的内存空间,如 summary,只反馈一些总结信息,告诉你有多少个malloc ,多少个free 等;如果是full 将输出所有的leaks,也就是定位到某一个malloc/free 。
10.–show-reachable=[default: no]
如果为 no,只输出没有引用的内存leaks,或指向 malloc返回的内存块中部某处的leaks
11.–undef-value-errors=[default: yes]
如果为 yes,memcheck将对无定义值错进行检查
可以把一些默认选项编辑在 ~/.valgrindrc文件里
四.报错分析解析
参考: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.
更多编程内容关注公众号:编程艺术
http://weixin.qq.com/r/70NtdX-EFSJqrTsW9xb9 (二维码自动识别)
csdn博客:
zzb2019的博客_CSDN博客-学习笔记,转换,小项目领域博主blog.csdn.netgithub:
https://github.com/zzb2019github.com