|
From: <sv...@va...> - 2006-08-28 12:24:50
|
Author: sewardj
Date: 2006-08-28 13:24:48 +0100 (Mon, 28 Aug 2006)
New Revision: 6024
Log:
Merge r5991,4,6 (GraydonH leak checking fix)
Modified:
branches/VALGRIND_3_2_BRANCH/memcheck/mc_leakcheck.c
branches/VALGRIND_3_2_BRANCH/memcheck/tests/mempool.stderr.exp
Modified: branches/VALGRIND_3_2_BRANCH/memcheck/mc_leakcheck.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/VALGRIND_3_2_BRANCH/memcheck/mc_leakcheck.c 2006-08-28 12:21=
:19 UTC (rev 6023)
+++ branches/VALGRIND_3_2_BRANCH/memcheck/mc_leakcheck.c 2006-08-28 12:24=
:48 UTC (rev 6024)
@@ -175,7 +175,7 @@
PROF_EVENT(71, "find_shadow_for_OLD(loop)");
a_lo =3D shadows[i]->data;
a_hi =3D ((Addr)shadows[i]->data) + shadows[i]->size;
- if (a_lo <=3D ptr && ptr <=3D a_hi)
+ if (a_lo <=3D ptr && ptr < a_hi)
return i;
}
return -1;
@@ -201,16 +201,24 @@
mid =3D (lo + hi) / 2;
a_mid_lo =3D shadows[mid]->data;
a_mid_hi =3D shadows[mid]->data + shadows[mid]->size;
+ /* Extent of block 'mid' is [a_mid_lo .. a_mid_hi).
+ Special-case zero-sized blocks - treat them as if they had
+ size 1. Not doing so causes them to not cover any address
+ range at all and so will never be identified as the target of
+ any pointer, which causes them to be incorrectly reported as
+ definitely leaked. */
+ if (shadows[mid]->size =3D=3D 0)
+ a_mid_hi++;
=20
if (ptr < a_mid_lo) {
hi =3D mid-1;
continue;
}=20
- if (ptr > a_mid_hi) {
+ if (ptr >=3D a_mid_hi) {
lo =3D mid+1;
continue;
}
- tl_assert(ptr >=3D a_mid_lo && ptr <=3D a_mid_hi);
+ tl_assert(ptr >=3D a_mid_lo && ptr < a_mid_hi);
retVal =3D mid;
break;
}
@@ -345,7 +353,10 @@
return;
=20
tl_assert(sh_no >=3D 0 && sh_no < lc_n_shadows);
- tl_assert(ptr <=3D lc_shadows[sh_no]->data + lc_shadows[sh_no]->size)=
;
+ tl_assert(ptr >=3D lc_shadows[sh_no]->data);
+ tl_assert(ptr < lc_shadows[sh_no]->data=20
+ + lc_shadows[sh_no]->size
+ + (lc_shadows[sh_no]->size=3D=3D0 ? 1 : 0));
=20
if (lc_markstack[sh_no].state =3D=3D Unreached) {
if (0)
@@ -673,6 +684,107 @@
}
}
=20
+static MC_Chunk**
+find_active_shadows(UInt* n_shadows)
+{
+ /* Our goal is to construct a set of shadows that includes every
+ * mempool chunk, and every malloc region that *doesn't* contain a
+ * mempool chunk. We do this in several phases.
+ *
+ * First we collect all the malloc chunks into an array and sort it.
+ * We do this because we want to query the chunks by interior
+ * pointers, requiring binary search.
+ *
+ * Second we build an array containing a Bool for each malloc chunk,
+ * indicating whether it contains any mempools.
+ *
+ * Third we loop over the mempool tables. For each chunk in each
+ * pool, we set the entry in the Bool array corresponding to the
+ * malloc chunk containing the mempool chunk.
+ *
+ * Finally we copy the mempool chunks and the non-marked malloc
+ * chunks into a combined array of shadows, free our temporaries,
+ * and return the combined array.
+ */
+
+ MC_Mempool *mp;
+ MC_Chunk **mallocs, **shadows, *mc;
+ UInt n_mallocs, m, s;
+ Bool *malloc_chunk_holds_a_pool_chunk;
+
+ mallocs =3D (MC_Chunk**) VG_(HT_to_array)( MC_(malloc_list), &n_mallo=
cs );
+
+ if (n_mallocs =3D=3D 0) {
+ tl_assert(mallocs =3D=3D NULL);
+ *n_shadows =3D 0;
+ return NULL;
+ }
+
+ VG_(ssort)((void*)mallocs, n_mallocs,=20
+ sizeof(VgHashNode*), lc_compar);
+
+ malloc_chunk_holds_a_pool_chunk =3D VG_(calloc)( n_mallocs, sizeof(Bo=
ol) );
+
+ *n_shadows =3D n_mallocs;
+
+ VG_(HT_ResetIter)(MC_(mempool_list));
+ while ( (mp =3D VG_(HT_Next)(MC_(mempool_list))) ) {
+ VG_(HT_ResetIter)(mp->chunks);
+ while ( (mc =3D VG_(HT_Next)(mp->chunks)) ) {
+
+ /* We'll need a shadow for this chunk. */
+ ++(*n_shadows);
+
+ /* Possibly invalidate the malloc holding the beginning of this=
chunk. */
+ m =3D find_shadow_for(mc->data, mallocs, n_mallocs);
+ if (m !=3D -1 && malloc_chunk_holds_a_pool_chunk[m] =3D=3D Fals=
e) {
+ tl_assert(*n_shadows > 0);
+ --(*n_shadows);
+ malloc_chunk_holds_a_pool_chunk[m] =3D True;
+ }
+
+ /* Possibly invalidate the malloc holding the end of this chunk=
. */
+ if (mc->size > 1) {
+ m =3D find_shadow_for(mc->data + (mc->size - 1), mallocs, n_=
mallocs);
+ if (m !=3D -1 && malloc_chunk_holds_a_pool_chunk[m] =3D=3D F=
alse) {
+ tl_assert(*n_shadows > 0);
+ --(*n_shadows);
+ malloc_chunk_holds_a_pool_chunk[m] =3D True;
+ }
+ }
+ }
+ }
+
+ tl_assert(*n_shadows > 0);
+ shadows =3D VG_(malloc)(sizeof(VgHashNode*) * (*n_shadows));
+ s =3D 0;
+
+ /* Copy the mempool chunks into the final array. */
+ VG_(HT_ResetIter)(MC_(mempool_list));
+ while ( (mp =3D VG_(HT_Next)(MC_(mempool_list))) ) {
+ VG_(HT_ResetIter)(mp->chunks);
+ while ( (mc =3D VG_(HT_Next)(mp->chunks)) ) {
+ tl_assert(s < *n_shadows);
+ shadows[s++] =3D mc;
+ }
+ }
+
+ /* Copy the malloc chunks into the final array. */
+ for (m =3D 0; m < n_mallocs; ++m) {
+ if (!malloc_chunk_holds_a_pool_chunk[m]) {
+ tl_assert(s < *n_shadows);
+ shadows[s++] =3D mallocs[m];
+ }
+ }
+
+ tl_assert(s =3D=3D *n_shadows);
+ VG_(free)(mallocs);
+ VG_(free)(malloc_chunk_holds_a_pool_chunk);
+
+ return shadows;
+}
+
+
/* Top level entry point to leak detector. Call here, passing in
suitable address-validating functions (see comment at top of
scan_all_valid_memory above). These functions used to encapsulate th=
e
@@ -689,9 +801,7 @@
=20
tl_assert(mode !=3D LC_Off);
=20
- /* VG_(HT_to_array) allocates storage for shadows */
- lc_shadows =3D (MC_Chunk**)VG_(HT_to_array)( MC_(malloc_list),
- &lc_n_shadows );
+ lc_shadows =3D find_active_shadows(&lc_n_shadows);
=20
/* Sort the array. */
VG_(ssort)((void*)lc_shadows, lc_n_shadows, sizeof(VgHashNode*), lc_c=
ompar);
Modified: branches/VALGRIND_3_2_BRANCH/memcheck/tests/mempool.stderr.exp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/VALGRIND_3_2_BRANCH/memcheck/tests/mempool.stderr.exp 2006-0=
8-28 12:21:19 UTC (rev 6023)
+++ branches/VALGRIND_3_2_BRANCH/memcheck/tests/mempool.stderr.exp 2006-0=
8-28 12:24:48 UTC (rev 6024)
@@ -35,7 +35,25 @@
by 0x........: main (mempool.c:148)
=20
=20
-100,028 (20 direct, 100,008 indirect) bytes in 1 blocks are definitely l=
ost in loss record 2 of 3
+10 bytes in 1 blocks are definitely lost in loss record 2 of 5
+ at 0x........: allocate (mempool.c:99)
+ by 0x........: test (mempool.c:135)
+ by 0x........: main (mempool.c:148)
+
+
+10 bytes in 1 blocks are definitely lost in loss record 3 of 5
+ at 0x........: allocate (mempool.c:99)
+ by 0x........: test (mempool.c:115)
+ by 0x........: main (mempool.c:148)
+
+
+20 bytes in 1 blocks are definitely lost in loss record 4 of 5
+ at 0x........: allocate (mempool.c:99)
+ by 0x........: test (mempool.c:116)
+ by 0x........: main (mempool.c:148)
+
+
+28 (20 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss=
record 5 of 5
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: make_pool (mempool.c:37)
by 0x........: test (mempool.c:111)
|