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.
--- 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.