Memcheck: a memory error detector
Keep in mind that the last two points above say "typically": the Valgrind mempool client request API is intentionally
vague about the exact structure of a mempool.
There is no specific mention made of headers or superblocks.
Nevertheless, the following picture may help elucidate the intention of the terms in the API:
"pool"
(anchor address)
|
v
+--------+---+
| header | o |
+--------+-|-+
|
v
superblock
+------+---+--------------+---+------------------+
|
|rzB|
allocation
|rzB|
|
+------+---+--------------+---+------------------+
^
^
|
|
"addr"
"addr"+"size"
Note that the header and the superblock may be contiguous or discontiguous, and there may be multiple superblocks
associated with a single header; such variations are opaque to Memcheck. The API only requires that your allocation
scheme can present sensible values of "pool", "addr" and "size".
Typically,
before making client requests related to mempools,
a client program will have allocated
such a header and superblock for their mempool, and marked the superblock NOACCESS using the
VALGRIND_MAKE_MEM_NOACCESS
client request.
When dealing with mempools, the goal is to maintain a particular invariant condition: that Memcheck believes the
unallocated portions of the pool’s superblock (including redzones) are NOACCESS. To maintain this invariant, the
client program must ensure that the superblock starts out in that state; Memcheck cannot make it so, since Memcheck
never explicitly learns about the superblock of a pool, only the allocated chunks within the pool.
Once the header and superblock for a pool are established and properly marked, there are a number of client requests
programs can use to inform Memcheck about changes to the state of a mempool:
•
VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)
: This request registers the address
pool
as the
anchor address for a memory pool. It also provides a size
rzB
, specifying how large the redzones placed around
chunks allocated from the pool should be. Finally, it provides an
is_zeroed
argument that specifies whether the
pool’s chunks are zeroed (more precisely: defined) when allocated.
Upon completion of this request, no chunks are associated with the pool. The request simply tells Memcheck that
the pool exists, so that subsequent calls can refer to it as a pool.
•
VALGRIND_DESTROY_MEMPOOL(pool)
: This request tells Memcheck that a pool is being torn down. Mem-
check then removes all records of chunks associated with the pool, as well as its record of the pool’s existence. While
destroying its records of a mempool, Memcheck resets the redzones of any live chunks in the pool to NOACCESS.
70