diff options
-rw-r--r-- | webkit/glue/devtools/js/debugger_agent.js | 39 | ||||
-rw-r--r-- | webkit/glue/devtools/js/tests.js | 75 |
2 files changed, 92 insertions, 22 deletions
diff --git a/webkit/glue/devtools/js/debugger_agent.js b/webkit/glue/devtools/js/debugger_agent.js index 4361ccc..3eec221 100644 --- a/webkit/glue/devtools/js/debugger_agent.js +++ b/webkit/glue/devtools/js/debugger_agent.js @@ -75,6 +75,21 @@ devtools.DebuggerAgent = function() { this.requestScriptsWhenContextIdSet_ = false; /** + * Whether the agent is waiting for initial scripts response. + * @type {boolean} + */ + this.waitingForInitialScriptsResponse_ = false; + + /** + * If backtrace response is received when initial scripts response + * is not yet processed the backtrace handling will be postponed until + * after the scripts response processing. The handler bound to its arguments + * and this agent will be stored in this field then. + * @type {?function()} + */ + this.pendingBacktraceResponseHandler_ = null; + + /** * Active profiler modules flags. * @type {number} */ @@ -138,6 +153,8 @@ devtools.DebuggerAgent.prototype.reset = function() { // No need to request scripts since they all will be pushed in AfterCompile // events. this.requestScriptsWhenContextIdSet_ = false; + this.waitingForInitialScriptsResponse_ = false; + this.parsedScripts_ = {}; this.requestNumberToBreakpointInfo_ = {}; this.callFrames_ = []; @@ -173,6 +190,7 @@ devtools.DebuggerAgent.prototype.initUI = function() { } return; } + this.waitingForInitialScriptsResponse_ = true; // Script list should be requested only when current context id is known. RemoteDebuggerAgent.GetContextId(); this.requestScriptsWhenContextIdSet_ = true; @@ -823,6 +841,14 @@ devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) { if (contextId == debuggerAgent.contextId_) { debuggerAgent.handleScriptsResponse_(msg); } + + // We received initial scripts response so flush the flag and + // see if there is an unhandled backtrace response. + debuggerAgent.waitingForInitialScriptsResponse_ = false; + if (debuggerAgent.pendingBacktraceResponseHandler_) { + debuggerAgent.pendingBacktraceResponseHandler_(); + debuggerAgent.pendingBacktraceResponseHandler_ = null; + } }; } }; @@ -1065,6 +1091,19 @@ devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function( * @param {devtools.DebuggerMessage} msg */ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { + if (this.waitingForInitialScriptsResponse_) { + this.pendingBacktraceResponseHandler_ = + this.doHandleBacktraceResponse_.bind(this, msg); + } else { + this.doHandleBacktraceResponse_(msg); + } +}; + + +/** + * @param {devtools.DebuggerMessage} msg + */ +devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg) { var frames = msg.getBody().frames; this.callFrames_ = []; for (var i = 0; i < frames.length; ++i) { diff --git a/webkit/glue/devtools/js/tests.js b/webkit/glue/devtools/js/tests.js index 0a0cdd6..b3c8c93 100644 --- a/webkit/glue/devtools/js/tests.js +++ b/webkit/glue/devtools/js/tests.js @@ -643,19 +643,39 @@ TestSuite.prototype.testPauseWhenLoadingDevTools = function() { this.showPanel('scripts'); var test = this; + var expectations = { + functionsOnStack: ['callDebugger'], + lineNumber: 8, + lineText: ' debugger;' + }; + + // Script execution can already be paused. if (WebInspector.currentPanel.paused) { var callFrame = WebInspector.currentPanel.sidebarPanes.callstack.selectedCallFrame; - this.assertEquals('callDebugger', callFrame.functionName); + this.assertEquals(expectations.functionsOnStack[0], + callFrame.functionName); + var callbackInvoked = false; + this._checkSourceFrameWhenLoaded(expectations, function() { + callbackInvoked = true; + if (test.controlTaken_) { + test.releaseControl(); + } + }); + if (!callbackInvoked) { + test.takeControl(); + } return; } - this.addSniffer( - WebInspector, - 'pausedScript', - function(callFrames) { - test.assertEquals('callDebugger', callFrames[0].functionName); + this._waitForScriptPause( + { + functionsOnStack: ['callDebugger'], + lineNumber: 8, + lineText: ' debugger;' + }, + function() { test.releaseControl(); }); this.takeControl(); @@ -1041,24 +1061,35 @@ TestSuite.prototype._waitForScriptPause = function(expectations, callback) { expectations.functionsOnStack.join(','), functionsOnStack.join(','), 'Unexpected stack.'); - checkSourceFrameWhenLoaded(); + // Check that execution line where the script is paused is + // expected one. + test._checkSourceFrameWhenLoaded(expectations, callback); }); +}; - // Check that execution line where the script is paused is expected one. - function checkSourceFrameWhenLoaded() { - var frame = WebInspector.currentPanel.visibleView.sourceFrame; - if (frame._isContentLoaded()) { - checkExecLine(); - } else { - frame.addEventListener('content loaded', checkExecLine); - } - function checkExecLine() { - test._checkExecutionLine(frame, expectations.lineNumber, - expectations.lineText); - // Make sure we don't listen anymore. - frame.removeEventListener('content loaded', checkExecLine); - callback(); - } + +/** + * Waits for current source frame to load, checks expectations, and invokes + * the callback. + * @param {Object} expectations Dictionary of expectations + * @param {function():void} callback + */ +TestSuite.prototype._checkSourceFrameWhenLoaded = function( + expectations, callback) { + var test = this; + + var frame = WebInspector.currentPanel.visibleView.sourceFrame; + if (frame._isContentLoaded()) { + checkExecLine(); + } else { + frame.addEventListener('content loaded', checkExecLine); + } + function checkExecLine() { + test._checkExecutionLine(frame, expectations.lineNumber, + expectations.lineText); + // Make sure we don't listen anymore. + frame.removeEventListener('content loaded', checkExecLine); + callback(); } }; |