]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 233298 - Reflect MEMPOOL_FREE in heap summary
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 11 Jan 2025 16:39:44 +0000 (17:39 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 15 Feb 2026 16:40:05 +0000 (17:40 +0100)
There was one missing free increment for autoref pools.

Also added testcases based on memcheck mempool2 and leak-autorefpool.

Original patch contributed by 8dcc <8dcc.git@gmail.com>

This is an update on a patch from 2010:
https://bugsfiles.kde.org/attachment.cgi?id=42491

NEWS
memcheck/mc_malloc_wrappers.c
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/bug233298.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/bug233298.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/filter_heap_usage [new file with mode: 0755]
memcheck/tests/freebsd/leak-autofreepool-7.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/leak-autofreepool-7.vgtest [new file with mode: 0644]
memcheck/tests/leak-autofreepool.c
memcheck/tests/mempool2.c
memcheck/tests/mempool2.stderr.exp

diff --git a/NEWS b/NEWS
index 24a34af19b4de4ad00ca6f369f54eee1b66cde14..de11c3c0f3377fa9be2bb2051422ce1370c115df 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 
 126256  (fnop) vex x86->IR: unhandled instruction bytes: 0xD9 0xD0 0x31 0xC0
 228343  none/tests/darwin/bug228343 fails on OS X
+233298  MEMPOOL_FREE not reflected in heap summary
 253436  vex amd64->IR: unhandled instruction bytes: 0xF2 0xA6 (repne cmps)
 258140  Valgrind on OS X always reports some memory "still reachable"
 413369  unhandled amd64-darwin syscall: unix:151 (getpgid)
index ae50923c49f62820127bf8e79af13c0921bfc06f..737837dbba706069e65d8c3ecde4003a97b8ff2c 100644 (file)
@@ -782,6 +782,7 @@ static void free_mallocs_in_mempool_block (MC_Mempool* mp,
 
         VG_(HT_remove_at_Iter)(MC_(malloc_list));
         die_and_free_mem(tid, mc, mp->rzB);
+         cmalloc_n_frees++;
       }
    }
 }
@@ -1014,6 +1015,7 @@ void MC_(mempool_free)(Addr pool, Addr addr)
 
    die_and_free_mem ( tid, mc, mp->rzB );
    if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
+   cmalloc_n_frees++;
 }
 
 
@@ -1073,10 +1075,11 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB)
             MC_(record_free_error)(tid, (Addr)mc->data);
             VG_(free)(chunks);
             if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
+            cmalloc_n_frees++;
             return;
          }
          die_and_free_mem ( tid, mc, mp->rzB );  
