Bug 1439474 - Make double-free crashes more identifiable. r?njn
- Turn MOZ_DIAGNOSTIC_ASSERTs related to double-frees into
MOZ_RELEASE_ASSERTs with a crash message making them more identifiable
than the asserted condition.
- In huge_dalloc, MOZ_RELEASE_ASSERT early, instead of letting
RedBlackTree::Remove end up crashing because the node is not in the
tree.
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -2298,17 +2298,18 @@ arena_run_reg_dalloc(arena_run_t* run, a
MOZ_DIAGNOSTIC_ASSERT(diff == regind * size);
MOZ_DIAGNOSTIC_ASSERT(regind < bin->mRunNumRegions);
elm = regind >> (LOG2(sizeof(int)) + 3);
if (elm < run->mRegionsMinElement) {
run->mRegionsMinElement = elm;
}
bit = regind - (elm << (LOG2(sizeof(int)) + 3));
- MOZ_DIAGNOSTIC_ASSERT((run->mRegionsMask[elm] & (1U << bit)) == 0);
+ MOZ_RELEASE_ASSERT((run->mRegionsMask[elm] & (1U << bit)) == 0,
+ "Double-free?");
run->mRegionsMask[elm] |= (1U << bit);
#undef SIZE_INV
#undef SIZE_INV_SHIFT
}
bool
arena_t::SplitRun(arena_run_t* aRun, size_t aSize, bool aLarge, bool aZero)
{
@@ -3492,17 +3493,17 @@ arena_dalloc(void* aPtr, size_t aOffset,
auto arena = chunk->arena;
MOZ_ASSERT(arena);
MOZ_DIAGNOSTIC_ASSERT(arena->mMagic == ARENA_MAGIC);
MOZ_RELEASE_ASSERT(!aArena || arena == aArena);
MutexAutoLock lock(arena->mLock);
size_t pageind = aOffset >> gPageSize2Pow;
arena_chunk_map_t* mapelm = &chunk->map[pageind];
- MOZ_DIAGNOSTIC_ASSERT((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0);
+ MOZ_RELEASE_ASSERT((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0, "Double-free?");
if ((mapelm->bits & CHUNK_MAP_LARGE) == 0) {
// Small allocation.
arena->DallocSmall(chunk, aPtr, mapelm);
} else {
// Large allocation.
arena->DallocLarge(chunk, aPtr);
}
}
@@ -3891,17 +3892,17 @@ huge_dalloc(void* aPtr, arena_t* aArena)
extent_node_t* node;
{
extent_node_t key;
MutexAutoLock lock(huge_mtx);
// Extract from tree of huge allocations.
key.mAddr = aPtr;
node = huge.Search(&key);
- MOZ_ASSERT(node);
+ MOZ_RELEASE_ASSERT(node, "Double-free?");
MOZ_ASSERT(node->mAddr == aPtr);
MOZ_RELEASE_ASSERT(!aArena || node->mArena == aArena);
huge.Remove(node);
huge_allocated -= node->mSize;
huge_mapped -= CHUNK_CEILING(node->mSize);
}