Bug 1300900 - Add a helper around jemalloc_ptr_info for debuggers. r?njn
jemalloc_ptr_info takes an outparam, which makes it harder to use in a
debugger: you'd need to find some memory to use as outparam and pass
that in.
So for convenience, we add a non-exported symbol for use in debuggers,
which just returns a pointer to a static buffer for the result.
lldb:
(lldb) print *Debug::jemalloc_ptr_info($0)
(jemalloc_ptr_info_t) $1 = (tag = TagLiveSmall, addr=0x000000011841dd80, size = 160)
gdb:
(gdb) print *Debug::jemalloc_ptr_info($0)
$1 = {tag = TagLiveSmall, addr = 0x7f8e7ebd0dc0, size = 96}
windbg:
0:040> .call Debug::jemalloc_ptr_info(0x6187880)
Thread is set up for call, 'g' will execute.
WARNING: This can have serious side-effects,
including deadlocks and corruption of the debuggee.
0:040> g
.call returns:
struct jemalloc_ptr_info_t * 0x7501f3f4
+0x000 tag : 1 ( TagLiveSmall )
+0x004 addr : 0x06187880 Void
+0x008 size : 0x20
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -3576,16 +3576,28 @@ MozJemalloc::jemalloc_ptr_info(const voi
unsigned elm = regind >> (SIZEOF_INT_2POW + 3);
unsigned bit = regind - (elm << (SIZEOF_INT_2POW + 3));
PtrInfoTag tag = ((run->regs_mask[elm] & (1U << bit)))
? TagFreedSmall : TagLiveSmall;
*aInfo = { tag, addr, size};
}
+namespace Debug
+{
+ // Helper for debuggers. We don't want it to be inlined and optimized out.
+ MOZ_NEVER_INLINE jemalloc_ptr_info_t*
+ jemalloc_ptr_info(const void* aPtr)
+ {
+ static jemalloc_ptr_info_t info;
+ MozJemalloc::jemalloc_ptr_info(aPtr, &info);
+ return &info;
+ }
+}
+
void
arena_t::DallocSmall(arena_chunk_t* aChunk, void* aPtr, arena_chunk_map_t* aMapElm)
{
arena_run_t* run;
arena_bin_t* bin;
size_t size;
run = (arena_run_t*)(aMapElm->bits & ~pagesize_mask);
@@ -4402,16 +4414,19 @@ MALLOC_OUT:
thread_arena.set(gMainArena);
if (!gChunkRTree.Init()) {
return true;
}
malloc_initialized = true;
+ // Dummy call so that the function is not removed by dead-code elimination
+ Debug::jemalloc_ptr_info(nullptr);
+
#if !defined(XP_WIN) && !defined(XP_DARWIN)
/* Prevent potential deadlock on malloc locks after fork. */
pthread_atfork(_malloc_prefork, _malloc_postfork_parent, _malloc_postfork_child);
#endif
return false;
}