Bug 751949 - Reloading a page when the debuggee is paused results in: ASSERTION: Mismatched calls to ResumeTimeouts; r=rcampbell

This commit is contained in:
Panos Astithas 2012-07-13 13:10:22 +03:00
Родитель e6216ac10d
Коммит 9a42aa2f50
3 изменённых файлов: 89 добавлений и 4 удалений

Просмотреть файл

@ -260,7 +260,8 @@ let DebuggerController = {
* @return boolean
*/
get _isChromeDebugger() {
return !window.parent.content && !this._isRemoteDebugger;
// Directly accessing window.parent.content may throw in some cases.
return !("content" in window.parent) && !this._isRemoteDebugger;
},
/**

Просмотреть файл

@ -99,7 +99,7 @@ BrowserRootActor.prototype = {
}
let actor = this._tabActors.get(browser);
if (!actor) {
actor = new BrowserTabActor(this.conn, browser);
actor = new BrowserTabActor(this.conn, browser, win.gBrowser);
actor.parentID = this.actorID;
this._tabActors.set(browser, actor);
}
@ -188,11 +188,14 @@ BrowserRootActor.prototype.requestTypes = {
* The conection to the client.
* @param aBrowser browser
* The browser instance that contains this tab.
* @param aTabBrowser tabbrowser
* The tabbrowser that can receive nsIWebProgressListener events.
*/
function BrowserTabActor(aConnection, aBrowser)
function BrowserTabActor(aConnection, aBrowser, aTabBrowser)
{
this.conn = aConnection;
this._browser = aBrowser;
this._tabbrowser = aTabBrowser;
this._onWindowCreated = this.onWindowCreated.bind(this);
}
@ -212,6 +215,8 @@ BrowserTabActor.prototype = {
_contextPool: null,
get contextActorPool() { return this._contextPool; },
_pendingNavigation: null,
/**
* Add the specified breakpoint to the default actor pool connection, in order
* to be alive as long as the server is.
@ -250,6 +255,10 @@ BrowserTabActor.prototype = {
*/
disconnect: function BTA_disconnect() {
this._detach();
if (this._progressListener) {
this._progressListener.destroy();
}
},
/**
@ -266,7 +275,11 @@ BrowserTabActor.prototype = {
type: "tabDetached" });
}
if (this._progressListener) {
this._progressListener.destroy();
}
this._browser = null;
this._tabbrowser = null;
},
/**
@ -288,6 +301,7 @@ BrowserTabActor.prototype = {
// Watch for globals being created in this tab.
this.browser.addEventListener("DOMWindowCreated", this._onWindowCreated, true);
this.browser.addEventListener("pageshow", this._onWindowCreated, true);
this._progressListener = new DebuggerProgressListener(this);
this._attached = true;
},
@ -370,6 +384,10 @@ BrowserTabActor.prototype = {
this._detach();
if (this._progressListener) {
this._progressListener.destroy();
}
return { type: "detached" };
},
@ -401,6 +419,10 @@ BrowserTabActor.prototype = {
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.resumeTimeouts();
windowUtils.suppressEventHandling(false);
if (this._pendingNavigation) {
this._pendingNavigation.resume();
this._pendingNavigation = null;
}
},
/**
@ -430,6 +452,68 @@ BrowserTabActor.prototype.requestTypes = {
"detach": BrowserTabActor.prototype.onDetach
};
/**
* The DebuggerProgressListener object is an nsIWebProgressListener which
* handles onStateChange events for the inspected browser. If the user tries to
* navigate away from a paused page, the listener makes sure that the debuggee
* is resumed before the navigation begins.
*
* @param BrowserTabActor aBrowserTabActor
* The tab actor associated with this listener.
*/
function DebuggerProgressListener(aBrowserTabActor) {
this._tabActor = aBrowserTabActor;
this._tabActor._tabbrowser.addProgressListener(this);
}
DebuggerProgressListener.prototype = {
onStateChange:
function DPL_onStateChange(aProgress, aRequest, aFlag, aStatus) {
let isStart = aFlag & Ci.nsIWebProgressListener.STATE_START;
let isStop = aFlag & Ci.nsIWebProgressListener.STATE_STOP;
let isDocument = aFlag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
let isNetwork = aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
let isRequest = aFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST;
let isWindow = aFlag & Ci.nsIWebProgressListener.STATE_IS_WINDOW;
// Skip non-interesting states.
if (isStart && isDocument && isRequest && isNetwork) {
// If the request is about to happen in a new window, we are not concerned
// about the request.
if (aProgress.DOMWindow != this._tabActor.browser.contentWindow) {
return;
}
// If the debuggee is not paused, then proceed normally.
if (this._tabActor.threadActor.state != "paused") {
return;
}
aRequest.suspend();
this._tabActor._pendingNavigation = aRequest;
this._tabActor._detach();
this._needsTabNavigated = true;
} else if (isStop && isWindow && isNetwork && this._needsTabNavigated) {
this._tabActor.conn.send({
from: this._tabActor.actorID,
type: "tabNavigated",
url: this._tabActor.browser.contentDocument.URL
});
this.destroy();
}
},
/**
* Destroy the progress listener instance.
*/
destroy: function DPL_destroy() {
this._tabActor._tabbrowser.removeProgressListener(this);
this._tabActor._progressListener = null;
this._tabActor = null;
}
};
/**
* Registers handlers for new request types defined dynamically. This is used
* for example by add-ons to augment the functionality of the tab actor.

Просмотреть файл

@ -543,7 +543,7 @@ ThreadActor.prototype = {
/**
* Handle a protocol request to pause the debuggee.
*/
onInterrupt: function TA_onScripts(aRequest) {
onInterrupt: function TA_onInterrupt(aRequest) {
if (this.state == "exited") {
return { type: "exited" };
} else if (this.state == "paused") {