Bug 1113416 - Don't read stack labels inside hang monitor sighandler; r=nfroyd r=snorp
authorJim Chen <nchen@mozilla.com>
Sat, 10 Jan 2015 12:41:48 -0500
changeset 223185 6cbf0b1ec001b3a26f1c83347b70cef858311adf
parent 223184 ab841f36d62f699d04853b7cc613bc27845a4760
child 223186 d3e8e73bafdebd002ffc69a9684c93ac3718ecbe
push id10769
push usercbook@mozilla.com
push dateMon, 12 Jan 2015 14:15:52 +0000
treeherderfx-team@0e9765732906 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd, snorp
bugs1113416
milestone37.0a1
Bug 1113416 - Don't read stack labels inside hang monitor sighandler; r=nfroyd r=snorp When we're inside the hang monitor's signal handler, we must not read any string labels. Doing so may result in on-demand decompression kicking in on Android, which may result in a deadlock.
xpcom/threads/BackgroundHangMonitor.cpp
xpcom/threads/ThreadStackHelper.cpp
--- a/xpcom/threads/BackgroundHangMonitor.cpp
+++ b/xpcom/threads/BackgroundHangMonitor.cpp
@@ -355,16 +355,23 @@ BackgroundHangThread::~BackgroundHangThr
 }
 
 Telemetry::HangHistogram&
 BackgroundHangThread::ReportHang(PRIntervalTime aHangTime)
 {
   // Recovered from a hang; called on the monitor thread
   // mManager->mLock IS locked
 
+  // Remove unwanted "js::RunScript" frame from the stack
+  for (const char** f = &mHangStack.back(); f >= mHangStack.begin(); f--) {
+    if (!mHangStack.IsInBuffer(*f) && !strcmp(*f, "js::RunScript")) {
+      mHangStack.erase(f);
+    }
+  }
+
   Telemetry::HangHistogram newHistogram(Move(mHangStack));
   for (Telemetry::HangHistogram* oldHistogram = mStats.mHangs.begin();
        oldHistogram != mStats.mHangs.end(); oldHistogram++) {
     if (newHistogram == *oldHistogram) {
       // New histogram matches old one
       oldHistogram->Add(aHangTime);
       return *oldHistogram;
     }
--- a/xpcom/threads/ThreadStackHelper.cpp
+++ b/xpcom/threads/ThreadStackHelper.cpp
@@ -668,20 +668,18 @@ ThreadStackHelper::FillStackBuffer()
       continue;
     }
 #ifdef MOZ_THREADSTACKHELPER_NATIVE
     if (mContextToFill) {
       mContextToFill->mStackEnd = entry->stackAddress();
     }
 #endif
     const char* const label = entry->label();
-    if (mStackToFill->IsSameAsEntry(prevLabel, label) ||
-        !strcmp(label, "js::RunScript")) {
+    if (mStackToFill->IsSameAsEntry(prevLabel, label)) {
       // Avoid duplicate labels to save space in the stack.
-      // Avoid js::RunScript labels because we save actual JS frames above.
       continue;
     }
     mStackToFill->infallibleAppend(label);
     prevLabel = label;
   }
 
   // end != entry if we exited early due to not enough reserved frames.
   // Expand the number of reserved frames for next time.