mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Clarify name and description/manual for meta mempool
* rename macro VALGRIND_CREATE_META_MEMPOOL
to VALGRIND_CREATE_MEMPOOL_EXT
* abort execution if a pool is marked as auto_free but is not a meta pool
+ removed test leak-autofreepool-3.vgtest, which now aborts.
* reword/clarify valgrind.h explanations for meta pool
* similarly reword/clarify the manual
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16042
This commit is contained in:
parent
7ac00163a3
commit
38fab04de9
@ -7009,21 +7009,37 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
|
||||
pool, rzB, is_zeroed, 0, 0)
|
||||
|
||||
/* Create a memory pool with special flags. When the VALGRIND_MEMPOOL_AUTO_FREE
|
||||
is passed, a MEMPOOL_DELETE will auto-free all chunks (so not reported as
|
||||
leaks) for allocators that assume that destroying a pool destroys all
|
||||
objects in the pool. When VALGRIND_MEMPOOL_METAPOOL is passed, the custom
|
||||
allocator uses the pool blocks as superblocks to dole out MALLOC_LIKE blocks.
|
||||
The resulting behaviour would normally be classified as overlapping blocks,
|
||||
and cause assert-errors in valgrind.
|
||||
These 2 MEMPOOL flags can be OR-ed together into the "flags" argument.
|
||||
/* Create a memory pool with some flags specifying extended behaviour.
|
||||
When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL.
|
||||
|
||||
The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory
|
||||
associated with the pool using VALGRIND_MEMPOOL_ALLOC will be used
|
||||
by the application as superblocks to dole out MALLOC_LIKE blocks using
|
||||
VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels"
|
||||
pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC.
|
||||
The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK.
|
||||
Note that the association between the pool and the second level blocks
|
||||
is implicit : second level blocks will be located inside first level
|
||||
blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag
|
||||
for such 2 levels pools, as otherwise valgrind will detect overlapping
|
||||
memory blocks, and will abort execution (e.g. during leak search).
|
||||
|
||||
Such a meta pool can also be marked as an 'auto free' pool using the flag
|
||||
VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the
|
||||
VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE
|
||||
will automatically free the second level blocks that are contained
|
||||
inside the first level block freed with VALGRIND_MEMPOOL_FREE.
|
||||
In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls
|
||||
to VALGRIND_FREELIKE_BLOCK for all the second level blocks included
|
||||
in the first level block.
|
||||
Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag
|
||||
without the VALGRIND_MEMPOOL_METAPOOL flag.
|
||||
*/
|
||||
#define VALGRIND_MEMPOOL_AUTO_FREE 1
|
||||
#define VALGRIND_MEMPOOL_METAPOOL 2
|
||||
#define VALGRIND_CREATE_META_MEMPOOL(pool, rzB, is_zeroed, flags) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
|
||||
pool, rzB, is_zeroed, flags, 0)
|
||||
#define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags) \
|
||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \
|
||||
pool, rzB, is_zeroed, flags, 0)
|
||||
|
||||
/* Destroy a memory pool. */
|
||||
#define VALGRIND_DESTROY_MEMPOOL(pool) \
|
||||
|
||||
@ -2320,34 +2320,53 @@ inform Memcheck about changes to the state of a mempool:</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<!-- Note: the below is mostly a copy of valgrind.h. Keep in sync! -->
|
||||
<para>
|
||||
<varname>VALGRIND_CREATE_META_MEMPOOL(pool, rzB, is_zeroed, flags)</varname>:
|
||||
This does the same as <varname>VALGRIND_CREATE_MEMPOOL</varname>,
|
||||
but allows you to specify two seldom-used options for custom
|
||||
allocators (or-ed together) in the <varname>flags</varname> argument:</para>
|
||||
<varname>VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags)</varname>:
|
||||
Create a memory pool with some flags (that can
|
||||
be OR-ed together) specifying extended behaviour. When flags is
|
||||
zero, the behaviour is identical to
|
||||
<varname>VALGRIND_CREATE_MEMPOOL</varname>.</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<varname>VALGRIND_MEMPOOL_AUTO_FREE</varname>.
|
||||
This indicates that items allocated from this
|
||||
memory pool are automatically freed when
|
||||
<varname>VALGRIND_MEMPOOL_FREE</varname>
|
||||
is used on a block. This allows a custom allocator to delete
|
||||
(part of) a memory pool without explicitly deleting all allocated
|
||||
items. Without this option, such an action will report all items
|
||||
in the pool as memory leaks.
|
||||
<para> The flag <varname>VALGRIND_MEMPOOL_METAPOOL</varname>
|
||||
specifies that the pieces of memory associated with the pool
|
||||
using <varname>VALGRIND_MEMPOOL_ALLOC</varname> will be used
|
||||
by the application as superblocks to dole out MALLOC_LIKE
|
||||
blocks using <varname>VALGRIND_MALLOCLIKE_BLOCK</varname>.
|
||||
In other words, a meta pool is a "2 levels" pool : first
|
||||
level is the blocks described
|
||||
by <varname>VALGRIND_MEMPOOL_ALLOC</varname>. The second
|
||||
level blocks are described
|
||||
using <varname>VALGRIND_MALLOCLIKE_BLOCK</varname>. Note
|
||||
that the association between the pool and the second level
|
||||
blocks is implicit : second level blocks will be located
|
||||
inside first level blocks. It is necessary to use
|
||||
the <varname>VALGRIND_MEMPOOL_METAPOOL</varname> flag for
|
||||
such 2 levels pools, as otherwise valgrind will detect
|
||||
overlapping memory blocks, and will abort execution
|
||||
(e.g. during leak search).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<varname>VALGRIND_MEMPOOL_METAPOOL</varname>.
|
||||
This indicates that memory that has been
|
||||
marked as being allocated with
|
||||
<varname>VALGRIND_MALLOCLIKE_BLOCK</varname> is used
|
||||
by a custom allocator to pass out memory to an application (again
|
||||
marked with <varname>VALGRIND_MALLOCLIKE_BLOCK</varname>).
|
||||
Without this option, such overlapping memory blocks may trigger
|
||||
a fatal error message in memcheck.
|
||||
<varname>VALGRIND_MEMPOOL_AUTO_FREE</varname>. Such a meta
|
||||
pool can also be marked as an 'auto free' pool using the
|
||||
flag <varname>VALGRIND_MEMPOOL_AUTO_FREE</varname>, which
|
||||
must be OR-ed together with
|
||||
the <varname>VALGRIND_MEMPOOL_METAPOOL</varname>. For an
|
||||
'auto free' pool, <varname>VALGRIND_MEMPOOL_FREE</varname>
|
||||
will automatically free the second level blocks that are
|
||||
contained inside the first level block freed
|
||||
with <varname>VALGRIND_MEMPOOL_FREE</varname>. In other
|
||||
words, calling <varname>VALGRIND_MEMPOOL_FREE</varname> will
|
||||
cause implicit calls
|
||||
to <varname>VALGRIND_FREELIKE_BLOCK</varname> for all the
|
||||
second level blocks included in the first level block.
|
||||
Note: it is an error to use
|
||||
the <varname>VALGRIND_MEMPOOL_AUTO_FREE</varname> flag
|
||||
without the
|
||||
<varname>VALGRIND_MEMPOOL_METAPOOL</varname> flag.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
@ -711,12 +711,17 @@ void MC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed,
|
||||
{
|
||||
MC_Mempool* mp;
|
||||
|
||||
if (VG_(clo_verbosity) > 2) {
|
||||
if (VG_(clo_verbosity) > 2 || (auto_free && !metapool)) {
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"create_mempool(0x%lx, rzB=%u, zeroed=%d, autofree=%d, metapool=%d)\n",
|
||||
pool, rzB, is_zeroed, auto_free, metapool);
|
||||
"create_mempool(0x%lx, rzB=%u, zeroed=%d,"
|
||||
" autofree=%d, metapool=%d)\n",
|
||||
pool, rzB, is_zeroed,
|
||||
auto_free, metapool);
|
||||
VG_(get_and_pp_StackTrace)
|
||||
(VG_(get_running_tid)(), MEMPOOL_DEBUG_STACKTRACE_DEPTH);
|
||||
if (auto_free && !metapool)
|
||||
VG_(tool_panic)("Inappropriate use of mempool:"
|
||||
" an auto free pool must be a meta pool. Aborting\n");
|
||||
}
|
||||
|
||||
mp = VG_(HT_lookup)(MC_(mempool_list), (UWord)pool);
|
||||
|
||||
@ -153,13 +153,11 @@ EXTRA_DIST = \
|
||||
leak-pool-0.vgtest leak-pool-0.stderr.exp \
|
||||
leak-pool-1.vgtest leak-pool-1.stderr.exp \
|
||||
leak-pool-2.vgtest leak-pool-2.stderr.exp \
|
||||
leak-pool-3.vgtest leak-pool-3.stderr.exp \
|
||||
leak-pool-4.vgtest leak-pool-4.stderr.exp \
|
||||
leak-pool-5.vgtest leak-pool-5.stderr.exp \
|
||||
leak-autofreepool-0.vgtest leak-autofreepool-0.stderr.exp \
|
||||
leak-autofreepool-1.vgtest leak-autofreepool-1.stderr.exp \
|
||||
leak-autofreepool-2.vgtest leak-autofreepool-2.stderr.exp \
|
||||
leak-autofreepool-3.vgtest leak-autofreepool-3.stderr.exp \
|
||||
leak-autofreepool-4.vgtest leak-autofreepool-4.stderr.exp \
|
||||
leak-autofreepool-5.vgtest leak-autofreepool-5.stderr.exp \
|
||||
leak-autofreepool-6.vgtest leak-autofreepool-6.stderr.exp \
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
HEAP SUMMARY:
|
||||
in use at exit: ... bytes in ... blocks
|
||||
total heap usage: ... allocs, ... frees, ... bytes allocated
|
||||
|
||||
All heap blocks were freed -- no leaks are possible
|
||||
|
||||
For counts of detected and suppressed errors, rerun with: -v
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
@ -1,4 +0,0 @@
|
||||
prog: leak-autofreepool
|
||||
vgopts: --leak-check=full --show-possibly-lost=no --track-origins=yes
|
||||
args: 3
|
||||
stderr_filter: filter_allocs
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#include "../memcheck.h"
|
||||
|
||||
// Test VALGRIND_CREATE_META_MEMPOOL features, the VALGRIND_MEMPOOL_METAPOOL and
|
||||
// Test VALGRIND_CREATE_MEMPOOL_EXT features, the VALGRIND_MEMPOOL_METAPOOL and
|
||||
// VALGRIND_MEMPOOL_AUTO_FREE flags.
|
||||
// Also show that without these, having a custom allocator that:
|
||||
// - Allocates a MEMPOOL
|
||||
@ -64,7 +64,7 @@ static char MetaBlock[POOL_BLOCK_SIZE];
|
||||
|
||||
void create_meta_pool (void)
|
||||
{
|
||||
VALGRIND_CREATE_META_MEMPOOL(MetaPool, 0, 0, MetaPoolFlags);
|
||||
VALGRIND_CREATE_MEMPOOL_EXT(MetaPool, 0, 0, MetaPoolFlags);
|
||||
VALGRIND_MEMPOOL_ALLOC(MetaPool, MetaBlock, POOL_BLOCK_SIZE);
|
||||
|
||||
MetaPool->buf = (uint8_t *) MetaBlock;
|
||||
@ -124,7 +124,7 @@ static void *allocate_plain_style (struct pool *p, size_t n)
|
||||
static void set_flags ( int n )
|
||||
{
|
||||
switch (n) {
|
||||
// Case 0: No special flags. VALGRIND_CREATE_META_MEMPOOL is same as
|
||||
// Case 0: No special flags. VALGRIND_CREATE_MEMPOOL_EXT is same as
|
||||
// VALGRIND_CREATE_MEMPOOL.
|
||||
// When mempools are destroyed, the METAPOOL leaks because auto-free is
|
||||
// missing. Must show 2*N (20) leaks.
|
||||
@ -148,13 +148,15 @@ static void set_flags ( int n )
|
||||
// Same as before, but now the MALLOCLIKE blocks are auto-freed.
|
||||
// Must show 0 leaks.
|
||||
case 2:
|
||||
MetaPoolFlags = VALGRIND_MEMPOOL_AUTO_FREE | VALGRIND_MEMPOOL_METAPOOL;
|
||||
MetaPoolFlags = VALGRIND_MEMPOOL_METAPOOL | VALGRIND_MEMPOOL_AUTO_FREE;
|
||||
CleanupBeforeExit = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Just auto-free, with cleanup. The cleanup removes the overlapping
|
||||
// blocks, so this is the same as case 2: No leaks, no problems.
|
||||
case 3: // Note: this is incorrect behaviour, and aborts valgrind.
|
||||
// (so it is not exercised during regression testing).
|
||||
// Just auto-free, not marked with meta pool flag.
|
||||
// This is an error, and will cause valgrind to abort when the pool
|
||||
// is created.
|
||||
MetaPoolFlags = VALGRIND_MEMPOOL_AUTO_FREE;
|
||||
CleanupBeforeExit = 1;
|
||||
break;
|
||||
@ -185,7 +187,7 @@ static void set_flags ( int n )
|
||||
// already done above) is by allocating lots of other chunks that are
|
||||
// NOT part of the pool so the MC_Alloc lists contain other stuff.
|
||||
// That will make the iterator find stuff AND skip stuff.
|
||||
MetaPoolFlags = VALGRIND_MEMPOOL_AUTO_FREE | VALGRIND_MEMPOOL_METAPOOL;
|
||||
MetaPoolFlags = VALGRIND_MEMPOOL_METAPOOL | VALGRIND_MEMPOOL_AUTO_FREE;
|
||||
CleanupBeforeExit = 1;
|
||||
GenerateNoise = 1;
|
||||
break;
|
||||
@ -314,9 +316,9 @@ int main( int argc, char** argv )
|
||||
pool_block_size = nr_elts * sizeof(struct cell) + sizeof(uint8_t) + 1;
|
||||
|
||||
// Create perf meta pool
|
||||
VALGRIND_CREATE_META_MEMPOOL
|
||||
VALGRIND_CREATE_MEMPOOL_EXT
|
||||
(&perf_meta_pool, 0, 0,
|
||||
VALGRIND_MEMPOOL_AUTO_FREE | VALGRIND_MEMPOOL_METAPOOL);
|
||||
VALGRIND_MEMPOOL_METAPOOL | VALGRIND_MEMPOOL_AUTO_FREE);
|
||||
perf_meta_block = malloc(pool_block_size);
|
||||
|
||||
VALGRIND_MEMPOOL_ALLOC(&perf_meta_pool, perf_meta_block,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user