Bug 821577 - DMD: Fix hang at start-up on Mac. r+a=jlebar
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 13 Dec 2012 19:42:47 -0800
changeset 122922 2c8991f63c211d51cdcd285c42d1e6db7a80f8ce
parent 122921 c6671a6c79158215465ef41d23e71e1408e8b091
child 122923 4694ea14a8f43a3a60b4d1d374ad056e6af26928
push id273
push userlsblakk@mozilla.com
push dateThu, 14 Feb 2013 23:19:38 +0000
treeherdermozilla-release@c5e807a3f8b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs821577
milestone19.0a2
Bug 821577 - DMD: Fix hang at start-up on Mac. r+a=jlebar
memory/replace/dmd/DMD.cpp
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -1435,16 +1435,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);
@@ -1527,16 +1534,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);