Bug 1175975 - Null crash fix in ProcessHangMonitor (r=jimm)

This commit is contained in:
Bill McCloskey 2015-06-18 13:10:46 -07:00
parent 5e87ffa029
commit 5a3098de24
4 changed files with 31 additions and 16 deletions

View File

@ -156,7 +156,7 @@ public:
NS_IMETHOD IsReportForBrowser(nsIFrameLoader* aFrameLoader, bool* aResult) override;
// Called on xpcom shutdown
// Called when a content process shuts down.
void Clear() {
mContentParent = nullptr;
mActor = nullptr;
@ -456,11 +456,25 @@ HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor)
mReportHangs = mozilla::Preferences::GetBool("dom.ipc.reportProcessHangs", false);
}
static PLDHashOperator
DeleteMinidump(const uint32_t& aPluginId, nsString aCrashId, void* aUserData)
{
#ifdef MOZ_CRASHREPORTER
if (!aCrashId.IsEmpty()) {
CrashReporter::DeleteMinidumpFilesForID(aCrashId);
}
#endif
return PL_DHASH_NEXT;
}
HangMonitorParent::~HangMonitorParent()
{
// For some reason IPDL doesn't autmatically delete the channel for a
// bridged protocol (bug 1090570). So we have to do it ourselves.
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(GetTransport()));
MutexAutoLock lock(mBrowserCrashDumpHashLock);
mBrowserCrashDumpIds.EnumerateRead(DeleteMinidump, nullptr);
}
void
@ -805,7 +819,9 @@ HangMonitoredProcess::TerminatePlugin()
uint32_t id = mHangData.get_PluginHangData().pluginId();
plugins::TerminatePlugin(id, mBrowserDumpId);
mActor->CleanupPluginHang(id, false);
if (mActor) {
mActor->CleanupPluginHang(id, false);
}
return NS_OK;
}
@ -818,7 +834,7 @@ HangMonitoredProcess::TerminateProcess()
return NS_ERROR_UNEXPECTED;
}
if (mHangData.type() == HangData::TPluginHangData) {
if (mActor && mHangData.type() == HangData::TPluginHangData) {
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
}
@ -855,8 +871,10 @@ HangMonitoredProcess::UserCanceled()
return NS_OK;
}
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
if (mActor) {
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
}
return NS_OK;
}

View File

@ -353,8 +353,7 @@ PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse)
int responseCode;
if (aResponse & HANGUI_USER_RESPONSE_STOP) {
// User clicked Stop
nsString dummy;
mModule->TerminateChildProcess(mMainThreadMessageLoop, &dummy);
mModule->TerminateChildProcess(mMainThreadMessageLoop, EmptyString());
responseCode = 1;
} else if(aResponse & HANGUI_USER_RESPONSE_CONTINUE) {
mModule->OnHangUIContinue();

View File

@ -359,10 +359,9 @@ mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDu
if (!pluginTag || !pluginTag->mPlugin) {
return;
}
nsAutoString dumpId(aBrowserDumpId);
nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
chromeParent->TerminateChildProcess(MessageLoop::current(), &dumpId);
chromeParent->TerminateChildProcess(MessageLoop::current(), aBrowserDumpId);
}
/* static */ PluginLibrary*
@ -1154,8 +1153,7 @@ PluginModuleChromeParent::ShouldContinueFromReplyTimeout()
// original plugin hang behaviour and kill the plugin container.
FinishHangUI();
#endif // XP_WIN
nsString dummy;
TerminateChildProcess(MessageLoop::current(), &dummy);
TerminateChildProcess(MessageLoop::current(), EmptyString());
GetIPCChannel()->CloseWithTimeout();
return false;
}
@ -1179,7 +1177,7 @@ PluginModuleContentParent::OnExitedSyncSend()
void
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
nsAString* aBrowserDumpId)
const nsAString& aBrowserDumpId)
{
#ifdef MOZ_CRASHREPORTER
#ifdef XP_WIN
@ -1215,8 +1213,8 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
// since the posted message will trash our browser stack state.
bool exists;
nsCOMPtr<nsIFile> browserDumpFile;
if (aBrowserDumpId && !aBrowserDumpId->IsEmpty() &&
CrashReporter::GetMinidumpForID(*aBrowserDumpId, getter_AddRefs(browserDumpFile)) &&
if (!aBrowserDumpId.IsEmpty() &&
CrashReporter::GetMinidumpForID(aBrowserDumpId, getter_AddRefs(browserDumpFile)) &&
browserDumpFile &&
NS_SUCCEEDED(browserDumpFile->Exists(&exists)) && exists)
{
@ -1226,7 +1224,7 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
NS_LITERAL_CSTRING("browser"));
if (!reportsReady) {
browserDumpFile = nullptr;
CrashReporter::DeleteMinidumpFilesForID(*aBrowserDumpId);
CrashReporter::DeleteMinidumpFilesForID(aBrowserDumpId);
}
}

View File

@ -387,7 +387,7 @@ class PluginModuleChromeParent
* generating a multi-process crash report. If not provided a browser
* dump will be taken at the time of this call.
*/
void TerminateChildProcess(MessageLoop* aMsgLoop, nsAString* aBrowserDumpId);
void TerminateChildProcess(MessageLoop* aMsgLoop, const nsAString& aBrowserDumpId);
#ifdef XP_WIN
/**