From cb8c3ea7503ad25bd22466e3853c0e56a22301ad Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Fri, 16 Jan 2015 14:46:05 -0800 Subject: [PATCH] Backout bug 1118618 on a CLOSED TREE --- browser/app/profile/firefox.js | 10 +- browser/base/content/browser.js | 3 - browser/base/content/browser.xul | 20 - browser/base/content/tabbrowser.xml | 4 - browser/components/nsBrowserGlue.js | 5 - browser/devtools/framework/gDevTools.jsm | 44 +- .../locales/en-US/chrome/browser/browser.dtd | 8 - .../en-US/chrome/browser/browser.properties | 5 - browser/modules/ProcessHangMonitor.jsm | 309 ------ browser/modules/moz.build | 1 - dom/base/SlowScriptDebug.js | 3 - dom/base/nsGlobalWindow.cpp | 39 +- dom/base/nsGlobalWindow.h | 1 - dom/base/nsISlowScriptDebug.idl | 15 - dom/ipc/ContentChild.cpp | 8 - dom/ipc/ContentChild.h | 4 - dom/ipc/ContentParent.cpp | 21 +- dom/ipc/ContentParent.h | 6 - dom/ipc/PContent.ipdl | 2 - dom/ipc/PProcessHangMonitor.ipdl | 42 - dom/ipc/ProcessHangMonitor.cpp | 954 ------------------ dom/ipc/ProcessHangMonitor.h | 78 -- dom/ipc/ProcessHangMonitorIPC.h | 34 - dom/ipc/moz.build | 10 - dom/ipc/nsIHangReport.idl | 66 -- dom/plugins/base/nsPluginHost.h | 3 +- dom/plugins/ipc/PluginBridge.h | 3 - dom/plugins/ipc/PluginModuleParent.cpp | 64 +- dom/plugins/ipc/PluginModuleParent.h | 17 +- ipc/glue/MessageChannel.cpp | 15 +- ipc/glue/MessageChannel.h | 8 - ipc/glue/MessageLink.h | 5 - js/xpconnect/src/XPCJSRuntime.cpp | 24 +- modules/libpref/init/all.js | 5 - .../client/marionette/geckoinstance.py | 3 +- testing/profiles/prefs_general.js | 2 - 36 files changed, 38 insertions(+), 1803 deletions(-) delete mode 100644 browser/modules/ProcessHangMonitor.jsm delete mode 100644 dom/ipc/PProcessHangMonitor.ipdl delete mode 100644 dom/ipc/ProcessHangMonitor.cpp delete mode 100644 dom/ipc/ProcessHangMonitor.h delete mode 100644 dom/ipc/ProcessHangMonitorIPC.h delete mode 100644 dom/ipc/nsIHangReport.idl diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index d222d2e61149..14f6ac7ce3e8 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1803,11 +1803,5 @@ pref("extensions.interposition.prefetching", true); pref("browser.defaultbrowser.notificationbar", false); -// How often to check for CPOW timeouts. CPOWs are only timed out by -// the hang monitor. -pref("dom.ipc.cpow.timeout", 500); - -// Enable e10s hang monitoring (slow script checking and plugin hang -// detection). -pref("dom.ipc.processHangMonitor", true); -pref("dom.ipc.reportProcessHangs", true); +// How many milliseconds to wait for a CPOW response from the child process. +pref("dom.ipc.cpow.timeout", 0); diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index b7781a58708e..ca9db831b348 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -149,9 +149,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Social", XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", "resource://gre/modules/PageThumbs.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "ProcessHangMonitor", - "resource:///modules/ProcessHangMonitor.jsm"); - #ifdef MOZ_SAFE_BROWSING XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", "resource://gre/modules/SafeBrowsing.jsm"); diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 8afeecd913ba..a42f415bf87b 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -334,26 +334,6 @@ orient="horizontal" hidden="true"/> - - - - - - - diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index a4e2fc761b57..45aa791b8107 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -59,9 +59,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "CustomizationTabPreloader", XPCOMUtils.defineLazyModuleGetter(this, "PdfJs", "resource://pdf.js/PdfJs.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "ProcessHangMonitor", - "resource:///modules/ProcessHangMonitor.jsm"); - #ifdef NIGHTLY_BUILD XPCOMUtils.defineLazyModuleGetter(this, "ShumwayUtils", "resource://shumway/ShumwayUtils.jsm"); @@ -763,8 +760,6 @@ BrowserGlue.prototype = { } #endif - ProcessHangMonitor.init(); - // A channel for "remote troubleshooting" code... let channel = new WebChannel("remote-troubleshooting", "remote-troubleshooting"); channel.listen((id, data, target) => { diff --git a/browser/devtools/framework/gDevTools.jsm b/browser/devtools/framework/gDevTools.jsm index 2db3bbfd3a9a..968aefcf2eef 100644 --- a/browser/devtools/framework/gDevTools.jsm +++ b/browser/devtools/framework/gDevTools.jsm @@ -854,9 +854,17 @@ let gDevToolsBrowser = { .getService(Ci.nsISlowScriptDebug); let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); - function slowScriptDebugHandler(aTab, aCallback) { - let target = devtools.TargetFactory.forTab(aTab); + debugService.activationHandler = function(aWindow) { + let chromeWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow) + .QueryInterface(Ci.nsIDOMChromeWindow); + let target = devtools.TargetFactory.forTab(chromeWindow.gBrowser.selectedTab); + let setupFinished = false; gDevTools.showToolbox(target, "jsdebugger").then(toolbox => { let threadClient = toolbox.getCurrentPanel().panelWin.gThreadClient; @@ -866,13 +874,13 @@ let gDevToolsBrowser = { case "paused": // When the debugger is already paused. threadClient.breakOnNext(); - aCallback(); + setupFinished = true; break; case "attached": // When the debugger is already open. threadClient.interrupt(() => { threadClient.breakOnNext(); - aCallback(); + setupFinished = true; }); break; case "resuming": @@ -880,7 +888,7 @@ let gDevToolsBrowser = { threadClient.addOneTimeListener("resumed", () => { threadClient.interrupt(() => { threadClient.breakOnNext(); - aCallback(); + setupFinished = true; }); }); break; @@ -889,20 +897,6 @@ let gDevToolsBrowser = { threadClient.state); } }); - } - - debugService.activationHandler = function(aWindow) { - let chromeWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .QueryInterface(Ci.nsIDOMChromeWindow); - - let setupFinished = false; - slowScriptDebugHandler(chromeWindow.gBrowser.selectedTab, - () => { setupFinished = true; }); // Don't return from the interrupt handler until the debugger is brought // up; no reason to continue executing the slow script. @@ -914,18 +908,6 @@ let gDevToolsBrowser = { } utils.leaveModalState(); }; - - debugService.remoteActivationHandler = function(aBrowser, aCallback) { - let chromeWindow = aBrowser.ownerDocument.defaultView; - let tab = chromeWindow.gBrowser.getTabForBrowser(aBrowser); - chromeWindow.gBrowser.selected = tab; - - function callback() { - aCallback.finishDebuggerStartup(); - } - - slowScriptDebugHandler(tab, callback); - }; }, /** diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index 0553b443f669..5ed0a3ea5370 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -831,11 +831,3 @@ just addresses the organization to follow, e.g. "This site is run by " --> - - - - - - - - diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 77f669108c1d..8e37b09fa73c 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -435,11 +435,6 @@ dataReportingNotification.message = %1$S automatically sends some data to dataReportingNotification.button.label = Choose What I Share dataReportingNotification.button.accessKey = C -# Process hang reporter -processHang.message = A web page is causing %1$S to run slowly. What would you like to do? -processHang.button.label = Options -processHang.button.accessKey = O - # Webapps notification popup webapps.install = Install webapps.install.accesskey = I diff --git a/browser/modules/ProcessHangMonitor.jsm b/browser/modules/ProcessHangMonitor.jsm deleted file mode 100644 index 6213e11febdb..000000000000 --- a/browser/modules/ProcessHangMonitor.jsm +++ /dev/null @@ -1,309 +0,0 @@ -/* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; - -this.EXPORTED_SYMBOLS = ["ProcessHangMonitor"]; - -Cu.import("resource://gre/modules/Services.jsm"); - -/** - * This JSM is responsible for observing content process hang reports - * and asking the user what to do about them. See nsIHangReport for - * the platform interface. - */ - -/** - * If a hang hasn't been reported for more than 5 seconds, assume the - * content process has gotten unstuck (and hide the hang notification). - */ -const HANG_EXPIRATION_TIME = 5000; - -let ProcessHangMonitor = { - /** - * Collection of hang reports that haven't expired or been dismissed - * by the user. The keys are nsIHangReports and values keys are - * timers. Each time the hang is reported, the timer is refreshed so - * it expires after HANG_EXPIRATION_TIME. - */ - _activeReports: new Map(), - - /** - * Initialize hang reporting. Called once in the parent process. - */ - init: function() { - Services.obs.addObserver(this, "process-hang-report", false); - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.ww.registerNotification(this); - }, - - /** - * Terminate JavaScript associated with the hang being reported for - * the selected browser in |win|. - */ - terminateScript: function(win) { - this.handleUserInput(win, report => report.terminateScript()); - }, - - /** - * Start devtools debugger for JavaScript associated with the hang - * being reported for the selected browser in |win|. - */ - debugScript: function(win) { - this.handleUserInput(win, report => { - function callback() { - report.endStartingDebugger(); - } - - report.beginStartingDebugger(); - - let svc = Cc["@mozilla.org/dom/slow-script-debug;1"].getService(Ci.nsISlowScriptDebug); - let handler = svc.remoteActivationHandler; - handler.handleSlowScriptDebug(report.scriptBrowser, callback); - }); - }, - - /** - * Kill the plugin process causing the hang being reported for the - * selected browser in |win|. - */ - terminatePlugin: function(win) { - this.handleUserInput(win, report => report.terminatePlugin()); - }, - - /** - * Kill the content process causing the hang being reported for the selected - * browser in |win|. - */ - terminateProcess: function(win) { - this.handleUserInput(win, report => report.terminateProcess()); - }, - - /** - * Update the "Options" pop-up menu for the hang notification - * associated with the selected browser in |win|. The menu should - * display only options that are relevant to the given report. - */ - refreshMenu: function(win) { - let report = this.findReport(win.gBrowser.selectedBrowser); - if (!report) { - return; - } - - function setVisible(id, visible) { - let item = win.document.getElementById(id); - item.hidden = !visible; - } - - if (report.hangType == report.SLOW_SCRIPT) { - setVisible("processHangTerminateScript", true); - setVisible("processHangDebugScript", true); - setVisible("processHangTerminatePlugin", false); - } else if (report.hangType == report.PLUGIN_HANG) { - setVisible("processHangTerminateScript", false); - setVisible("processHangDebugScript", false); - setVisible("processHangTerminatePlugin", true); - } - }, - - /** - * If there is a hang report associated with the selected browser in - * |win|, invoke |func| on that report and stop notifying the user - * about it. - */ - handleUserInput: function(win, func) { - let report = this.findReport(win.gBrowser.selectedBrowser); - if (!report) { - return; - } - this.removeReport(report); - - return func(report); - }, - - observe: function(subject, topic, data) { - switch (topic) { - case "xpcom-shutdown": - Services.obs.removeObserver(this, "xpcom-shutdown"); - Services.obs.removeObserver(this, "process-hang-report"); - Services.ww.unregisterNotification(this); - break; - - case "process-hang-report": - this.reportHang(subject.QueryInterface(Ci.nsIHangReport)); - break; - - case "domwindowopened": - // Install event listeners on the new window in case one of - // its tabs is already hung. - let win = subject.QueryInterface(Ci.nsIDOMWindow); - let listener = (ev) => { - win.removeEventListener("load", listener, true); - this.updateWindows(); - }; - win.addEventListener("load", listener, true); - break; - } - }, - - /** - * Find any active hang reports for the given element. - */ - findReport: function(browser) { - let frameLoader = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader; - for (let [report, timer] of this._activeReports) { - if (report.isReportForBrowser(frameLoader)) { - return report; - } - } - return null; - }, - - /** - * Iterate over all XUL windows and ensure that the proper hang - * reports are shown for each one. Also install event handlers in - * each window to watch for events that would cause a different hang - * report to be displayed. - */ - updateWindows: function() { - let e = Services.wm.getEnumerator("navigator:browser"); - while (e.hasMoreElements()) { - let win = e.getNext(); - - this.updateWindow(win); - - // Only listen for these events if there are active hang reports. - if (this._activeReports.size) { - this.trackWindow(win); - } else { - this.untrackWindow(win); - } - } - }, - - /** - * If there is a hang report for the current tab in |win|, display it. - */ - updateWindow: function(win) { - let report = this.findReport(win.gBrowser.selectedBrowser); - - if (report) { - this.showNotification(win, report); - } else { - this.hideNotification(win); - } - }, - - /** - * Show the notification for a hang. - */ - showNotification: function(win, report) { - let nb = win.document.getElementById("high-priority-global-notificationbox"); - let notification = nb.getNotificationWithValue("process-hang"); - if (notification) { - return; - } - - let bundle = win.gNavigatorBundle; - let brandBundle = win.document.getElementById("bundle_brand"); - let appName = brandBundle.getString("brandShortName"); - let message = bundle.getFormattedString( - "processHang.message", - [appName]); - - let buttons = [{ - label: bundle.getString("processHang.button.label"), - accessKey: bundle.getString("processHang.button.accessKey"), - popup: "processHangOptions", - callback: null, - }]; - - nb.appendNotification(message, "process-hang", - "chrome://browser/content/aboutRobots-icon.png", - nb.PRIORITY_WARNING_HIGH, buttons); - }, - - /** - * Ensure that no hang notifications are visible in |win|. - */ - hideNotification: function(win) { - let nb = win.document.getElementById("high-priority-global-notificationbox"); - let notification = nb.getNotificationWithValue("process-hang"); - if (notification) { - nb.removeNotification(notification); - } - }, - - /** - * Install event handlers on |win| to watch for events that would - * cause a different hang report to be displayed. - */ - trackWindow: function(win) { - win.gBrowser.tabContainer.addEventListener("TabSelect", this, true); - win.gBrowser.tabContainer.addEventListener("TabRemotenessChange", this, true); - }, - - untrackWindow: function(win) { - win.gBrowser.tabContainer.removeEventListener("TabSelect", this, true); - win.gBrowser.tabContainer.removeEventListener("TabRemotenessChange", this, true); - }, - - handleEvent: function(event) { - let win = event.target.ownerDocument.defaultView; - - // If a new tab is selected or if a tab changes remoteness, then - // we may need to show or hide a hang notification. - - if (event.type == "TabSelect" || event.type == "TabRemotenessChange") { - this.updateWindow(win); - } - }, - - /** - * Handle a potentially new hang report. If it hasn't been seen - * before, show a notification for it in all open XUL windows. - */ - reportHang: function(report) { - // If this hang was already reported, then reset the timer for it. - if (this._activeReports.has(report)) { - let timer = this._activeReports.get(report); - timer.cancel(); - timer.initWithCallback(this, HANG_EXPIRATION_TIME, timer.TYPE_ONE_SHOT); - return; - } - - // Otherwise create a new timer and display the report. - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback(this, HANG_EXPIRATION_TIME, timer.TYPE_ONE_SHOT); - - this._activeReports.set(report, timer); - this.updateWindows(); - }, - - /** - * Dismiss a hang report because the user closed the notification - * for it or the report expired. - */ - removeReport: function(report) { - this._activeReports.delete(report); - this.updateWindows(); - }, - - /** - * Callback for when HANG_EXPIRATION_TIME has elapsed. - */ - notify: function(timer) { - for (let [otherReport, otherTimer] of this._activeReports) { - if (otherTimer === timer) { - this.removeReport(otherReport); - break; - } - } - }, -}; diff --git a/browser/modules/moz.build b/browser/modules/moz.build index 96501ed48baa..74d81611c9b9 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -27,7 +27,6 @@ EXTRA_JS_MODULES += [ 'NetworkPrioritizer.jsm', 'offlineAppCache.jsm', 'PanelFrame.jsm', - 'ProcessHangMonitor.jsm', 'RemotePrompt.jsm', 'SitePermissions.jsm', 'Social.jsm', diff --git a/dom/base/SlowScriptDebug.js b/dom/base/SlowScriptDebug.js index 296889d7b909..c9603abe2aee 100644 --- a/dom/base/SlowScriptDebug.js +++ b/dom/base/SlowScriptDebug.js @@ -16,9 +16,6 @@ SlowScriptDebug.prototype = { get activationHandler() { return this._activationHandler; }, set activationHandler(cb) { return this._activationHandler = cb; }, - - get remoteActivationHandler() { return this._remoteActivationHandler; }, - set remoteActivationHandler(cb) { return this._remoteActivationHandler = cb; }, }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SlowScriptDebug]); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1daf5fb553cb..07735ae5e6f2 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -67,7 +67,6 @@ #include "mozilla/EventListenerManager.h" #include "mozilla/EventStates.h" #include "mozilla/MouseEvents.h" -#include "mozilla/ProcessHangMonitor.h" #include "AudioChannelService.h" #include "MessageEvent.h" #include "nsAboutProtocolUtils.h" @@ -10970,45 +10969,17 @@ nsGlobalWindow::ShowSlowScriptDialog() return KillSlowScript; } - // Check if we should offer the option to debug - JS::AutoFilename filename; - unsigned lineno; - bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno); - - if (XRE_GetProcessType() == GeckoProcessType_Content && - ProcessHangMonitor::Get()) { - ProcessHangMonitor::SlowScriptAction action; - nsRefPtr monitor = ProcessHangMonitor::Get(); - nsCOMPtr child = do_GetInterface(GetDocShell()); - action = monitor->NotifySlowScript(child, - filename.get(), - lineno); - if (action == ProcessHangMonitor::Terminate) { - return KillSlowScript; - } - - if (action == ProcessHangMonitor::StartDebugger) { - // Spin a nested event loop so that the debugger in the parent can fetch - // any information it needs. Once the debugger has started, return to the - // script. - nsRefPtr outer = GetOuterWindowInternal(); - outer->EnterModalState(); - while (!monitor->IsDebuggerStartupComplete()) { - NS_ProcessNextEvent(nullptr, true); - } - outer->LeaveModalState(); - return ContinueSlowScript; - } - - return ContinueSlowScriptAndKeepNotifying; - } - // Get the nsIPrompt interface from the docshell nsCOMPtr ds = GetDocShell(); NS_ENSURE_TRUE(ds, KillSlowScript); nsCOMPtr prompt = do_GetInterface(ds); NS_ENSURE_TRUE(prompt, KillSlowScript); + // Check if we should offer the option to debug + JS::AutoFilename filename; + unsigned lineno; + bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno); + // Prioritize the SlowScriptDebug interface over JSD1. nsCOMPtr debugCallback; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 731b1390887c..c9cd5bc49119 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -726,7 +726,6 @@ public: enum SlowScriptResponse { ContinueSlowScript = 0, - ContinueSlowScriptAndKeepNotifying, AlwaysContinueSlowScript, KillSlowScript }; diff --git a/dom/base/nsISlowScriptDebug.idl b/dom/base/nsISlowScriptDebug.idl index 2248b69cac6a..91e91086f332 100644 --- a/dom/base/nsISlowScriptDebug.idl +++ b/dom/base/nsISlowScriptDebug.idl @@ -5,7 +5,6 @@ #include "nsISupports.idl" interface nsIDOMWindow; -interface nsIDOMEventTarget; [scriptable, function, uuid(f7dbb80c-5d1e-4fd9-b55c-a9ffda4a75b1)] interface nsISlowScriptDebugCallback : nsISupports @@ -13,22 +12,8 @@ interface nsISlowScriptDebugCallback : nsISupports void handleSlowScriptDebug(in nsIDOMWindow aWindow); }; -[scriptable, function, uuid(b1c6ecd0-8fa4-11e4-b4a9-0800200c9a66)] -interface nsISlowScriptDebugerStartupCallback : nsISupports -{ - void finishDebuggerStartup(); -}; - -[scriptable, function, uuid(dbee14b0-8fa0-11e4-b4a9-0800200c9a66)] -interface nsISlowScriptDebugRemoteCallback : nsISupports -{ - void handleSlowScriptDebug(in nsIDOMEventTarget aBrowser, - in nsISlowScriptDebugerStartupCallback aCallback); -}; - [scriptable, uuid(f75d4164-3aa7-4395-ba44-a5f95b2e8427)] interface nsISlowScriptDebug : nsISupports { attribute nsISlowScriptDebugCallback activationHandler; - attribute nsISlowScriptDebugRemoteCallback remoteActivationHandler; }; diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 4df3de573776..4c8f1048b931 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -24,7 +24,6 @@ #include "mozilla/a11y/DocAccessibleChild.h" #endif #include "mozilla/Preferences.h" -#include "mozilla/ProcessHangMonitorIPC.h" #include "mozilla/docshell/OfflineCacheUpdateChild.h" #include "mozilla/dom/ContentBridgeChild.h" #include "mozilla/dom/ContentBridgeParent.h" @@ -1000,13 +999,6 @@ ContentChild::AllocPBackgroundChild(Transport* aTransport, return BackgroundChild::Alloc(aTransport, aOtherProcess); } -PProcessHangMonitorChild* -ContentChild::AllocPProcessHangMonitorChild(Transport* aTransport, - ProcessId aOtherProcess) -{ - return CreateHangMonitorChild(aTransport, aOtherProcess); -} - #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) static void SetUpSandboxEnvironment() diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 0e76e01059ca..1e2e8a37ddc3 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -126,10 +126,6 @@ public: AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport, base::ProcessId aOtherProcess) MOZ_OVERRIDE; - PProcessHangMonitorChild* - AllocPProcessHangMonitorChild(Transport* aTransport, - ProcessId aOtherProcess) MOZ_OVERRIDE; - #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) // Cleans up any resources used by the process when sandboxed. void CleanUpSandboxEnvironment(); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 7ecbf3c5fb33..f7f52a3e3b17 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -73,8 +73,6 @@ #include "mozilla/net/NeckoParent.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/Preferences.h" -#include "mozilla/ProcessHangMonitor.h" -#include "mozilla/ProcessHangMonitorIPC.h" #include "mozilla/Services.h" #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" @@ -1804,11 +1802,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why) // finish waiting in the xpcom-shutdown/profile-before-change observer. mIPCOpen = false; - if (mHangMonitorActor) { - ProcessHangMonitor::RemoveProcess(mHangMonitorActor); - mHangMonitorActor = nullptr; - } - if (why == NormalShutdown && !mCalledClose) { // If we shut down normally but haven't called Close, assume somebody // else called Close on us. In that case, we still need to call @@ -2041,7 +2034,6 @@ ContentParent::InitializeMembers() mCreatedPairedMinidumps = false; mShutdownPending = false; mIPCOpen = true; - mHangMonitorActor = nullptr; } ContentParent::ContentParent(mozIApplication* aApp, @@ -2121,8 +2113,6 @@ ContentParent::ContentParent(mozIApplication* aApp, ContentProcessManager::GetSingleton()->AddContentProcess(this); - ProcessHangMonitor::AddProcess(this); - // Set a reply timeout for CPOWs. SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0)); } @@ -3060,14 +3050,6 @@ ContentParent::AllocPBackgroundParent(Transport* aTransport, return BackgroundParent::Alloc(this, aTransport, aOtherProcess); } -PProcessHangMonitorParent* -ContentParent::AllocPProcessHangMonitorParent(Transport* aTransport, - ProcessId aOtherProcess) -{ - mHangMonitorActor = CreateHangMonitorParent(this, aTransport, aOtherProcess); - return mHangMonitorActor; -} - PSharedBufferManagerParent* ContentParent::AllocPSharedBufferManagerParent(mozilla::ipc::Transport* aTransport, base::ProcessId aOtherProcess) @@ -4317,8 +4299,7 @@ ContentParent::RecvNotifyKeywordSearchLoading(const nsString &aProvider, bool ContentParent::ShouldContinueFromReplyTimeout() { - nsRefPtr monitor = ProcessHangMonitor::Get(); - return !monitor || !monitor->ShouldTimeOutCPOWs(); + return false; } bool diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index c2bb0570586a..4ec30c9035a7 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -485,10 +485,6 @@ private: AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess) MOZ_OVERRIDE; - PProcessHangMonitorParent* - AllocPProcessHangMonitorParent(Transport* aTransport, - ProcessId aOtherProcess) MOZ_OVERRIDE; - virtual bool RecvGetProcessAttributes(ContentParentId* aCpId, bool* aIsForApp, bool* aIsForBrowser) MOZ_OVERRIDE; @@ -843,8 +839,6 @@ private: static int32_t sNuwaPid; static bool sNuwaReady; #endif - - PProcessHangMonitorParent* mHangMonitorActor; }; } // namespace dom diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 772c22be6a30..4d32082bdec2 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -21,7 +21,6 @@ include protocol PFileDescriptorSet; include protocol PFMRadio; include protocol PFileSystemRequest; include protocol PHal; -include protocol PProcessHangMonitor; include protocol PImageBridge; include protocol PMemoryReportRequest; include protocol PMobileConnection; @@ -346,7 +345,6 @@ prio(normal upto urgent) intr protocol PContent parent spawns PPluginModule; parent opens PCompositor; - parent opens PProcessHangMonitor; parent opens PSharedBufferManager; parent opens PImageBridge; child opens PBackground; diff --git a/dom/ipc/PProcessHangMonitor.ipdl b/dom/ipc/PProcessHangMonitor.ipdl deleted file mode 100644 index 9ac0115a15be..000000000000 --- a/dom/ipc/PProcessHangMonitor.ipdl +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=8 et : - */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; - -namespace mozilla { - -struct SlowScriptData -{ - TabId tabId; - nsCString filename; - uint32_t lineno; -}; - -struct PluginHangData -{ - uint32_t pluginId; -}; - -union HangData -{ - SlowScriptData; - PluginHangData; -}; - -protocol PProcessHangMonitor -{ -parent: - async HangEvidence(HangData data); - -child: - async TerminateScript(); - - async BeginStartingDebugger(); - async EndStartingDebugger(); -}; - -} // namespace mozilla diff --git a/dom/ipc/ProcessHangMonitor.cpp b/dom/ipc/ProcessHangMonitor.cpp deleted file mode 100644 index 75a5df9d3cc7..000000000000 --- a/dom/ipc/ProcessHangMonitor.cpp +++ /dev/null @@ -1,954 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/ProcessHangMonitor.h" -#include "mozilla/ProcessHangMonitorIPC.h" - -#include "mozilla/Atomics.h" -#include "mozilla/dom/ContentParent.h" -#include "mozilla/dom/Element.h" -#include "mozilla/dom/TabChild.h" -#include "mozilla/dom/TabParent.h" -#include "mozilla/Monitor.h" -#include "mozilla/plugins/PluginBridge.h" -#include "mozilla/Preferences.h" -#include "mozilla/unused.h" - -#include "nsIFrameLoader.h" -#include "nsIHangReport.h" -#include "nsITabParent.h" -#include "nsPluginHost.h" -#include "nsThreadUtils.h" - -#include "base/task.h" -#include "base/thread.h" - -using namespace mozilla; -using namespace mozilla::dom; - -/* - * Basic architecture: - * - * Each process has its own ProcessHangMonitor singleton. This singleton exists - * as long as there is at least one content process in the system. Each content - * process has a HangMonitorChild and the chrome process has one - * HangMonitorParent per process. Each process (including the chrome process) - * runs a hang monitoring thread. The PHangMonitor actors are bound to this - * thread so that they never block on the main thread. - * - * When the content process detects a hang, it posts a task to its hang thread, - * which sends an IPC message to the hang thread in the parent. The parent - * cancels any ongoing CPOW requests and then posts a runnable to the main - * thread that notifies Firefox frontend code of the hang. The frontend code is - * passed an nsIHangReport, which can be used to terminate the hang. - * - * If the user chooses to terminate a script, a task is posted to the chrome - * process's hang monitoring thread, which sends an IPC message to the hang - * thread in the content process. That thread sets a flag to indicate that JS - * execution should be terminated the next time it hits the interrupt - * callback. A similar scheme is used for debugging slow scripts. If a content - * process or plug-in needs to be terminated, the chrome process does so - * directly, without messaging the content process. - */ - -namespace { - -/* Child process objects */ - -class HangMonitorChild - : public PProcessHangMonitorChild -{ - public: - explicit HangMonitorChild(ProcessHangMonitor* aMonitor); - virtual ~HangMonitorChild(); - - void Open(Transport* aTransport, ProcessHandle aHandle, - MessageLoop* aIOLoop); - - typedef ProcessHangMonitor::SlowScriptAction SlowScriptAction; - SlowScriptAction NotifySlowScript(nsITabChild* aTabChild, - const char* aFileName, - unsigned aLineNo); - void NotifySlowScriptAsync(TabId aTabId, - const nsCString& aFileName, - unsigned aLineNo); - - bool IsDebuggerStartupComplete(); - - void NotifyPluginHang(uint32_t aPluginId); - void NotifyPluginHangAsync(uint32_t aPluginId); - - void ClearHang(); - - virtual bool RecvTerminateScript() MOZ_OVERRIDE; - virtual bool RecvBeginStartingDebugger() MOZ_OVERRIDE; - virtual bool RecvEndStartingDebugger() MOZ_OVERRIDE; - - virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; - - void Shutdown(); - - static HangMonitorChild* Get() { return sInstance; } - - MessageLoop* MonitorLoop() { return mHangMonitor->MonitorLoop(); } - - private: - void ShutdownOnThread(); - - static HangMonitorChild* sInstance; - - const nsRefPtr mHangMonitor; - Monitor mMonitor; - - // Main thread-only. - bool mSentReport; - - // These fields must be accessed with mMonitor held. - bool mTerminateScript; - bool mStartDebugger; - bool mFinishedStartingDebugger; - bool mShutdownDone; - - // This field is only accessed on the hang thread. - bool mIPCOpen; -}; - -HangMonitorChild* HangMonitorChild::sInstance; - -/* Parent process objects */ - -class HangMonitorParent; - -class HangMonitoredProcess MOZ_FINAL - : public nsIHangReport -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - - HangMonitoredProcess(HangMonitorParent* aActor, - ContentParent* aContentParent) - : mActor(aActor), mContentParent(aContentParent) {} - - NS_IMETHOD GetHangType(uint32_t* aHangType) MOZ_OVERRIDE; - NS_IMETHOD GetScriptBrowser(nsIDOMElement** aBrowser) MOZ_OVERRIDE; - NS_IMETHOD GetScriptFileName(nsACString& aFileName) MOZ_OVERRIDE; - NS_IMETHOD GetScriptLineNo(uint32_t* aLineNo) MOZ_OVERRIDE; - - NS_IMETHOD GetPluginName(nsACString& aPluginName) MOZ_OVERRIDE; - - NS_IMETHOD TerminateScript() MOZ_OVERRIDE; - NS_IMETHOD BeginStartingDebugger() MOZ_OVERRIDE; - NS_IMETHOD EndStartingDebugger() MOZ_OVERRIDE; - NS_IMETHOD TerminatePlugin() MOZ_OVERRIDE; - NS_IMETHOD TerminateProcess() MOZ_OVERRIDE; - - NS_IMETHOD IsReportForBrowser(nsIFrameLoader* aFrameLoader, bool* aResult); - - void Clear() { mContentParent = nullptr; mActor = nullptr; } - - void SetHangData(const HangData& aHangData) { mHangData = aHangData; } - -private: - ~HangMonitoredProcess() {} - - // Everything here is main thread-only. - HangMonitorParent* mActor; - ContentParent* mContentParent; - HangData mHangData; -}; - -class HangMonitorParent - : public PProcessHangMonitorParent -{ -public: - explicit HangMonitorParent(ProcessHangMonitor* aMonitor); - virtual ~HangMonitorParent(); - - void Open(Transport* aTransport, ProcessHandle aHandle, - MessageLoop* aIOLoop); - - virtual bool RecvHangEvidence(const HangData& aHangData) MOZ_OVERRIDE; - - virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; - - void SetProcess(HangMonitoredProcess* aProcess) { mProcess = aProcess; } - - void Shutdown(); - - void TerminateScript(); - void BeginStartingDebugger(); - void EndStartingDebugger(); - - MessageLoop* MonitorLoop() { return mHangMonitor->MonitorLoop(); } - - private: - void ShutdownOnThread(); - - const nsRefPtr mHangMonitor; - - // This field is read-only after construction. - bool mReportHangs; - - // This field is only accessed on the hang thread. - bool mIPCOpen; - - Monitor mMonitor; - - // Must be accessed with mMonitor held. - nsRefPtr mProcess; - bool mShutdownDone; -}; - -} // namespace - -template<> -struct RunnableMethodTraits -{ - typedef HangMonitorChild Class; - static void RetainCallee(Class* obj) { } - static void ReleaseCallee(Class* obj) { } -}; - -template<> -struct RunnableMethodTraits -{ - typedef HangMonitorParent Class; - static void RetainCallee(Class* obj) { } - static void ReleaseCallee(Class* obj) { } -}; - -/* HangMonitorChild implementation */ - -HangMonitorChild::HangMonitorChild(ProcessHangMonitor* aMonitor) - : mHangMonitor(aMonitor), - mMonitor("HangMonitorChild lock"), - mSentReport(false), - mTerminateScript(false), - mStartDebugger(false), - mFinishedStartingDebugger(false), - mShutdownDone(false), - mIPCOpen(true) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); -} - -HangMonitorChild::~HangMonitorChild() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(sInstance == this); - sInstance = nullptr; -} - -void -HangMonitorChild::Shutdown() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - MonitorAutoLock lock(mMonitor); - while (!mShutdownDone) { - mMonitor.Wait(); - } -} - -void -HangMonitorChild::ShutdownOnThread() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - MonitorAutoLock lock(mMonitor); - mShutdownDone = true; - mMonitor.Notify(); -} - -void -HangMonitorChild::ActorDestroy(ActorDestroyReason aWhy) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - mIPCOpen = false; - - // We use a task here to ensure that IPDL is finished with this - // HangMonitorChild before it gets deleted on the main thread. - MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &HangMonitorChild::ShutdownOnThread)); -} - -bool -HangMonitorChild::RecvTerminateScript() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - MonitorAutoLock lock(mMonitor); - mTerminateScript = true; - return true; -} - -bool -HangMonitorChild::RecvBeginStartingDebugger() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - MonitorAutoLock lock(mMonitor); - mStartDebugger = true; - return true; -} - -bool -HangMonitorChild::RecvEndStartingDebugger() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - MonitorAutoLock lock(mMonitor); - mFinishedStartingDebugger = true; - return true; -} - -void -HangMonitorChild::Open(Transport* aTransport, ProcessHandle aHandle, - MessageLoop* aIOLoop) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - MOZ_ASSERT(!sInstance); - sInstance = this; - - DebugOnly ok = PProcessHangMonitorChild::Open(aTransport, aHandle, aIOLoop); - MOZ_ASSERT(ok); -} - -void -HangMonitorChild::NotifySlowScriptAsync(TabId aTabId, - const nsCString& aFileName, - unsigned aLineNo) -{ - if (mIPCOpen) { - unused << SendHangEvidence(SlowScriptData(aTabId, aFileName, aLineNo)); - } -} - -HangMonitorChild::SlowScriptAction -HangMonitorChild::NotifySlowScript(nsITabChild* aTabChild, - const char* aFileName, - unsigned aLineNo) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - mSentReport = true; - - { - MonitorAutoLock lock(mMonitor); - - if (mTerminateScript) { - mTerminateScript = false; - return SlowScriptAction::Terminate; - } - - if (mStartDebugger) { - mStartDebugger = false; - return SlowScriptAction::StartDebugger; - } - } - - TabId id; - if (aTabChild) { - nsRefPtr tabChild = static_cast(aTabChild); - id = tabChild->GetTabId(); - } - nsAutoCString filename(aFileName); - - MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &HangMonitorChild::NotifySlowScriptAsync, - id, filename, aLineNo)); - return SlowScriptAction::Continue; -} - -bool -HangMonitorChild::IsDebuggerStartupComplete() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - MonitorAutoLock lock(mMonitor); - - if (mFinishedStartingDebugger) { - mFinishedStartingDebugger = false; - return true; - } - - return false; -} - -void -HangMonitorChild::NotifyPluginHang(uint32_t aPluginId) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - mSentReport = true; - - MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &HangMonitorChild::NotifyPluginHangAsync, - aPluginId)); -} - -void -HangMonitorChild::NotifyPluginHangAsync(uint32_t aPluginId) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - if (mIPCOpen) { - unused << SendHangEvidence(PluginHangData(aPluginId)); - } -} - -void -HangMonitorChild::ClearHang() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (mSentReport) { - MonitorAutoLock lock(mMonitor); - mSentReport = false; - mTerminateScript = false; - mStartDebugger = false; - mFinishedStartingDebugger = false; - } -} - -/* HangMonitorParent implementation */ - -HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor) - : mHangMonitor(aMonitor), - mIPCOpen(true), - mMonitor("HangMonitorParent lock"), - mShutdownDone(false) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - mReportHangs = mozilla::Preferences::GetBool("dom.ipc.reportProcessHangs", false); -} - -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(GetTransport())); -} - -void -HangMonitorParent::Shutdown() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - MonitorAutoLock lock(mMonitor); - - if (mProcess) { - mProcess->Clear(); - mProcess = nullptr; - } - - MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &HangMonitorParent::ShutdownOnThread)); - - while (!mShutdownDone) { - mMonitor.Wait(); - } -} - -void -HangMonitorParent::ShutdownOnThread() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - // mIPCOpen is only written from this thread, so need need to take the lock - // here. We'd be shooting ourselves in the foot, because ActorDestroy takes - // it. - if (mIPCOpen) { - Close(); - } - - MonitorAutoLock lock(mMonitor); - mShutdownDone = true; - mMonitor.Notify(); -} - -void -HangMonitorParent::ActorDestroy(ActorDestroyReason aWhy) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - mIPCOpen = false; -} - -void -HangMonitorParent::Open(Transport* aTransport, ProcessHandle aHandle, - MessageLoop* aIOLoop) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - DebugOnly ok = PProcessHangMonitorParent::Open(aTransport, aHandle, aIOLoop); - MOZ_ASSERT(ok); -} - -class HangObserverNotifier MOZ_FINAL : public nsRunnable -{ -public: - HangObserverNotifier(HangMonitoredProcess* aProcess, const HangData& aHangData) - : mProcess(aProcess), - mHangData(aHangData) - {} - - NS_IMETHOD - Run() - { - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - mProcess->SetHangData(mHangData); - - nsCOMPtr observerService = - mozilla::services::GetObserverService(); - observerService->NotifyObservers(mProcess, "process-hang-report", nullptr); - return NS_OK; - } - -private: - nsRefPtr mProcess; - HangData mHangData; -}; - -bool -HangMonitorParent::RecvHangEvidence(const HangData& aHangData) -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - if (!mReportHangs) { - return true; - } - - mHangMonitor->InitiateCPOWTimeout(); - - MonitorAutoLock lock(mMonitor); - - nsCOMPtr notifier = new HangObserverNotifier(mProcess, aHangData); - NS_DispatchToMainThread(notifier); - - return true; -} - -void -HangMonitorParent::TerminateScript() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - if (mIPCOpen) { - unused << SendTerminateScript(); - } -} - -void -HangMonitorParent::BeginStartingDebugger() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - if (mIPCOpen) { - unused << SendBeginStartingDebugger(); - } -} - -void -HangMonitorParent::EndStartingDebugger() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - - if (mIPCOpen) { - unused << SendEndStartingDebugger(); - } -} - -/* HangMonitoredProcess implementation */ - -NS_IMPL_ISUPPORTS(HangMonitoredProcess, nsIHangReport) - -NS_IMETHODIMP -HangMonitoredProcess::GetHangType(uint32_t* aHangType) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - switch (mHangData.type()) { - case HangData::TSlowScriptData: - *aHangType = SLOW_SCRIPT; - break; - case HangData::TPluginHangData: - *aHangType = PLUGIN_HANG; - break; - default: - MOZ_ASSERT(false); - return NS_ERROR_UNEXPECTED; - break; - } - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::GetScriptBrowser(nsIDOMElement** aBrowser) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_NOT_AVAILABLE; - } - - TabId tabId = mHangData.get_SlowScriptData().tabId(); - if (!mContentParent) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsTArray tabs; - mContentParent->ManagedPBrowserParent(tabs); - for (size_t i = 0; i < tabs.Length(); i++) { - TabParent* tp = static_cast(tabs[i]); - if (tp->GetTabId() == tabId) { - nsCOMPtr node = do_QueryInterface(tp->GetOwnerElement()); - node.forget(aBrowser); - return NS_OK; - } - } - - *aBrowser = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::GetScriptFileName(nsACString& aFileName) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_NOT_AVAILABLE; - } - - aFileName = mHangData.get_SlowScriptData().filename(); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::GetScriptLineNo(uint32_t* aLineNo) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_NOT_AVAILABLE; - } - - *aLineNo = mHangData.get_SlowScriptData().lineno(); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::GetPluginName(nsACString& aPluginName) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TPluginHangData) { - return NS_ERROR_NOT_AVAILABLE; - } - - uint32_t id = mHangData.get_PluginHangData().pluginId(); - - nsRefPtr host = nsPluginHost::GetInst(); - nsPluginTag* tag = host->PluginWithId(id); - if (!tag) { - return NS_ERROR_UNEXPECTED; - } - - aPluginName = tag->mName; - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::TerminateScript() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_UNEXPECTED; - } - - if (!mActor) { - return NS_ERROR_UNEXPECTED; - } - - ProcessHangMonitor::Get()->MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(mActor, &HangMonitorParent::TerminateScript)); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::BeginStartingDebugger() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_UNEXPECTED; - } - - if (!mActor) { - return NS_ERROR_UNEXPECTED; - } - - ProcessHangMonitor::Get()->MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(mActor, &HangMonitorParent::BeginStartingDebugger)); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::EndStartingDebugger() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TSlowScriptData) { - return NS_ERROR_UNEXPECTED; - } - - if (!mActor) { - return NS_ERROR_UNEXPECTED; - } - - ProcessHangMonitor::Get()->MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(mActor, &HangMonitorParent::EndStartingDebugger)); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::TerminatePlugin() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (mHangData.type() != HangData::TPluginHangData) { - return NS_ERROR_UNEXPECTED; - } - - uint32_t id = mHangData.get_PluginHangData().pluginId(); - plugins::TerminatePlugin(id); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::TerminateProcess() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - if (!mContentParent) { - return NS_ERROR_UNEXPECTED; - } - - mContentParent->KillHard(); - return NS_OK; -} - -NS_IMETHODIMP -HangMonitoredProcess::IsReportForBrowser(nsIFrameLoader* aFrameLoader, bool* aResult) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - if (!mActor) { - *aResult = false; - return NS_OK; - } - - nsCOMPtr itp; - aFrameLoader->GetTabParent(getter_AddRefs(itp)); - if (!itp) { - *aResult = false; - return NS_OK; - } - - *aResult = mContentParent == static_cast(itp.get())->Manager(); - return NS_OK; -} - -ProcessHangMonitor* ProcessHangMonitor::sInstance; - -ProcessHangMonitor::ProcessHangMonitor() - : mCPOWTimeout(false) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - MOZ_COUNT_CTOR(ProcessHangMonitor); - - if (XRE_GetProcessType() == GeckoProcessType_Content) { - nsCOMPtr obs = mozilla::services::GetObserverService(); - obs->AddObserver(this, "xpcom-shutdown", false); - } - - mThread = new base::Thread("ProcessHangMonitor"); - if (!mThread->Start()) { - delete mThread; - mThread = nullptr; - } -} - -ProcessHangMonitor::~ProcessHangMonitor() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - MOZ_COUNT_DTOR(ProcessHangMonitor); - - MOZ_ASSERT(sInstance == this); - sInstance = nullptr; - - delete mThread; -} - -ProcessHangMonitor* -ProcessHangMonitor::GetOrCreate() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (!sInstance) { - sInstance = new ProcessHangMonitor(); - } - return sInstance; -} - -NS_IMPL_ISUPPORTS(ProcessHangMonitor, nsIObserver) - -NS_IMETHODIMP -ProcessHangMonitor::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - if (!strcmp(aTopic, "xpcom-shutdown")) { - if (HangMonitorChild* child = HangMonitorChild::Get()) { - child->Shutdown(); - delete child; - } - - nsCOMPtr obs = mozilla::services::GetObserverService(); - if (obs) { - obs->RemoveObserver(this, "xpcom-shutdown"); - } - } - return NS_OK; -} - -ProcessHangMonitor::SlowScriptAction -ProcessHangMonitor::NotifySlowScript(nsITabChild* aTabChild, - const char* aFileName, - unsigned aLineNo) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - return HangMonitorChild::Get()->NotifySlowScript(aTabChild, aFileName, aLineNo); -} - -bool -ProcessHangMonitor::IsDebuggerStartupComplete() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - return HangMonitorChild::Get()->IsDebuggerStartupComplete(); -} - -bool -ProcessHangMonitor::ShouldTimeOutCPOWs() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - if (mCPOWTimeout) { - mCPOWTimeout = false; - return true; - } - return false; -} - -void -ProcessHangMonitor::InitiateCPOWTimeout() -{ - MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop()); - mCPOWTimeout = true; -} - -void -ProcessHangMonitor::NotifyPluginHang(uint32_t aPluginId) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - return HangMonitorChild::Get()->NotifyPluginHang(aPluginId); -} - -PProcessHangMonitorParent* -mozilla::CreateHangMonitorParent(ContentParent* aContentParent, - mozilla::ipc::Transport* aTransport, - base::ProcessId aOtherProcess) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate(); - HangMonitorParent* parent = new HangMonitorParent(monitor); - - HangMonitoredProcess* process = new HangMonitoredProcess(parent, aContentParent); - parent->SetProcess(process); - - base::ProcessHandle handle; - if (!base::OpenProcessHandle(aOtherProcess, &handle)) { - // XXX need to kill |aOtherProcess|, it's boned - return nullptr; - } - - monitor->MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(parent, &HangMonitorParent::Open, - aTransport, handle, XRE_GetIOMessageLoop())); - - return parent; -} - -PProcessHangMonitorChild* -mozilla::CreateHangMonitorChild(mozilla::ipc::Transport* aTransport, - base::ProcessId aOtherProcess) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate(); - HangMonitorChild* child = new HangMonitorChild(monitor); - - base::ProcessHandle handle; - if (!base::OpenProcessHandle(aOtherProcess, &handle)) { - // XXX need to kill |aOtherProcess|, it's boned - return nullptr; - } - - monitor->MonitorLoop()->PostTask( - FROM_HERE, - NewRunnableMethod(child, &HangMonitorChild::Open, - aTransport, handle, XRE_GetIOMessageLoop())); - - return child; -} - -MessageLoop* -ProcessHangMonitor::MonitorLoop() -{ - return mThread->message_loop(); -} - -/* static */ void -ProcessHangMonitor::AddProcess(ContentParent* aContentParent) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - - if (mozilla::Preferences::GetBool("dom.ipc.processHangMonitor", false)) { - DebugOnly opened = PProcessHangMonitor::Open(aContentParent); - MOZ_ASSERT(opened); - } -} - -/* static */ void -ProcessHangMonitor::RemoveProcess(PProcessHangMonitorParent* aParent) -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - auto parent = static_cast(aParent); - parent->Shutdown(); - delete parent; -} - -/* static */ void -ProcessHangMonitor::ClearHang() -{ - MOZ_ASSERT(NS_IsMainThread()); - if (HangMonitorChild* child = HangMonitorChild::Get()) { - child->ClearHang(); - } -} diff --git a/dom/ipc/ProcessHangMonitor.h b/dom/ipc/ProcessHangMonitor.h deleted file mode 100644 index 39ef1652d102..000000000000 --- a/dom/ipc/ProcessHangMonitor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_ProcessHangMonitor_h -#define mozilla_ProcessHangMonitor_h - -#include "mozilla/Atomics.h" -#include "nsIObserver.h" - -class nsGlobalWindow; -class nsITabChild; - -class MessageLoop; - -namespace base { -class Thread; -}; - -namespace mozilla { - -namespace dom { -class ContentParent; -} - -class PProcessHangMonitorParent; -class PProcessHangMonitorChild; - -class ProcessHangMonitor MOZ_FINAL - : public nsIObserver -{ - private: - ProcessHangMonitor(); - virtual ~ProcessHangMonitor(); - - public: - static ProcessHangMonitor* Get() { return sInstance; } - static ProcessHangMonitor* GetOrCreate(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - static void AddProcess(dom::ContentParent* aContentParent); - static void RemoveProcess(PProcessHangMonitorParent* aParent); - - static void ClearHang(); - - enum SlowScriptAction { - Continue, - Terminate, - StartDebugger - }; - SlowScriptAction NotifySlowScript(nsITabChild* aTabChild, - const char* aFileName, - unsigned aLineNo); - - void NotifyPluginHang(uint32_t aPluginId); - - bool IsDebuggerStartupComplete(); - - void InitiateCPOWTimeout(); - bool ShouldTimeOutCPOWs(); - - MessageLoop* MonitorLoop(); - - private: - static ProcessHangMonitor* sInstance; - - Atomic mCPOWTimeout; - - base::Thread* mThread; -}; - -} // namespace mozilla - -#endif // mozilla_ProcessHangMonitor_h diff --git a/dom/ipc/ProcessHangMonitorIPC.h b/dom/ipc/ProcessHangMonitorIPC.h deleted file mode 100644 index 87c0e856bb1f..000000000000 --- a/dom/ipc/ProcessHangMonitorIPC.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_ProcessHangMonitorIPC_h -#define mozilla_ProcessHangMonitorIPC_h - -#include "base/task.h" -#include "base/thread.h" - -#include "mozilla/PProcessHangMonitor.h" -#include "mozilla/PProcessHangMonitorParent.h" -#include "mozilla/PProcessHangMonitorChild.h" - -namespace mozilla { - -namespace dom { -class ContentParent; -} - -PProcessHangMonitorParent* -CreateHangMonitorParent(mozilla::dom::ContentParent* aContentParent, - mozilla::ipc::Transport* aTransport, - base::ProcessId aOtherProcess); - -PProcessHangMonitorChild* -CreateHangMonitorChild(mozilla::ipc::Transport* aTransport, - base::ProcessId aOtherProcess); - -} // namespace mozilla - -#endif // mozilla_ProcessHangMonitorIPC_h diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index ce808549ba78..f8b0427f2fa2 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -4,12 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -XPIDL_SOURCES += [ - 'nsIHangReport.idl', -] - -XPIDL_MODULE = 'dom' - EXPORTS += [ 'nsICachedFileDescriptorListener.h', ] @@ -45,8 +39,6 @@ EXPORTS.mozilla.dom += [ EXPORTS.mozilla += [ 'AppProcessChecker.h', 'PreallocatedProcessManager.h', - 'ProcessHangMonitor.h', - 'ProcessHangMonitorIPC.h', 'ProcessPriorityManager.h', ] @@ -81,7 +73,6 @@ SOURCES += [ 'Blob.cpp', 'ContentChild.cpp', 'CrashReporterChild.cpp', - 'ProcessHangMonitor.cpp', ] IPDL_SOURCES += [ @@ -101,7 +92,6 @@ IPDL_SOURCES += [ 'PFilePicker.ipdl', 'PMemoryReportRequest.ipdl', 'PPluginWidget.ipdl', - 'PProcessHangMonitor.ipdl', 'PScreenManager.ipdl', 'PTabContext.ipdlh', ] diff --git a/dom/ipc/nsIHangReport.idl b/dom/ipc/nsIHangReport.idl deleted file mode 100644 index d8ac12505288..000000000000 --- a/dom/ipc/nsIHangReport.idl +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIDOMElement; -interface nsIFrameLoader; - -/** - * When a content process hangs, Gecko notifies "process-hang-report" observers - * and passes an nsIHangReport for the subject parameter. There is at most one - * nsIHangReport associated with a given content process. As long as the content - * process stays stuck, the "process-hang-report" observer will continue to be - * notified at regular intervals (approximately once per second). The content - * process will continue to run uninhibitedly during this time. - */ - -[scriptable, uuid(3b88d100-8d5b-11e4-b4a9-0800200c9a66)] -interface nsIHangReport : nsISupports -{ - const unsigned long SLOW_SCRIPT = 1; - const unsigned long PLUGIN_HANG = 2; - - // The type of hang being reported: SLOW_SCRIPT or PLUGIN_HANG. - readonly attribute unsigned long hangType; - - // For SLOW_SCRIPT reports, these fields contain information about the - // slow script. - // Only valid for SLOW_SCRIPT reports. - readonly attribute nsIDOMElement scriptBrowser; - readonly attribute ACString scriptFileName; - readonly attribute unsigned long scriptLineNo; - - // For PLUGIN_HANGs, this field contains information about the plugin. - // Only valid for PLUGIN_HANG reports. - readonly attribute ACString pluginName; - - // Terminate the slow script if it is still running. - // Only valid for SLOW_SCRIPT reports. - void terminateScript(); - - // Terminate the plugin if it is still hung. - // Only valid for PLUGIN_HANG reports. - void terminatePlugin(); - - // Terminate the hung content process unconditionally. - // Valid for any type of hang. - void terminateProcess(); - - // Ask the content process to start up the slow script debugger. - // Only valid for SLOW_SCRIPT reports. - void beginStartingDebugger(); - - // Inform the content process that the slow script debugger has finished - // spinning up. The content process will run a nested event loop until this - // method is called. - // Only valid for SLOW_SCRIPT reports. - void endStartingDebugger(); - - // Inquire whether the report is for a content process loaded by the given - // frameloader. - bool isReportForBrowser(in nsIFrameLoader aFrameLoader); -}; diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index 578e653284ba..8124dde36d07 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -201,8 +201,6 @@ public: // Does not accept nullptr and should never fail. nsPluginTag* TagForPlugin(nsNPAPIPlugin* aPlugin); - nsPluginTag* PluginWithId(uint32_t aId); - nsresult GetPlugin(const char *aMimeType, nsNPAPIPlugin** aPlugin); nsresult GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPlugin); void NotifyContentModuleDestroyed(uint32_t aPluginId); @@ -278,6 +276,7 @@ private: // Returns the first plugin at |path| nsPluginTag* FirstPluginWithPath(const nsCString& path); + nsPluginTag* PluginWithId(uint32_t aId); nsresult EnsurePrivateDirServiceProvider(); diff --git a/dom/plugins/ipc/PluginBridge.h b/dom/plugins/ipc/PluginBridge.h index a8abcd43d70a..8bd5963602c1 100644 --- a/dom/plugins/ipc/PluginBridge.h +++ b/dom/plugins/ipc/PluginBridge.h @@ -24,9 +24,6 @@ FindPluginsForContent(uint32_t aPluginEpoch, nsTArray* aPlugins, uint32_t* aNewPluginEpoch); -void -TerminatePlugin(uint32_t aPluginId); - } // namespace plugins } // namespace mozilla diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 98acf02d893b..4e4562bd4537 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -21,7 +21,6 @@ #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/Preferences.h" -#include "mozilla/ProcessHangMonitor.h" #include "mozilla/Services.h" #include "mozilla/Telemetry.h" #include "mozilla/unused.h" @@ -70,7 +69,6 @@ using namespace mozilla::plugins::parent; using namespace CrashReporter; #endif -static const char kContentTimeoutPref[] = "dom.ipc.plugins.contentTimeoutSecs"; static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs"; static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs"; static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs"; @@ -261,22 +259,6 @@ PRCList PluginModuleMapping::sModuleListHead = bool PluginModuleMapping::sIsLoadModuleOnStack = false; -void -mozilla::plugins::TerminatePlugin(uint32_t aPluginId) -{ - MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); - - nsRefPtr host = nsPluginHost::GetInst(); - nsPluginTag* pluginTag = host->PluginWithId(aPluginId); - if (!pluginTag || !pluginTag->mPlugin) { - return; - } - - nsRefPtr plugin = pluginTag->mPlugin; - PluginModuleChromeParent* chromeParent = static_cast(plugin->GetLibrary()); - chromeParent->TerminateChildProcess(MessageLoop::current()); -} - /* static */ PluginLibrary* PluginModuleContentParent::LoadModule(uint32_t aPluginId) { @@ -307,8 +289,6 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId) mapping.forget(); } - parent->mPluginId = aPluginId; - return parent; } @@ -348,8 +328,6 @@ PluginModuleContentParent::Initialize(mozilla::ipc::Transport* aTransport, // all share the same channel. parent->GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION); - TimeoutChanged(kContentTimeoutPref, parent); - // moduleMapping is linked into PluginModuleMapping::sModuleListHead and is // needed later, so since this function is returning successfully we // forget it here. @@ -539,12 +517,6 @@ PluginModuleParent::~PluginModuleParent() PluginModuleContentParent::PluginModuleContentParent() : PluginModuleParent(false) { - Preferences::RegisterCallback(TimeoutChanged, kContentTimeoutPref, this); -} - -PluginModuleContentParent::~PluginModuleContentParent() -{ - Preferences::UnregisterCallback(TimeoutChanged, kContentTimeoutPref, this); } PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId) @@ -678,7 +650,7 @@ PluginModuleChromeParent::WriteExtraDataForMinidump(AnnotationTable& notes) #endif // MOZ_CRASHREPORTER void -PluginModuleParent::SetChildTimeout(const int32_t aChildTimeout) +PluginModuleChromeParent::SetChildTimeout(const int32_t aChildTimeout) { int32_t timeoutMs = (aChildTimeout > 0) ? (1000 * aChildTimeout) : MessageChannel::kNoTimeout; @@ -686,33 +658,24 @@ PluginModuleParent::SetChildTimeout(const int32_t aChildTimeout) } void -PluginModuleParent::TimeoutChanged(const char* aPref, void* aModule) +PluginModuleChromeParent::TimeoutChanged(const char* aPref, void* aModule) { - PluginModuleParent* module = static_cast(aModule); - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); #ifndef XP_WIN if (!strcmp(aPref, kChildTimeoutPref)) { - MOZ_ASSERT(module->IsChrome()); // The timeout value used by the parent for children int32_t timeoutSecs = Preferences::GetInt(kChildTimeoutPref, 0); - module->SetChildTimeout(timeoutSecs); + static_cast(aModule)->SetChildTimeout(timeoutSecs); #else if (!strcmp(aPref, kChildTimeoutPref) || !strcmp(aPref, kHangUIMinDisplayPref) || !strcmp(aPref, kHangUITimeoutPref)) { - MOZ_ASSERT(module->IsChrome()); - static_cast(module)->EvaluateHangUIState(true); + static_cast(aModule)->EvaluateHangUIState(true); #endif // XP_WIN } else if (!strcmp(aPref, kParentTimeoutPref)) { // The timeout value used by the child for its parent - MOZ_ASSERT(module->IsChrome()); int32_t timeoutSecs = Preferences::GetInt(kParentTimeoutPref, 0); - unused << static_cast(module)->SendSetParentHangTimeout(timeoutSecs); - } else if (!strcmp(aPref, kContentTimeoutPref)) { - MOZ_ASSERT(!module->IsChrome()); - int32_t timeoutSecs = Preferences::GetInt(kContentTimeoutPref, 0); - module->SetChildTimeout(timeoutSecs); + unused << static_cast(aModule)->SendSetParentHangTimeout(timeoutSecs); } } @@ -896,23 +859,6 @@ PluginModuleChromeParent::ShouldContinueFromReplyTimeout() return false; } -bool -PluginModuleContentParent::ShouldContinueFromReplyTimeout() -{ - nsRefPtr monitor = ProcessHangMonitor::Get(); - if (!monitor) { - return true; - } - monitor->NotifyPluginHang(mPluginId); - return true; -} - -void -PluginModuleContentParent::OnExitedSyncSend() -{ - ProcessHangMonitor::ClearHang(); -} - void PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop) { diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 88c79cf31ef9..f100f8cd77dd 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -176,9 +176,6 @@ protected: PluginAsyncSurrogate** aSurrogate = nullptr); protected: - void SetChildTimeout(const int32_t aChildTimeout); - static void TimeoutChanged(const char* aPref, void* aModule); - virtual void UpdatePluginTimeout() {} virtual bool RecvNotifyContentModuleDestroyed() MOZ_OVERRIDE { return true; } @@ -312,19 +309,13 @@ class PluginModuleContentParent : public PluginModuleParent static void OnLoadPluginResult(const uint32_t& aPluginId, const bool& aResult); static void AssociatePluginId(uint32_t aPluginId, base::ProcessId aProcessId); - virtual ~PluginModuleContentParent(); - private: - virtual bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE; - virtual void OnExitedSyncSend() MOZ_OVERRIDE; #ifdef MOZ_CRASHREPORTER_INJECTOR void OnCrash(DWORD processID) MOZ_OVERRIDE {} #endif static PluginModuleContentParent* sSavedModuleParent; - - uint32_t mPluginId; }; class PluginModuleChromeParent @@ -352,9 +343,6 @@ class PluginModuleChromeParent */ void OnHangUIContinue(); - - void - EvaluateHangUIState(const bool aReset); #endif // XP_WIN virtual bool WaitForIPCConnection() MOZ_OVERRIDE; @@ -414,6 +402,8 @@ private: CrashReporterParent* CrashReporter(); void CleanupFromTimeout(const bool aByHangUI); + void SetChildTimeout(const int32_t aChildTimeout); + static void TimeoutChanged(const char* aPref, void* aModule); virtual void UpdatePluginTimeout() MOZ_OVERRIDE; @@ -459,6 +449,9 @@ private: #endif // MOZ_CRASHREPORTER + void + EvaluateHangUIState(const bool aReset); + /** * Launches the Plugin Hang UI. * diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index bd5c01c14219..57ed038b3789 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -177,11 +177,6 @@ public: return INTR_SEMS == mMesageSemantics && OUT_MESSAGE == mDirection; } - bool IsOutgoingSync() const { - return (mMesageSemantics == INTR_SEMS || mMesageSemantics == SYNC_SEMS) && - mDirection == OUT_MESSAGE; - } - void Describe(int32_t* id, const char** dir, const char** sems, const char** name) const { @@ -223,9 +218,6 @@ public: if (frame.IsInterruptIncall()) mThat.EnteredCall(); - if (frame.IsOutgoingSync()) - mThat.EnteredSyncSend(); - mThat.mSawInterruptOutMsg |= frame.IsInterruptOutcall(); } @@ -234,9 +226,7 @@ public: MOZ_ASSERT(!mThat.mCxxStackFrames.empty()); - const InterruptFrame& frame = mThat.mCxxStackFrames.back(); - bool exitingSync = frame.IsOutgoingSync(); - bool exitingCall = frame.IsInterruptIncall(); + bool exitingCall = mThat.mCxxStackFrames.back().IsInterruptIncall(); mThat.mCxxStackFrames.shrinkBy(1); bool exitingStack = mThat.mCxxStackFrames.empty(); @@ -249,9 +239,6 @@ public: if (exitingCall) mThat.ExitedCall(); - if (exitingSync) - mThat.ExitedSyncSend(); - if (exitingStack) mThat.ExitedCxxStack(); } diff --git a/ipc/glue/MessageChannel.h b/ipc/glue/MessageChannel.h index a0e2ebbc8758..894f075696a6 100644 --- a/ipc/glue/MessageChannel.h +++ b/ipc/glue/MessageChannel.h @@ -291,14 +291,6 @@ class MessageChannel : HasResultCodes mListener->OnExitedCall(); } - void EnteredSyncSend() { - mListener->OnEnteredSyncSend(); - } - - void ExitedSyncSend() { - mListener->OnExitedSyncSend(); - } - MessageListener *Listener() const { return mListener.get(); } diff --git a/ipc/glue/MessageLink.h b/ipc/glue/MessageLink.h index 7004019e1c4f..069024c7799e 100644 --- a/ipc/glue/MessageLink.h +++ b/ipc/glue/MessageLink.h @@ -98,11 +98,6 @@ class MessageListener return RIPChildWins; } - virtual void OnEnteredSyncSend() { - } - virtual void OnExitedSyncSend() { - } - virtual void ProcessRemoteNativeEventsInInterruptCall() { } diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 174ddb9abaff..cea5e1c84acf 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -40,7 +40,6 @@ #include "mozilla/dom/WindowBinding.h" #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" -#include "mozilla/ProcessHangMonitor.h" #include "AccessCheck.h" #include "nsGlobalWindow.h" #include "nsAboutProtocolUtils.h" @@ -1113,7 +1112,6 @@ class Watchdog #include "ipc/Nuwa.h" #endif -#define PREF_MAX_SCRIPT_RUN_TIME_CHILD "dom.max_child_script_run_time" #define PREF_MAX_SCRIPT_RUN_TIME_CONTENT "dom.max_script_run_time" #define PREF_MAX_SCRIPT_RUN_TIME_CHROME "dom.max_chrome_script_run_time" @@ -1136,7 +1134,6 @@ class WatchdogManager : public nsIObserver mozilla::Preferences::AddStrongObserver(this, "dom.use_watchdog"); mozilla::Preferences::AddStrongObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CONTENT); mozilla::Preferences::AddStrongObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CHROME); - mozilla::Preferences::AddStrongObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CHILD); } protected: @@ -1150,7 +1147,6 @@ class WatchdogManager : public nsIObserver mozilla::Preferences::RemoveObserver(this, "dom.use_watchdog"); mozilla::Preferences::RemoveObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CONTENT); mozilla::Preferences::RemoveObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CHROME); - mozilla::Preferences::RemoveObserver(this, PREF_MAX_SCRIPT_RUN_TIME_CHILD); } public: @@ -1228,10 +1224,7 @@ class WatchdogManager : public nsIObserver int32_t chromeTime = Preferences::GetInt(PREF_MAX_SCRIPT_RUN_TIME_CHROME, 20); if (chromeTime <= 0) chromeTime = INT32_MAX; - int32_t childTime = Preferences::GetInt(PREF_MAX_SCRIPT_RUN_TIME_CHILD, 3); - if (childTime <= 0) - childTime = INT32_MAX; - mWatchdog->SetMinScriptRunTimeSeconds(std::min(std::min(contentTime, chromeTime), childTime)); + mWatchdog->SetMinScriptRunTimeSeconds(std::min(contentTime, chromeTime)); } } @@ -1348,10 +1341,6 @@ XPCJSRuntime::DefaultJSContextCallback(JSRuntime *rt) void XPCJSRuntime::ActivityCallback(void *arg, bool active) { - if (!active) { - ProcessHangMonitor::ClearHang(); - } - XPCJSRuntime* self = static_cast(arg); self->mWatchdogManager->RecordRuntimeActivity(active); } @@ -1390,16 +1379,13 @@ XPCJSRuntime::InterruptCallback(JSContext *cx) if (!nsContentUtils::IsInitialized()) return true; - bool contentProcess = XRE_GetProcessType() == GeckoProcessType_Content; - // This is at least the second interrupt callback we've received since // returning to the event loop. See how long it's been, and what the limit // is. TimeDuration duration = TimeStamp::NowLoRes() - self->mSlowScriptCheckpoint; bool chrome = nsContentUtils::IsCallerChrome(); - const char *prefName = contentProcess ? PREF_MAX_SCRIPT_RUN_TIME_CHILD - : chrome ? PREF_MAX_SCRIPT_RUN_TIME_CHROME - : PREF_MAX_SCRIPT_RUN_TIME_CONTENT; + const char *prefName = chrome ? PREF_MAX_SCRIPT_RUN_TIME_CHROME + : PREF_MAX_SCRIPT_RUN_TIME_CONTENT; int32_t limit = Preferences::GetInt(prefName, chrome ? 20 : 10); // If there's no limit, or we're within the limit, let it go. @@ -1437,9 +1423,7 @@ XPCJSRuntime::InterruptCallback(JSContext *cx) // The user chose to continue the script. Reset the timer, and disable this // machinery with a pref of the user opted out of future slow-script dialogs. - if (response != nsGlobalWindow::ContinueSlowScriptAndKeepNotifying) - self->mSlowScriptCheckpoint = TimeStamp::NowLoRes(); - + self->mSlowScriptCheckpoint = TimeStamp::NowLoRes(); if (response == nsGlobalWindow::AlwaysContinueSlowScript) Preferences::SetInt(prefName, 0); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 6c77a246ce21..0c1cf4a83e7e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2278,7 +2278,6 @@ pref("editor.positioning.offset", 0); pref("dom.use_watchdog", true); pref("dom.max_chrome_script_run_time", 20); -pref("dom.max_child_script_run_time", 2); pref("dom.max_script_run_time", 10); // If true, ArchiveReader will be enabled @@ -2325,9 +2324,6 @@ pref("dom.ipc.plugins.timeoutSecs", 45); // to a synchronous request before terminating itself. After this // point the child assumes the parent is hung. Currently disabled. pref("dom.ipc.plugins.parentTimeoutSecs", 0); -// How long a plugin in e10s is allowed to process a synchronous IPC -// message before we notify the chrome process of a hang. -pref("dom.ipc.plugins.contentTimeoutSecs", 2); // How long a plugin launch is allowed to take before // we consider it failed. pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45); @@ -2345,7 +2341,6 @@ pref("dom.ipc.tabs.shutdownTimeoutSecs", 5); #else // No timeout in DEBUG builds pref("dom.ipc.plugins.timeoutSecs", 0); -pref("dom.ipc.plugins.contentTimeoutSecs", 0); pref("dom.ipc.plugins.processLaunchTimeoutSecs", 0); pref("dom.ipc.plugins.parentTimeoutSecs", 0); #ifdef XP_WIN diff --git a/testing/marionette/client/marionette/geckoinstance.py b/testing/marionette/client/marionette/geckoinstance.py index 1f0d9c51a0ac..0bc1a1477152 100644 --- a/testing/marionette/client/marionette/geckoinstance.py +++ b/testing/marionette/client/marionette/geckoinstance.py @@ -28,8 +28,7 @@ class GeckoInstance(object): "browser.displayedE10SPrompt.3": 5, "browser.displayedE10SPrompt.4": 5, "browser.tabs.remote.autostart.1": False, - "browser.tabs.remote.autostart.2": False, - "dom.ipc.reportProcessHangs": False} + "browser.tabs.remote.autostart.2": False} def __init__(self, host, port, bin, profile=None, app_args=None, symbols_path=None, gecko_log=None, prefs=None): diff --git a/testing/profiles/prefs_general.js b/testing/profiles/prefs_general.js index 7769d1ba91b6..e18fe96c053d 100644 --- a/testing/profiles/prefs_general.js +++ b/testing/profiles/prefs_general.js @@ -14,8 +14,6 @@ user_pref("dom.forms.color", true); // on for testing user_pref("dom.max_script_run_time", 0); // no slow script dialogs user_pref("hangmonitor.timeout", 0); // no hang monitor user_pref("dom.max_chrome_script_run_time", 0); -user_pref("dom.max_child_script_run_time", 0); -user_pref("dom.ipc.reportProcessHangs", false); // process hang monitor user_pref("dom.popup_maximum", -1); user_pref("dom.send_after_paint_to_content", true); user_pref("dom.successive_dialog_time_limit", 0);