void HangMonitorParent::SendHangNotification(const HangData& aHangData, const nsString& aBrowserDumpId, bool aTakeMinidump) { // chrome process, main thread MOZ_RELEASE_ASSERT(NS_IsMainThread()); nsString dumpId; if ((aHangData.type() == HangData::TPluginHangData) && aTakeMinidump) { // We've been handed a partial minidump; complete it with plugin and // content process dumps. const PluginHangData& phd = aHangData.get_PluginHangData(); plugins::TakeFullMinidump(phd.pluginId(), phd.contentProcessId(), aBrowserDumpId, dumpId); UpdateMinidump(phd.pluginId(), dumpId); } else { // We already have a full minidump; go ahead and use it. dumpId = aBrowserDumpId; } mProcess->SetHangData(aHangData, dumpId); nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); observerService->NotifyObservers(mProcess, "process-hang-report", nullptr); }
bool HangMonitorParent::RecvHangEvidence(const HangData& aHangData) { // chrome process, background thread MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); if (!mReportHangs) { return true; } #ifdef XP_WIN // Don't report hangs if we're debugging the process. You can comment this // line out for testing purposes. if (IsDebuggerPresent()) { return true; } #endif // Before we wake up the browser main thread we want to take a // browser minidump. nsAutoString crashId; #ifdef MOZ_CRASHREPORTER if (aHangData.type() == HangData::TPluginHangData) { MutexAutoLock lock(mBrowserCrashDumpHashLock); const PluginHangData& phd = aHangData.get_PluginHangData(); if (!mBrowserCrashDumpIds.Get(phd.pluginId(), &crashId)) { nsCOMPtr<nsIFile> browserDump; if (CrashReporter::TakeMinidump(getter_AddRefs(browserDump), true)) { if (!CrashReporter::GetIDFromMinidump(browserDump, crashId) || crashId.IsEmpty()) { browserDump->Remove(false); NS_WARNING("Failed to generate timely browser stack, this is bad for plugin hang analysis!"); } else { mBrowserCrashDumpIds.Put(phd.pluginId(), crashId); } } } } #endif mHangMonitor->InitiateCPOWTimeout(); MonitorAutoLock lock(mMonitor); nsCOMPtr<nsIRunnable> notifier = new HangObserverNotifier(mProcess, aHangData, crashId); NS_DispatchToMainThread(notifier); return true; }
mozilla::ipc::IPCResult HangMonitorParent::RecvHangEvidence(const HangData& aHangData) { // chrome process, background thread MOZ_RELEASE_ASSERT(IsOnThread()); if (!mReportHangs) { return IPC_OK(); } #ifdef XP_WIN // Don't report hangs if we're debugging the process. You can comment this // line out for testing purposes. if (IsDebuggerPresent()) { return IPC_OK(); } #endif // Before we wake up the browser main thread we want to take a // browser minidump. nsAutoString crashId; bool takeMinidump = false; if (aHangData.type() == HangData::TPluginHangData) { takeMinidump = TakeBrowserMinidump(aHangData.get_PluginHangData(), crashId); } mHangMonitor->InitiateCPOWTimeout(); MonitorAutoLock lock(mMonitor); NS_DispatchToMainThread( mMainThreadTaskFactory.NewRunnableMethod( &HangMonitorParent::SendHangNotification, aHangData, crashId, takeMinidump)); return IPC_OK(); }
bool HangMonitorParent::RecvHangEvidence(const HangData& aHangData) { // chrome process, background thread MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); if (!mReportHangs) { return true; } #ifdef XP_WIN // Don't report hangs if we're debugging the process. You can comment this // line out for testing purposes. if (IsDebuggerPresent()) { return true; } #endif // Before we wake up the browser main thread we want to take a // browser minidump. nsAutoString crashId; bool takeMinidump = false; if (aHangData.type() == HangData::TPluginHangData) { takeMinidump = TakeBrowserMinidump(aHangData.get_PluginHangData(), crashId); } mHangMonitor->InitiateCPOWTimeout(); MonitorAutoLock lock(mMonitor); nsCOMPtr<nsIRunnable> notifier = new HangObserverNotifier(mProcess, this, aHangData, crashId, takeMinidump); NS_DispatchToMainThread(notifier); return true; }