mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
A few minor manual updates.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4419
This commit is contained in:
parent
7ec1597605
commit
b329702e3b
@ -427,8 +427,8 @@ precisely reflect any changes in memory permissions caused by the system call.
|
||||
|
||||
<para>Here's an example of two system calls with invalid parameters:</para>
|
||||
<programlisting><![CDATA[
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
int main( void )
|
||||
{
|
||||
char* arr = malloc(10);
|
||||
@ -510,8 +510,8 @@ don't make any assumptions about the language implementation.</para>
|
||||
|
||||
|
||||
|
||||
<sect1 id="mc-manual.suppfiles" xreflabel="Writing suppressions files">
|
||||
<title>Writing suppressions files</title>
|
||||
<sect1 id="mc-manual.suppfiles" xreflabel="Writing suppression files">
|
||||
<title>Writing suppression files</title>
|
||||
|
||||
<para>The basic suppression format is described in
|
||||
<xref linkend="manual-core.suppress"/>.</para>
|
||||
@ -564,7 +564,7 @@ Memcheck,Addrcheck:suppression_type]]></programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><computeroutput>Overlap</computeroutput>, meaning a
|
||||
<para>Or: <computeroutput>Overlap</computeroutput>, meaning a
|
||||
<computeroutput>src</computeroutput> /
|
||||
<computeroutput>dst</computeroutput> overlap in
|
||||
<computeroutput>memcpy() or a similar
|
||||
@ -572,9 +572,8 @@ Memcheck,Addrcheck:suppression_type]]></programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Last but not least, you can suppress leak reports with
|
||||
<computeroutput>Leak</computeroutput>. Leak suppression was
|
||||
added in valgrind-1.9.3, I believe.</para>
|
||||
<para>Or: <computeroutput>Leak</computeroutput>, meaning
|
||||
a memory leak.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
@ -612,7 +611,7 @@ what and how Memcheck is checking.</para>
|
||||
<title>Valid-value (V) bits</title>
|
||||
|
||||
<para>It is simplest to think of Memcheck implementing a
|
||||
synthetic Intel x86 CPU which is identical to a real CPU, except
|
||||
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
|
||||
@ -631,8 +630,8 @@ bitmap.</para>
|
||||
|
||||
<para>In short, each bit in the system has an associated V bit,
|
||||
which follows it around everywhere, even inside the CPU. Yes,
|
||||
the CPU's (integer and <computeroutput>%eflags</computeroutput>)
|
||||
registers have their own V bit vectors.</para>
|
||||
all the CPU's registers (integer, floating point, and condition
|
||||
registers) have their own V bit vectors.</para>
|
||||
|
||||
<para>Copying values around does not cause Memcheck to check for,
|
||||
or report on, errors. However, when a value is used in a way
|
||||
@ -673,14 +672,14 @@ the <computeroutput>printf</computeroutput> -- an observable
|
||||
action of your program -- that Memcheck complains.</para>
|
||||
|
||||
<para>Most low level operations, such as adds, cause Memcheck to
|
||||
use the <literal>V bits</literal> for the operands to calculate
|
||||
the V bits for the result. Even if the result is partially or
|
||||
wholly undefined, it does not complain.</para>
|
||||
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.</para>
|
||||
|
||||
<para>Checks on definedness only occur in two places: when a
|
||||
value is used to generate a memory address, and where control
|
||||
flow decision needs to be made. Also, when a system call is
|
||||
detected, valgrind checks definedness of parameters as
|
||||
<para>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, Valgrind checks definedness of parameters as
|
||||
required.</para>
|
||||
|
||||
<para>If a check should detect undefinedness, an error message is
|
||||
@ -729,20 +728,6 @@ necessary. This allows <literal>gcc</literal> to copy
|
||||
warning will only be emitted if the uninitialised values are
|
||||
later used.</para>
|
||||
|
||||
<para>One final twist to this story. The above scheme allows
|
||||
garbage to pass through the CPU's integer registers without
|
||||
complaint. It does this by giving the integer registers
|
||||
<literal>V</literal> tags, passing these around in the expected
|
||||
way. This complicated and computationally expensive to do, but
|
||||
is necessary. Memcheck is more simplistic about floating-point
|
||||
loads and stores. In particular, <literal>V</literal> bits for
|
||||
data read as a result of floating-point loads are checked at the
|
||||
load instruction. So if your program uses the floating-point
|
||||
registers to do memory-to-memory copies, you will get complaints
|
||||
about uninitialised values. Fortunately, I have not yet
|
||||
encountered a program which (ab)uses the floating-point registers
|
||||
in this way.</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
|
||||
@ -756,23 +741,22 @@ access any particular memory location. We now consider the
|
||||
latter issue.</para>
|
||||
|
||||
<para>As described above, every bit in memory or in the CPU has
|
||||
an associated valid-value (<literal>V</literal>) bit. In
|
||||
an associated valid-value (V) bit. In
|
||||
addition, all bytes in memory, but not in the CPU, have an
|
||||
associated valid-address (<literal>A</literal>) bit. This
|
||||
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 or the data at that location -- that's the job of the
|
||||
<literal>V</literal> bits -- only whether or not the location may
|
||||
V bits -- only whether or not the location may
|
||||
be accessed.</para>
|
||||
|
||||
<para>Every time your program reads or writes memory, Memcheck
|
||||
checks the <literal>A</literal> bits associated with the address.
|
||||
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.</para>
|
||||
|
||||
<para>So how do the <literal>A</literal> bits get set/cleared?
|
||||
Like this:</para>
|
||||
<para>So how do the A bits get set/cleared? Like this:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@ -788,15 +772,14 @@ Like this:</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>When the stack pointer register
|
||||
(<literal>%esp</literal>) moves up or down,
|
||||
(<literal>SP</literal>) moves up or down,
|
||||
<literal>A</literal> bits are set. The rule is that the area
|
||||
from <literal>%esp</literal> up to the base of the stack is
|
||||
marked as accessible, and below <literal>%esp</literal> is
|
||||
from <literal>SP</literal> up to the base of the stack is
|
||||
marked as accessible, and below <literal>SP</literal> 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 <literal>%esp</literal> like
|
||||
including GNU/Linux.) Tracking <literal>SP</literal> 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
|
||||
@ -830,66 +813,49 @@ follows:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Each byte in memory has 8 associated
|
||||
<literal>V</literal> (valid-value) bits, saying whether or
|
||||
V (valid-value) bits, saying whether or
|
||||
not the byte has a defined value, and a single
|
||||
<literal>A</literal> (valid-address) bit, saying whether or
|
||||
A (valid-address) bit, saying whether or
|
||||
not the program currently has the right to read/write that
|
||||
address.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When memory is read or written, the relevant
|
||||
<literal>A</literal> bits are consulted. If they indicate an
|
||||
A bits are consulted. If they indicate an
|
||||
invalid address, Valgrind emits an Invalid read or Invalid
|
||||
write error.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When memory is read into the CPU's integer registers,
|
||||
the relevant <literal>V</literal> bits are fetched from
|
||||
<para>When memory is read into the CPU's registers,
|
||||
the relevant V bits are fetched from
|
||||
memory and stored in the simulated CPU. They are not
|
||||
consulted.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When an integer register is written out to memory, the
|
||||
<literal>V</literal> bits for that register are written back
|
||||
<para>When a register is written out to memory, the
|
||||
V bits for that register are written back
|
||||
to memory too.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When memory is read into the CPU's floating point
|
||||
registers, the relevant <literal>V</literal> bits are read
|
||||
from memory and they are immediately checked. If any are
|
||||
invalid, an uninitialised value error is emitted. This
|
||||
precludes using the floating-point registers to copy
|
||||
possibly-uninitialised memory, but simplifies Valgrind in
|
||||
that it does not have to track the validity status of the
|
||||
floating-point registers.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>As a result, when a floating-point register is written
|
||||
to memory, the associated V bits are set to indicate a valid
|
||||
value.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When values in integer CPU registers are used to
|
||||
<para>When values in CPU registers are used to
|
||||
generate a memory address, or to determine the outcome of a
|
||||
conditional branch, the <literal>V</literal> bits for those
|
||||
conditional branch, the V bits for those
|
||||
values are checked, and an error emitted if any of them are
|
||||
undefined.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When values in integer CPU registers are used for any
|
||||
<para>When values in CPU registers are used for any
|
||||
other purpose, Valgrind computes the V bits for the result,
|
||||
but does not check them.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>One the <literal>V</literal> bits for a value in the
|
||||
<para>One the V bits for a value in the
|
||||
CPU have been checked, they are then set to indicate
|
||||
validity. This avoids long chains of errors.</para>
|
||||
</listitem>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user