Bug 1300900 - Add a helper around jemalloc_ptr_info for debuggers. r?njn draft
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 25 Oct 2017 08:01:41 +0900
changeset 686449 05379a223b4533db0628f0a5d146ca276e633f54
parent 686335 a97fb1c39d51a7337b46957bde4273bd308b796a
child 686556 205648c2ec5942793ba1de1fc0f8d7a00183674a
push id86197
push userbmo:mh+mozilla@glandium.org
push dateWed, 25 Oct 2017 22:07:34 +0000
reviewersnjn
bugs1300900
milestone58.0a1
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
memory/build/mozjemalloc.cpp
--- 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;
 }