Bug 1275942 - Add option to wait for debugger on startup. r=jdescottes

Adds a `--wait-for-jsdebugger` CLI option which will spin the event loop until
the debugger connects to allow debugging _some_ startup code paths, such as the
beginning of the `browser.js` file.

Startup code paths that run before the DevTools CLI handler will be missed for
now.  This can be improved in the future if we move this to an earlier phase of
app startup.

MozReview-Commit-ID: J1A8lWLETGY
This commit is contained in:
J. Ryan Stinnett
2017-03-02 14:50:30 -06:00
parent a2a1a1e978
commit 4999247ce4
3 changed files with 37 additions and 4 deletions

View File

@@ -13,7 +13,7 @@
"use strict";
const { interfaces: Ci, utils: Cu } = Components;
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const kDebuggerPrefs = [
"devtools.debugger.remote-enabled",
"devtools.chrome.enabled"
@@ -124,9 +124,28 @@ DevToolsStartup.prototype = {
if (!this._isRemoteDebuggingEnabled()) {
return;
}
let devtoolsThreadResumed = false;
let pauseOnStartup = cmdLine.handleFlag("wait-for-jsdebugger", false);
if (pauseOnStartup) {
let observe = function (subject, topic, data) {
devtoolsThreadResumed = true;
Services.obs.removeObserver(observe, "devtools-thread-resumed");
};
Services.obs.addObserver(observe, "devtools-thread-resumed", false);
}
const { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
BrowserToolboxProcess.init();
if (pauseOnStartup) {
// Spin the event loop until the debugger connects.
let thread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
while (!devtoolsThreadResumed) {
thread.processNextEvent(true);
}
}
if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
cmdLine.preventDefault = true;
}
@@ -203,6 +222,9 @@ DevToolsStartup.prototype = {
/* eslint-disable max-len */
helpInfo: " --jsconsole Open the Browser Console.\n" +
" --jsdebugger Open the Browser Toolbox.\n" +
" --wait-for-jsdebugger Spin event loop until JS debugger connects.\n" +
" Enables debugging (some) application startup code paths.\n" +
" Only has an effect when `--jsdebugger` is also supplied.\n" +
" --devtools Open DevTools on initial load.\n" +
" --start-debugger-server [ws:][ <port> | <path> ] Start the debugger server on\n" +
" a TCP port or Unix domain socket path. Defaults to TCP port\n" +

View File

@@ -50,7 +50,18 @@ function ChromeActor(connection) {
if (!window) {
window = Services.wm.getMostRecentWindow(null);
}
// On xpcshell, there is no window/docshell
// We really want _some_ window at least, so fallback to the hidden window if
// there's nothing else (such as during early startup).
if (!window) {
try {
window = Services.appShell.hiddenDOMWindow;
} catch (e) {
// On XPCShell, the above line will throw.
}
}
// On XPCShell, there is no window/docshell
let docShell = window ? window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
: null;

View File

@@ -1020,8 +1020,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
let packet = this._resumed();
this._popThreadPause();
// Tell anyone who cares of the resume (as of now, that's the xpcshell
// harness)
// Tell anyone who cares of the resume (as of now, that's the xpcshell harness and
// devtools-startup.js when handling the --wait-for-jsdebugger flag)
if (Services.obs) {
Services.obs.notifyObservers(this, "devtools-thread-resumed", null);
}