/* Record malloc'd blocks. */
VgHashTable MC_(malloc_list) = NULL;
-/* Memory pools. */
+/* Memory pools: a hash table of MC_Mempools. Search key is
+ MC_Mempool::pool. */
VgHashTable MC_(mempool_list) = NULL;
/* Records blocks after freeing. */
mc1->next = NULL; /* just paranoia */
/* free MC_Chunk */
- VG_(cli_free) ( (void*)(mc1->data) );
+ if (MC_AllocCustom != mc1->allockind)
+ VG_(cli_free) ( (void*)(mc1->data) );
VG_(free) ( mc1 );
}
}
accessible with a client request... */
MC_(make_mem_noaccess)( mc->data-rzB, mc->szB + 2*rzB );
- /* Put it out of harm's way for a while, if not from a client request */
- if (MC_AllocCustom != mc->allockind) {
- /* Record where freed */
- mc->where = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
- add_to_freed_queue ( mc );
- } else {
- VG_(free) ( mc );
- }
+ /* Record where freed */
+ mc->where = VG_(record_ExeContext) ( tid, 0/*first_ip_delta*/ );
+ /* Put it out of harm's way for a while */
+ add_to_freed_queue ( mc );
}
void MC_(handle_free) ( ThreadId tid, Addr p, UInt rzB, MC_AllocKind kind )
return ( mc ? mc->szB : 0 );
}
+/* This handles the in place resize of a block, as performed by the
+ VALGRIND_RESIZEINPLACE_BLOCK client request. It is unrelated to,
+ and not used for, handling of the normal libc realloc()
+ function. */
+void MC_(handle_resizeInPlace)(ThreadId tid, Addr p,
+ SizeT oldSizeB, SizeT newSizeB, SizeT rzB)
+{
+ MC_Chunk* mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)p );
+ if (!mc || mc->szB != oldSizeB || newSizeB == 0) {
+ /* Reject if: p is not found, or oldSizeB is wrong,
+ or new block would be empty. */
+ MC_(record_free_error) ( tid, p );
+ return;
+ }
+
+ if (oldSizeB == newSizeB)
+ return;
+
+ mc->szB = newSizeB;
+ if (newSizeB < oldSizeB) {
+ MC_(make_mem_noaccess)( p + newSizeB, oldSizeB - newSizeB + rzB );
+ } else {
+ ExeContext* ec = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
+ UInt ecu = VG_(get_ECU_from_ExeContext)(ec);
+ MC_(make_mem_undefined_w_otag)( p + oldSizeB, newSizeB - oldSizeB,
+ ecu | MC_OKIND_HEAP );
+ if (rzB > 0)
+ MC_(make_mem_noaccess)( p + newSizeB, rzB );
+ }
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Memory pool stuff. ---*/
+/*------------------------------------------------------------*/
+
+/* Set to 1 for intensive sanity checking. Is very expensive though
+ and should not be used in production scenarios. See #255966. */
+#define MP_DETAILED_SANITY_CHECKS 0
+
+static void check_mempool_sane(MC_Mempool* mp); /*forward*/
-/* Memory pool stuff. */
void MC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed)
{
mp->rzB = rzB;
mp->is_zeroed = is_zeroed;
mp->chunks = VG_(HT_construct)( "MC_(create_mempool)" );
+ check_mempool_sane(mp);
/* Paranoia ... ensure this area is off-limits to the client, so
the mp->data field isn't visible to the leak checker. If memory
MC_(record_illegal_mempool_error) ( tid, pool );
return;
}
+ check_mempool_sane(mp);
// Clean up the chunks, one by one
VG_(HT_ResetIter)(mp->chunks);
if (mp == NULL) {
MC_(record_illegal_mempool_error) ( tid, pool );
} else {
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
MC_(new_block)(tid, addr, szB, /*ignored*/0, mp->is_zeroed,
MC_AllocCustom, mp->chunks);
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
}
}
VG_(get_and_pp_StackTrace) (tid, MEMPOOL_DEBUG_STACKTRACE_DEPTH);
}
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
mc = VG_(HT_remove)(mp->chunks, (UWord)addr);
if (mc == NULL) {
MC_(record_free_error)(tid, (Addr)addr);
}
die_and_free_mem ( tid, mc, mp->rzB );
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
}
if (VG_(HT_remove)(mp->chunks, (UWord)mc->data) == NULL) {
MC_(record_free_error)(tid, (Addr)mc->data);
VG_(free)(chunks);
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
return;
}
die_and_free_mem ( tid, mc, mp->rzB );
if (VG_(HT_remove)(mp->chunks, (UWord)mc->data) == NULL) {
MC_(record_free_error)(tid, (Addr)mc->data);
VG_(free)(chunks);
- check_mempool_sane(mp);
+ if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp);
return;
}