valgrind的用法

 

valgrind --tool=memcheck --leak-check=full ./main
valgrind --tool=memcheck --leak-resolution=high ./main
valgrind --tool=memcheck --show-reachable=yes ./main
valgrind --tool=memcheck --show-reachable=yes --log-file=proglog ./main
valgrind --tool=callgrind ./main
valgrind --tool=cachegrind ./main
valgrind --tool=helgrind ./main
valgrind --tool=massif ./main


Details of Memcheck’s checking machinery
Read this section if you want to know, in detail, exactly what and how Memcheck is checking.
 Valid-value (V) bits
It is simplest to think of Memcheck implementing a synthetic CPU which is identical to a real CPU, except for one
crucial detail. Every bit (literally) of data processed, stored and handled by the real CPU has, in the synthetic CPU, an
associated "valid-value" bit, which says whether or not the accompanying bit has a legitimate value. In the discussions
which follow, this bit is referred to as the V (valid-value) bit.
Each byte in the system therefore has a 8 V bits which follow it wherever it goes. For example, when the CPU loads a
word-size item (4 bytes) from memory, it also loads the corresponding 32 V bits from a bitmap which stores the V bits
for the process’ entire address space. If the CPU should later write the whole or some part of that value to memory at
a different address, the relevant V bits will be stored back in the V-bit bitmap.
In short, each bit in the system has (conceptually) an associated V bit, which follows it around everywhere, even
inside the CPU. Yes, all the CPU’s registers (integer, floating point, vector and condition registers) have their own V
bit vectors. For this to work, Memcheck uses a great deal of compression to represent the V bits compactly.
Copying values around does not cause Memcheck to check for, or report on, errors. However, when a value is
used in a way which might conceivably affect your program’s externally-visible behaviour, the associated V bits are
immediately checked. If any of these indicate that the value is undefined (even partially), an error is reported.
Here’s an (admittedly nonsensical) example:
int i, j;
int a[10], b[10];
for ( i = 0; i < 10; i++ ) {
j = a[i];
b[i] = j;
}
Memcheck emits no complaints about this, since it merely copies uninitialised values from a[] into b[], and doesn’t
use them in a way which could affect the behaviour of the program. However, if the loop is changed to:
for ( i = 0; i < 10; i++ ) {
j += a[i];
}
if ( j == 77 )
printf("hello there\n");
then Memcheck will complain, at the if, that the condition depends on uninitialised values. Note that it doesn’t
complain at the j += a[i];, since at that point the undefinedness is not "observable". It’s only when a decision
has to be made as to whether or not to do the printf -- an observable action of your program -- that Memcheck
complains.
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. To do otherwise would give long chains of error messages. In other words, once Memcheck reports an
undefined value error, it tries to avoid reporting further errors derived from that same undefined value.
This sounds overcomplicated. Why not just check all reads from memory, and complain if an undefined value is
loaded into a CPU register? Well, that doesn’t work well, because perfectly legitimate C programs routinely copy
uninitialised values around in memory, and we don’t want endless complaints about that. Here’s the canonical
example. Consider a struct like this:
struct S { int x; char c; };
struct S s1, s2;
s1.x = 42;
s1.c = ’z’;
s2 = s1;
The question to ask is: how large is struct S, in bytes? An int is 4 bytes and a char one byte, so perhaps a
struct S occupies 5 bytes? Wrong. All non-toy compilers we know of will round the size of struct S up to
a whole number of words, in this case 8 bytes. Not doing this forces compilers to generate truly appalling code for
accessing arrays of struct S’s on some architectures.
So s1 occupies 8 bytes, yet only 5 of them will be initialised. For the assignment s2 = s1, GCC generates code
to copy all 8 bytes wholesale into s2 without regard for their meaning. If Memcheck simply checked values as they
came out of memory, it would yelp every time a structure assignment like this happened. So the more complicated
behaviour described above is necessary. This allows GCC to copy s1 into s2 any way it likes, and a warning will
only be emitted if the uninitialised values are later used.
Valid-address (A) bits
Notice that the previous subsection describes how the validity of values is established and maintained without having
to say whether the program does or does not have the right to access any particular memory location. We now consider
the latter question.
As described above, every bit in memory or in the CPU has an associated valid-value (V) bit. In addition, 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. It does not give any indication of the validity of the data at that location
-- that’s the job of the V bits -- only whether or not the location may be accessed.
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.
So how do the A bits get set/cleared? Like this:
•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.

