]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Clarify name and description/manual for meta mempool
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 15 Oct 2016 12:59:04 +0000 (12:59 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 15 Oct 2016 12:59:04 +0000 (12:59 +0000)
* 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

include/valgrind.h
memcheck/docs/mc-manual.xml
memcheck/mc_malloc_wrappers.c
memcheck/tests/Makefile.am
memcheck/tests/leak-autofreepool-3.stderr.exp [deleted file]
memcheck/tests/leak-autofreepool-3.vgtest [deleted file]
memcheck/tests/leak-autofreepool.c

index 20a188179c57b7a2f4b857b4b0492b9166c0484a..689200739f05dd72142907a3a87c11fb2a74be62 100644 (file)
@@ -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)                            \
index 57a9d7dcc4bd01b85f7c0270e7fb665f48eb189d..e8e08e2586e7132b44f0869fcd28e267ebaed510 100644 (file)
@@ -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>
index 8259401c95e428b9e489fdc330c14ce12515871f..f4881785241ff5b1bca5029379889284ee3fffbc 100644 (file)
@@ -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);
index 02888cb4cdc4d9da6055a365b32e19ac094be922..b432c078ac5451cff280a5dab92cb774ffdf5332 100644 (file)
@@ -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 \
diff --git a/memcheck/tests/leak-autofreepool-3.stderr.exp b/memcheck/tests/leak-autofreepool-3.stderr.exp
deleted file mode 100644 (file)
index 4178c4e..0000000
+++ /dev/null
@@ -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)
diff --git a/memcheck/tests/leak-autofreepool-3.vgtest b/memcheck/tests/leak-autofreepool-3.vgtest
deleted file mode 100644 (file)
index 46e3457..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-prog: leak-autofreepool
-vgopts: --leak-check=full --show-possibly-lost=no --track-origins=yes
-args: 3
-stderr_filter: filter_allocs
index f918fee324c474e1ec537f3affca59a03c22d4ae..3bd6e50dc36ab34054c6cbe67948274a075ef3c4 100644 (file)
@@ -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,