static MC_Chunk**
-find_active_chunks(Int* pn_chunks)
+get_sorted_array_of_active_chunks(Int* pn_chunks)
{
- // Our goal is to construct a set of chunks that includes every
- // mempool chunk, and every malloc region that *doesn't* contain a
- // mempool chunk.
- MC_Mempool *mp;
- MC_Chunk **mallocs, **chunks, *mc;
- UInt n_mallocs, n_chunks, m, s;
- Bool *malloc_chunk_holds_a_pool_chunk;
+ UInt n_mallocs;
+ MC_Chunk **mallocs;
// 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
}
VG_(ssort)(mallocs, n_mallocs, sizeof(VgHashNode*), compare_MC_Chunks);
- // Then we build an array containing a Bool for each malloc chunk,
- // indicating whether it contains any mempools.
- malloc_chunk_holds_a_pool_chunk = VG_(calloc)( "mc.fas.1",
- n_mallocs, sizeof(Bool) );
- n_chunks = n_mallocs;
+ // If there are no mempools (for most users, this is the case),
+ // n_mallocs and mallocs is the final result
+ // otherwise we need to do special handling for mempools.
+
+ if (VG_(HT_count_nodes)(MC_(mempool_list)) > 0) {
+ // Our goal is to construct a set of chunks that includes every
+ // mempool chunk, and every malloc region that *doesn't* contain a
+ // mempool chunk.
+ MC_Mempool *mp;
+ MC_Chunk **chunks, *mc;
+ UInt n_chunks, m, s;
+ Bool *malloc_chunk_holds_a_pool_chunk;
+
+ // We build an array containing a Bool for each malloc chunk,
+ // indicating whether it contains any mempools.
+ malloc_chunk_holds_a_pool_chunk = VG_(calloc)( "mc.fas.1",
+ n_mallocs, sizeof(Bool) );
+ n_chunks = n_mallocs;
+
+ // Then 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.
+ VG_(HT_ResetIter)(MC_(mempool_list));
+ while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
+ VG_(HT_ResetIter)(mp->chunks);
+ while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
- // Then 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.
- VG_(HT_ResetIter)(MC_(mempool_list));
- while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
- VG_(HT_ResetIter)(mp->chunks);
- while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
-
- // We'll need to record this chunk.
- n_chunks++;
-
- // Possibly invalidate the malloc holding the beginning of this chunk.
- m = find_chunk_for(mc->data, mallocs, n_mallocs);
- if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
- tl_assert(n_chunks > 0);
- n_chunks--;
- malloc_chunk_holds_a_pool_chunk[m] = True;
- }
+ // We'll need to record this chunk.
+ n_chunks++;
- // Possibly invalidate the malloc holding the end of this chunk.
- if (mc->szB > 1) {
- m = find_chunk_for(mc->data + (mc->szB - 1), mallocs, n_mallocs);
+ // Possibly invalidate the malloc holding the beginning of this chunk.
+ m = find_chunk_for(mc->data, mallocs, n_mallocs);
if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
tl_assert(n_chunks > 0);
n_chunks--;
malloc_chunk_holds_a_pool_chunk[m] = True;
}
+
+ // Possibly invalidate the malloc holding the end of this chunk.
+ if (mc->szB > 1) {
+ m = find_chunk_for(mc->data + (mc->szB - 1), mallocs, n_mallocs);
+ if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
+ tl_assert(n_chunks > 0);
+ n_chunks--;
+ malloc_chunk_holds_a_pool_chunk[m] = True;
+ }
+ }
}
}
- }
- tl_assert(n_chunks > 0);
+ tl_assert(n_chunks > 0);
- // Create final chunk array.
- chunks = VG_(malloc)("mc.fas.2", sizeof(VgHashNode*) * (n_chunks));
- s = 0;
+ // Create final chunk array.
+ chunks = VG_(malloc)("mc.fas.2", sizeof(VgHashNode*) * (n_chunks));
+ s = 0;
- // Copy the mempool chunks and the non-marked malloc chunks into a
- // combined array of chunks.
- VG_(HT_ResetIter)(MC_(mempool_list));
- while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
- VG_(HT_ResetIter)(mp->chunks);
- while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
- tl_assert(s < n_chunks);
- chunks[s++] = mc;
+ // Copy the mempool chunks and the non-marked malloc chunks into a
+ // combined array of chunks.
+ VG_(HT_ResetIter)(MC_(mempool_list));
+ while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
+ VG_(HT_ResetIter)(mp->chunks);
+ while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
+ tl_assert(s < n_chunks);
+ chunks[s++] = mc;
+ }
}
- }
- for (m = 0; m < n_mallocs; ++m) {
- if (!malloc_chunk_holds_a_pool_chunk[m]) {
- tl_assert(s < n_chunks);
- chunks[s++] = mallocs[m];
+ for (m = 0; m < n_mallocs; ++m) {
+ if (!malloc_chunk_holds_a_pool_chunk[m]) {
+ tl_assert(s < n_chunks);
+ chunks[s++] = mallocs[m];
+ }
}
- }
- tl_assert(s == n_chunks);
+ tl_assert(s == n_chunks);
- // Free temporaries.
- VG_(free)(mallocs);
- VG_(free)(malloc_chunk_holds_a_pool_chunk);
+ // Free temporaries.
+ VG_(free)(mallocs);
+ VG_(free)(malloc_chunk_holds_a_pool_chunk);
- *pn_chunks = n_chunks;
+ *pn_chunks = n_chunks;
+
+ // Sort the array so blocks are in ascending order in memory.
+ VG_(ssort)(chunks, n_chunks, sizeof(VgHashNode*), compare_MC_Chunks);
+
+ // Sanity check -- make sure they're in order.
+ for (int i = 0; i < n_chunks-1; i++) {
+ tl_assert( chunks[i]->data <= chunks[i+1]->data);
+ }
- return chunks;
+ return chunks;
+ } else {
+ *pn_chunks = n_mallocs;
+ return mallocs;
+ }
}
/*------------------------------------------------------------*/
VG_(free)(lc_chunks);
lc_chunks = NULL;
}
- lc_chunks = find_active_chunks(&lc_n_chunks);
+ lc_chunks = get_sorted_array_of_active_chunks(&lc_n_chunks);
lc_chunks_n_frees_marker = MC_(get_cmalloc_n_frees)();
if (lc_n_chunks == 0) {
tl_assert(lc_chunks == NULL);
return;
}
- // Sort the array so blocks are in ascending order in memory.
- VG_(ssort)(lc_chunks, lc_n_chunks, sizeof(VgHashNode*), compare_MC_Chunks);
-
- // Sanity check -- make sure they're in order.
- for (i = 0; i < lc_n_chunks-1; i++) {
- tl_assert( lc_chunks[i]->data <= lc_chunks[i+1]->data);
- }
-
// Sanity check -- make sure they don't overlap. One exception is that
// we allow a MALLOCLIKE block to sit entirely within a malloc() block.
// This is for bug 100628. If this occurs, we ignore the malloc() block
VG_(umsg) ("Searching for pointers pointing in %lu bytes from %#lx\n",
szB, address);
- chunks = find_active_chunks(&n_chunks);
+ chunks = get_sorted_array_of_active_chunks(&n_chunks);
// Scan memory root-set, searching for ptr pointing in address[szB]
scan_memory_root_set(address, szB);