-
+         cmalloc_n_frees++;
       } else {
 
          /* The current chunk intersects the trim extent: remove,
@@ -1088,6 +1091,7 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB)
             MC_(record_free_error)(tid, (Addr)mc->data);
             VG_(free)(chunks);
             if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
+            cmalloc_n_frees++;
             return;
          }
 
@@ -1122,6 +1126,7 @@ void MC_(mempool_trim)(Addr pool, Addr addr, SizeT szB)
          mc->data = lo;
          mc->szB = (UInt) (hi - lo);
          VG_(HT_add_node)( mp->chunks, mc );        
+         cmalloc_n_frees++;
       }
 
 #undef EXTENT_CONTAINS
index 96c57e21eedd37d9851c9415efe3bcdda8bc0f9c..9b67fb299a7bf15a73ef0b5bbf8b324edf5928ac 100644 (file)
@@ -4,7 +4,7 @@ include $(top_srcdir)/Makefile.tool-tests.am
 dist_noinst_SCRIPTS = filter_stderr filter_pts dump_stdout filter_sigwait \
        filter_scalar filter_realpathat filter_fstat filter_eventfd2 \
        toucher1 toucher2 filter_getfsstat filter_context filter_frame \
-       filter_supp filter_kenv
+       filter_supp filter_kenv filter_heap_usage
 
 EXTRA_DIST = \
        access.vgtest \
@@ -18,6 +18,8 @@ EXTRA_DIST = \
        aligned_allocs_supp.vgtest \
        aligned_allocs_supp.stderr.exp \
        aligned_allocs_supp.supp \
+       bug233298.vgtest \
+       bug233298.stderr.exp \
        bug464476.vgtest \
        bug464476.stdout.exp \
        bug464476_abs_symlink.vgtest \
@@ -73,6 +75,8 @@ EXTRA_DIST = \
        kqueue.stdout.exp \
        kqueuex.vgtest \
        kqueuex.stdout.exp \
+       leak-autofreepool-7.vgtest \
+       leak-autofreepool-7.stderr.exp \
        linkat.vgtest \
        linkat.stderr.exp \
         memalign.vgtest memalign.stderr.exp \
diff --git a/memcheck/tests/freebsd/bug233298.stderr.exp b/memcheck/tests/freebsd/bug233298.stderr.exp
new file mode 100644 (file)
index 0000000..8b6098f
--- /dev/null
@@ -0,0 +1 @@
+  total heap usage: 6 allocs, 6 frees, XXX bytes allocated
diff --git a/memcheck/tests/freebsd/bug233298.vgtest b/memcheck/tests/freebsd/bug233298.vgtest
new file mode 100644 (file)
index 0000000..8de1581
--- /dev/null
@@ -0,0 +1,3 @@
+prog: ../mempool2
+vgopts: --leak-check=yes
+stderr_filter: filter_heap_usage
diff --git a/memcheck/tests/freebsd/filter_heap_usage b/memcheck/tests/freebsd/filter_heap_usage
new file mode 100755 (executable)
index 0000000..6a624e5
--- /dev/null
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+../filter_stderr "$@" |
+grep "total heap usage:" |
+gsed 's/ [^ ]* bytes allocated/ XXX bytes allocated/'
+
+
+
+
diff --git a/memcheck/tests/freebsd/leak-autofreepool-7.stderr.exp b/memcheck/tests/freebsd/leak-autofreepool-7.stderr.exp
new file mode 100644 (file)
index 0000000..7c08153
--- /dev/null
@@ -0,0 +1 @@
+  total heap usage: 31 allocs, 31 frees, XXX bytes allocated
diff --git a/memcheck/tests/freebsd/leak-autofreepool-7.vgtest b/memcheck/tests/freebsd/leak-autofreepool-7.vgtest
new file mode 100644 (file)
index 0000000..be624dc
--- /dev/null
@@ -0,0 +1,4 @@
+prog: ../leak-autofreepool
+vgopts: --leak-check=full
+args: 7
+stderr_filter: filter_heap_usage
index 3bd6e50dc36ab34054c6cbe67948274a075ef3c4..057a6573b5646d3cd23bf22a68682a629ef3aebb 100644 (file)
@@ -53,6 +53,7 @@ static int    MetaPoolFlags = 0;
 static int    CleanupBeforeExit = 0;
 static int    GenerateNoise = 0;
 static int    NoiseCounter = 0;
+static int    CleanupMoreBeforeExit = 0;
 
 static struct cell *cells_plain[2 * N];
 static struct cell *cells_meta[2 * N];
@@ -192,6 +193,14 @@ static void set_flags ( int n )
         GenerateNoise     = 1;
         break;
 
+        // Same as case 2, but enable freeing blocks from PlainPool so that
+        // we can check that malloc count == free count
+     case 7:
+        MetaPoolFlags = VALGRIND_MEMPOOL_METAPOOL | VALGRIND_MEMPOOL_AUTO_FREE;
+        CleanupBeforeExit = 1;
+        CleanupMoreBeforeExit = 1;
+        break;
+
      default:
         assert(0);
   }
@@ -255,8 +264,10 @@ int main( int argc, char** argv )
    }
 
    // Leak the memory from the pools by losing the pointers.
-   for (i = 0; i < N; ++i) {
-      cells_plain[i] = NULL;
+   if (!CleanupMoreBeforeExit) {
+      for (i = 0; i < N; ++i) {
+         cells_plain[i] = NULL;
+      }
    }
 
    for (i = 0; i < 2 * N; ++i) {
@@ -284,6 +295,11 @@ int main( int argc, char** argv )
    }
 
    // Cleanup.
+   if (CleanupMoreBeforeExit) {
+      for (i = 0; i < N; ++i) {
+         VALGRIND_MEMPOOL_FREE(PlainPool, cells_plain[i]);
+      }
+   }
    VALGRIND_DESTROY_MEMPOOL(PlainPool);
 
    if (GenerateNoise)
index 4c8683c2200d8649c5b6b0d9a92e82c8895da02e..7408d122abc30af1ed13e579f00875c884e59b25 100644 (file)
@@ -182,6 +182,8 @@ void test(void)
       res += superblock[29]; // invalid
       res += superblock[40]; // invalid
 
+      VALGRIND_MEMPOOL_FREE(superblock, superblock+30);
+
       VALGRIND_DESTROY_MEMPOOL(superblock);
    }
    // claim res is used, so gcc can't nuke this all
index 8dda2cecb4cf21708aca305d8c544096f45679d5..6c6cc72333814ff752a9700c8b8b2c38b603e1ba 100644 (file)
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:135)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 1 bytes before a block of size 10 client-defined
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:130)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:136)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 0 bytes after a block of size 10 client-defined
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:130)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ out of range reads in mmap-backed pool ------
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:140)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 1 bytes before a block of size 20 client-defined
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:131)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:141)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 0 bytes after a block of size 20 client-defined
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:131)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ Illegal memory pool address  ------
 
 Illegal memory pool address
    at 0x........: test (mempool2.c:145)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 0 bytes inside a block of size 32 alloc'd
    at 0x........: malloc (vg_replace_malloc.c:...)
    by 0x........: make_pool (mempool2.c:46)
    by 0x........: test (mempool2.c:122)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ read free in malloc-backed pool ------
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:150)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 13 bytes inside a recently re-allocated block of size 100,000 alloc'd
    at 0x........: malloc (vg_replace_malloc.c:...)
    by 0x........: make_pool (mempool2.c:47)
    by 0x........: test (mempool2.c:122)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ read free in mmap-backed pool ------
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:155)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 11 bytes inside a block of size 20 free'd
    at 0x........: test (mempool2.c:154)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Block was alloc'd at
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:131)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ double free in malloc-backed pool ------
 
 Invalid free() / delete / delete[] / realloc()
    at 0x........: test (mempool2.c:159)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 8 bytes inside a recently re-allocated block of size 100,000 alloc'd
    at 0x........: malloc (vg_replace_malloc.c:...)
    by 0x........: make_pool (mempool2.c:47)
    by 0x........: test (mempool2.c:122)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ double free in mmap-backed pool ------
 
 Invalid free() / delete / delete[] / realloc()
    at 0x........: test (mempool2.c:163)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 0 bytes inside a block of size 20 free'd
    at 0x........: test (mempool2.c:154)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Block was alloc'd at
    at 0x........: allocate (mempool2.c:108)
    by 0x........: test (mempool2.c:131)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ 2 invalid access in 'no no-access superblock' ---
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:182)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 1 bytes before a block of size 10 client-defined
    at 0x........: test (mempool2.c:175)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 Invalid read of size 1
    at 0x........: test (mempool2.c:183)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
  Address 0x........ is 0 bytes after a block of size 10 client-defined
    at 0x........: test (mempool2.c:175)
-   by 0x........: main (mempool2.c:200)
+   by 0x........: main (mempool2.c:202)
 
 
 ------ done ------