📄 mc-manual.html
字号:
<p>Sources of uninitialised data tend to be:</p><div class="itemizedlist"><ul type="disc"><li><p>Local variables in procedures which have not been initialised, as in the example above.</p></li><li><p>The contents of malloc'd blocks, before you write something there. In C++, the new operator is a wrapper round malloc, so if you create an object with new, its fields will be uninitialised until you (or the constructor) fill them in, which is only Right and Proper.</p></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="mc-manual.badfrees"></a>3.3.3.營llegal frees</h3></div></div></div><p>For example:</p><pre class="programlisting">Invalid free() at 0x4004FFDF: free (vg_clientmalloc.c:577) by 0x80484C7: main (tests/doublefree.c:10) Address 0x3807F7B4 is 0 bytes inside a block of size 177 free'd at 0x4004FFDF: free (vg_clientmalloc.c:577) by 0x80484C7: main (tests/doublefree.c:10)</pre><p>Memcheck keeps track of the blocks allocated by your program withmalloc/new, so it can know exactly whether or not the argument tofree/delete is legitimate or not. Here, this test program has freed thesame block twice. As with the illegal read/write errors, Memcheckattempts to make sense of the address free'd. If, as here, the addressis one which has previously been freed, you wil be told that -- makingduplicate frees of the same block easy to spot.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="mc-manual.rudefn"></a>3.3.4.燱hen a block is freed with an inappropriate deallocationfunction</h3></div></div></div><p>In the following example, a block allocated with<code class="function">new[]</code> has wrongly been deallocated with<code class="function">free</code>:</p><pre class="programlisting">Mismatched free() / delete / delete [] at 0x40043249: free (vg_clientfuncs.c:171) by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149) by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60) by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44) Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd at 0x4004318C: __builtin_vec_new (vg_clientfuncs.c:152) by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314) by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416) by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272)</pre><p>In <code class="literal">C++</code> it's important to deallocate memory in away compatible with how it was allocated. The deal is:</p><div class="itemizedlist"><ul type="disc"><li><p>If allocated with <code class="function">malloc</code>, <code class="function">calloc</code>, <code class="function">realloc</code>, <code class="function">valloc</code> or <code class="function">memalign</code>, you must deallocate with <code class="function">free</code>.</p></li><li><p>If allocated with <code class="function">new[]</code>, you must deallocate with <code class="function">delete[]</code>.</p></li><li><p>If allocated with <code class="function">new</code>, you must deallocate with <code class="function">delete</code>.</p></li></ul></div><p>The worst thing is that on Linux apparently it doesn't matter ifyou do muddle these up, and it all seems to work ok, but the sameprogram may then crash on a different platform, Solaris for example. Soit's best to fix it properly. According to the KDE folks "it's amazinghow many C++ programmers don't know this".</p><p>Pascal Massimino adds the following clarification:<code class="function">delete[]</code> must be used for objects allocated by<code class="function">new[]</code> because the compiler stores the size of thearray and the pointer-to-member to the destructor of the array's contentjust before the pointer actually returned. This implies avariable-sized overhead in what's returned by <code class="function">new</code>or <code class="function">new[]</code>.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="mc-manual.badperm"></a>3.3.5.燩assing system call parameters with inadequate read/writepermissions</h3></div></div></div><p>Memcheck checks all parameters to system calls:</p><div class="itemizedlist"><ul type="disc"><li><p>It checks all the direct parameters themselves.</p></li><li><p>Also, if a system call needs to read from a buffer provided by your program, Memcheck checks that the entire buffer is addressible and has valid data, ie, it is readable.</p></li><li><p>Also, if the system call needs to write to a user-supplied buffer, Memcheck checks that the buffer is addressible.</p></li></ul></div><p></p><p>After the system call, Memcheck updates its tracked information toprecisely reflect any changes in memory permissions caused by the systemcall.</p><p>Here's an example of two system calls with invalid parameters:</p><pre class="programlisting"> #include <stdlib.h> #include <unistd.h> int main( void ) { char* arr = malloc(10); int* arr2 = malloc(sizeof(int)); write( 1 /* stdout */, arr, 10 ); exit(arr2[0]); }</pre><p>You get these complaints ...</p><pre class="programlisting"> Syscall param write(buf) points to uninitialised byte(s) at 0x25A48723: __write_nocancel (in /lib/tls/libc-2.3.3.so) by 0x259AFAD3: __libc_start_main (in /lib/tls/libc-2.3.3.so) by 0x8048348: (within /auto/homes/njn25/grind/head4/a.out) Address 0x25AB8028 is 0 bytes inside a block of size 10 alloc'd at 0x259852B0: malloc (vg_replace_malloc.c:130) by 0x80483F1: main (a.c:5) Syscall param exit(error_code) contains uninitialised byte(s) at 0x25A21B44: __GI__exit (in /lib/tls/libc-2.3.3.so) by 0x8048426: main (a.c:8)</pre><p>... because the program has (a) tried to write uninitialised junkfrom the malloc'd block to the standard output, and (b) passed anuninitialised value to <code class="function">exit</code>. Note that the firsterror refers to the memory pointed to by<code class="computeroutput">buf</code> (not<code class="computeroutput">buf</code> itself), but the second errorrefers to the argument <code class="computeroutput">error_code</code>itself.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="mc-manual.overlap"></a>3.3.6.燨verlapping source and destination blocks</h3></div></div></div><p>The following C library functions copy some data from onememory block to another (or something similar):<code class="function">memcpy()</code>,<code class="function">strcpy()</code>,<code class="function">strncpy()</code>,<code class="function">strcat()</code>,<code class="function">strncat()</code>. The blocks pointed to by their <code class="computeroutput">src</code> and<code class="computeroutput">dst</code> pointers aren't allowed to overlap.Memcheck checks for this.</p><p>For example:</p><pre class="programlisting">==27492== Source and destination overlap in memcpy(0xbffff294, 0xbffff280, 21)==27492== at 0x40026CDC: memcpy (mc_replace_strmem.c:71)==27492== by 0x804865A: main (overlap.c:40)==27492== </pre><p>You don't want the two blocks to overlap because one of them couldget partially trashed by the copying.</p><p>You might think that Memcheck is being overly pedantic reportingthis in the case where <code class="computeroutput">dst</code> is less than<code class="computeroutput">src</code>. For example, the obvious way toimplement <code class="function">memcpy()</code> is by copying from the firstbyte to the last. However, the optimisation guides of somearchitectures recommend copying from the last byte down to the first.Also, some implementations of <code class="function">memcpy()</code> zero<code class="computeroutput">dst</code> before copying, because zeroing thedestination's cache line(s) can improve performance.</p><p>The moral of the story is: if you want to write truly portablecode, don't make any assumptions about the languageimplementation.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="mc-manual.leaks"></a>3.3.7.燤emory leak detection</h3></div></div></div><p>Memcheck keeps track of all memory blocks issued in response tocalls to malloc/calloc/realloc/new. So when the program exits, it knowswhich blocks have not been freed.</p><p>If <code class="option">--leak-check</code> is set appropriately, for eachremaining block, Memcheck scans the entire address space of the process,looking for pointers to the block. Each block fits into one of thethree following categories.</p><div class="itemizedlist"><ul type="disc"><li><p>Still reachable: A pointer to the start of the block is found. This usually indicates programming sloppiness. Since the block is still pointed at, the programmer could, at least in principle, free it before program exit. Because these are very common and arguably not a problem, Memcheck won't report such blocks unless <code class="option">--show-reachable=yes</code> is specified.</p></li><li><p>Possibly lost, or "dubious": A pointer to the interior of the block is found. The pointer might originally have pointed to the start and have been moved along, or it might be entirely unrelated. Memcheck deems such a block as "dubious", because it's unclear whether or not a pointer to it still exists.</p></li><li><p>Definitely lost, or "leaked": The worst outcome is that no pointer to the block can be found. The block is classified as "leaked", because the programmer could not possibly have freed it at program exit, since no pointer to it exists. This is likely a symptom of having lost the pointer at some earlier point in the program.</p></li></ul></div><p>For each block mentioned, Memcheck will also tell you where theblock was allocated. It cannot tell you how or why the pointer to aleaked block has been lost; you have to work that out for yourself. Ingeneral, you should attempt to ensure your programs do not have anyleaked or dubious blocks at exit.</p><p>For example:</p><pre class="programlisting">8 bytes in 1 blocks are definitely lost in loss record 1 of 14 at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak-tree.c:11) by 0x........: main (leak-tree.c:39)88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14 at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak-tree.c:11) by 0x........: main (leak-tree.c:25)</pre><p>The first message describes a simple case of a single 8 byte blockthat has been definitely lost. The second case mentions both "direct"and "indirect" leaks. The distinction is that a direct leak is a blockwhich has no pointers to it. An indirect leak is a block which is onlypointed to by other leaked blocks. Both kinds of leak are bad.</p><p>The precise area of memory in which Memcheck searches for pointersis: all naturally-aligned machine-word-sized words for which all A bitsindicate addressibility and all V bits indicated that the stored valueis actually valid.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="mc-manual.suppfiles"></a>3.4.燱riting suppression files</h2></div></div></div><p>The basic suppression format is described in <a href="manual-core.html#manual-core.suppress">Suppressing errors</a>.</p><p>The suppression (2nd) line should have the form:</p><pre class="programlisting">Memcheck:suppression_type</pre><p>The Memcheck suppression types are as follows:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="varname">Value1</code>, <code class="varname">Value2</code>, <code class="varname">Value4</code>, <code class="varname">Value8</code>, <code class="varname">Value16</code>, meaning an uninitialised-value error when using a value of 1, 2, 4, 8 or 16 bytes.</p></li><li><p>Or: <code class="varname">Cond</code> (or its old name, <code class="varname">Value0</code>), meaning use of an uninitialised CPU condition code.</p></li><li><p>Or: <code class="varname">Addr1</code>, <code class="varname">Addr2</code>, <code class="varname">Addr4</code>, <code class="varname">Addr8</code>, <code class="varname">Addr16</code>, meaning an invalid address during a memory access of 1, 2, 4, 8 or 16 bytes respectively.</p></li><li><p>Or: <code class="varname">Param</code>, meaning an invalid system call parameter error.</p></li><li><p>Or: <code class="varname">Free</code>, meaning an invalid or mismatching free.</p></li><li><p>Or: <code class="varname">Overlap</code>, meaning a <code class="computeroutput">src</code> / <code class="computeroutput">dst</code> overlap in <code class="function">memcpy()</code> or a similar function.</p></li><li><p>Or: <code class="varname">Leak</code>, meaning a memory leak.</p></li></ul></div><p>The extra information line: for Param errors, is the name of theoffending system call parameter. No other error kinds have this extraline.</p><p>The first line of the calling context: for Value and Addr errors,it is either the name of the function in which the error occurred, or,failing that, the full path of the .so file or executable containing theerror location. For Free errors, is the name of the function doing thefreeing (eg, <code class="function">free</code>,<code class="function">__builtin_vec_delete</code>, etc). For Overlap errors, isthe name of the function with the overlapping arguments (eg.<code class="function">memcpy()</code>, <code class="function">strcpy()</code>,etc).</p><p>Lastly, there's the rest of the calling context.</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="mc-manual.machine"></a>3.5.燚etails of Memcheck's checking machinery</h2></div></div></div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -