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



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


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


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 manual
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.

Ibm developerworks
valgrind manual 


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这个工具对程序进行分析
将输出的信息写入到filename.PID 的文件里,PID是运行程序的进行ID
指定就输出到 filename文件
把输出信息发送到网络中指定的IP:PORT 去
–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文件里

个人分类: Linux与网络编程
想对作者说点什么? 我来说一句