Bug 821577 - DMD: Fix hang at start-up on Mac. r=jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 13 Dec 2012 19:42:47 -0800
changeset 125304 e082861f545f96949f4afa0aeaccddd798fd300c
parent 125303 e5fddab2f19e10b86fc95d5a273e5bbbd7680adc
child 125305 c9d3089866cf1cee0b518b68cb5652cb51f9b2df
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs821577
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 821577 - DMD: Fix hang at start-up on Mac. r=jlebar.
memory/replace/dmd/DMD.cpp
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -1632,16 +1632,23 @@ BadArg(const char* aArg)
   StatusMsg("  --sample-below=<1..%d> Sample blocks smaller than this [%d]\n"
             "                         (prime numbers recommended).\n",
             int(gMaxSampleBelowSize), int(gDefaultSampleBelowSize));
   StatusMsg("  --mode=<normal|test|stress>   Which mode to run in? [normal]\n");
   StatusMsg("\n");
   exit(1);
 }
 
+#ifdef XP_MACOSX
+static void
+NopStackWalkCallback(void* aPc, void* aSp, void* aClosure)
+{
+}
+#endif
+
 // Note that fopen() can allocate.
 static FILE*
 OpenTestOrStressFile(const char* aFilename)
 {
   FILE* fp = fopen(aFilename, "w");
   if (!fp) {
     StatusMsg("can't create %s file: %s\n", aFilename, strerror(errno));
     exit(1);
@@ -1724,16 +1731,26 @@ Init(const malloc_table_t* aMallocTable)
       *e = replacedChar;
     }
   }
 
   // Finished parsing $DMD.
 
   StatusMsg("DMD is enabled\n");
 
+#ifdef XP_MACOSX
+  // On Mac OS X we need to call StackWalkInitCriticalAddress() very early
+  // (prior to the creation of any mutexes, apparently) otherwise we can get
+  // hangs when getting stack traces (bug 821577).  But
+  // StackWalkInitCriticalAddress() isn't exported from xpcom/, so instead we
+  // just call NS_StackWalk, because that calls StackWalkInitCriticalAddress().
+  // See the comment above StackWalkInitCriticalAddress() for more details.
+  (void)NS_StackWalk(NopStackWalkCallback, 0, nullptr, 0, nullptr);
+#endif
+
   gStateLock = InfallibleAllocPolicy::new_<Mutex>();
 
   gSmallBlockActualSizeCounter = 0;
 
   DMD_CREATE_TLS_INDEX(gTlsIndex);
 
   gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
   gStackTraceTable->init(8192);