命令整理:

(1)检查内存(如内存初始化,内存溢出等错误)

valgrind --quiet --tool=memcheck ./myproc 10172 0474 htparam  

(2)内存检查选项 -- quiet 表示安静的执行,只打印错误信息

valgrind --quiet --tool=memcheck --leak-check=yes ./myproc 10172 0474 htparam  

(3)显示详细信息 --verbose

   显示详细信息。在各个方面显示你的程序的额外信息,例如:共享对象 

   加载,使用的重置,执行引擎和工具的进程,异常行为的警告信息。重 

   复这个标记可以增加详细的级别。

valgrind --quiet --verbose  --tool=memcheck --leak-check=yes ./ myproc 10172 0474 htparam

(4)输出到日志中 --log-file=<filename> 

   定Valgrind把它所有的信息输出到指定的文件中。实际上,被创建文件的 

   文件名是由filename,'.' 和进程号连接起来的(即<filename>.<pid>

   从而每个进程创建不同的文件。 

   

   valgrind --quiet --log-file=valgrind_myproc.log --verbose  --tool=memcheck --leak-check=yes ./ myproc 10172 0474 htparam

(5)输出日志到指定的网络ip和端口

valgrind --quiet --log-socket=<ip-192.168.20.210:port-8000> --verbose  --tool=memcheck --leak-check=yes ./ myproc 10172 0474 htparam   

----- 错误相关选项 -----

(6)xml格式输出日志: --xml=<yes|no> [default: no] 

 valgrind --quiet --verbose --xml=yes --tool=memcheck --leak-check=yes ./test

(7)改变层次 --num-callers=<number> [default: 12] 

valgrind --quiet --verbose --xml=yes --num-callers=100 --tool=memcheck --leak-check=yes ./test

(8)关闭默认错误的打印上限

   当这个选项打开时,在总量达到10,000,000,或者1,000个不同的错误, 

   Valgrind停止报告错误。这是为了避免错误跟踪机制在错误很多的程序 

   下变成一个巨大的性能负担。 

   

--error-limit=<yes|no> [default: yes] 

valgrind --quiet --verbose --xml=yes --num-callers=100 --error-limit=no --tool=memcheck --leak-check=yes ./test

-----malloc 选项-----

(9)内存对齐选项 --alignment=<number> [default: 8] 

  默认Valgrindmalloc(),realloc(), 等等,是8字节对齐地址的。这 

  是大部分处理器的标准。然而,一些程序可能假定malloc()等总是返回 

  16字节或更多对齐的内存。提供的数值必须在84096区间之内,并且 

  必须是2的幂数。

  

  valgrind --quiet --verbose --alignment=16 --xml=yes --num-callers=100 --error-limit=no --tool=memcheck --leak-check=yes ./test

---=========== 以下的比较重要 ---===========

-----内存检查选项----

(10) --leak-check=<no|summary|yes|full> [default: summary] 

当这个选项打开时,当客户程序结束时查找内存泄漏。内存泄漏意味着 

  有用malloc分配内存块,但是没有用free释放,而且没有指针指向这块 

  内存。这样的内存块永远不能被程序释放,因为没有指针指向它们。如 

  果设置为summaryValgrind会报告有多少内存泄漏发生了。如果设置为 

  fullyesValgrind给出每一个独立的泄漏的详细信息。 

  

(11) --show-reachable=<yes|no> [default: no] 

当这个选项关闭时,内存泄漏检测器只显示没有指针指向的内存块,或 

者只能找到指向块中间的指针。当这个选项打开时,内存泄漏检测器还 

报告有指针指向的内存块。这些块是最有可能出现内存泄漏的地方。你 

的程序可能,至少在原则上,应该在退出前释放这些内存块。这些有指 

针指向的内存块和没有指针指向的内存块,或者只有内部指针指向的块, 

都可能产生内存泄漏,因为实际上没有一个指向块起始的指针可以拿来释 

放,即使你想去释放它。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值