Commit 98d3b3a9 authored by aandrey@chromium.org's avatar aandrey@chromium.org

DevTools: Make frameworks work with "custom" breakpoints (DOM, XHR, Events).

BUG=267592
R=pfeldman, yurys

Review URL: https://codereview.chromium.org/304563002

git-svn-id: svn://svn.chromium.org/blink/trunk@175136 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 81ba4130
...@@ -152,6 +152,46 @@ InspectorTest.resumeExecution = function(callback) ...@@ -152,6 +152,46 @@ InspectorTest.resumeExecution = function(callback)
InspectorTest.waitUntilResumed(callback); InspectorTest.waitUntilResumed(callback);
}; };
InspectorTest.waitUntilPausedAndDumpStackAndResume = function(callback, options)
{
InspectorTest.waitUntilPaused(paused);
InspectorTest.addSniffer(WebInspector.CallStackSidebarPane.prototype, "setStatus", setStatus);
var caption;
var callFrames;
var asyncStackTrace;
function setStatus(status)
{
if (typeof status === "string")
caption = status;
else
caption = status.textContent;
if (callFrames)
step1();
}
function paused(frames, reason, breakpointIds, async)
{
callFrames = frames;
asyncStackTrace = async;
if (typeof caption === "string")
step1();
}
function step1()
{
InspectorTest.captureStackTrace(callFrames, asyncStackTrace, options);
InspectorTest.addResult(caption);
InspectorTest.runAfterPendingDispatches(step2);
}
function step2()
{
InspectorTest.resumeExecution(InspectorTest.safeWrap(callback));
}
};
InspectorTest.captureStackTrace = function(callFrames, asyncStackTrace, options) InspectorTest.captureStackTrace = function(callFrames, asyncStackTrace, options)
{ {
InspectorTest.addResult(InspectorTest.captureStackTraceIntoString(callFrames, asyncStackTrace, options)); InspectorTest.addResult(InspectorTest.captureStackTraceIntoString(callFrames, asyncStackTrace, options));
...@@ -164,9 +204,13 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace ...@@ -164,9 +204,13 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace
function printCallFrames(callFrames) function printCallFrames(callFrames)
{ {
var printed = 0;
for (var i = 0; i < callFrames.length; i++) { for (var i = 0; i < callFrames.length; i++) {
var frame = callFrames[i]; var frame = callFrames[i];
var script = WebInspector.debuggerModel.scriptForId(frame.location().scriptId); var script = WebInspector.debuggerModel.scriptForId(frame.location().scriptId);
var isFramework = script.isFramework();
if (options.dropFrameworkCallFrames && isFramework)
continue;
var url; var url;
var lineNumber; var lineNumber;
if (script) { if (script) {
...@@ -176,11 +220,12 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace ...@@ -176,11 +220,12 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace
url = "(internal script)"; url = "(internal script)";
lineNumber = "(line number)"; lineNumber = "(line number)";
} }
var s = " " + i + ") " + frame.functionName + " (" + url + (options.dropLineNumbers ? "" : ":" + lineNumber) + ")"; var s = (isFramework ? " * " : " ") + (printed++) + ") " + frame.functionName + " (" + url + (options.dropLineNumbers ? "" : ":" + lineNumber) + ")";
results.push(s); results.push(s);
if (options.printReturnValue && frame.returnValue()) if (options.printReturnValue && frame.returnValue())
results.push(" <return>: " + frame.returnValue().description); results.push(" <return>: " + frame.returnValue().description);
} }
return printed;
} }
results.push("Call stack:"); results.push("Call stack:");
...@@ -188,7 +233,9 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace ...@@ -188,7 +233,9 @@ InspectorTest.captureStackTraceIntoString = function(callFrames, asyncStackTrace
while (asyncStackTrace) { while (asyncStackTrace) {
results.push(" [" + (asyncStackTrace.description || "Async Call") + "]"); results.push(" [" + (asyncStackTrace.description || "Async Call") + "]");
printCallFrames(WebInspector.DebuggerModel.CallFrame.fromPayloadArray(WebInspector.targetManager.activeTarget(), asyncStackTrace.callFrames)); var printed = printCallFrames(WebInspector.DebuggerModel.CallFrame.fromPayloadArray(WebInspector.targetManager.activeTarget(), asyncStackTrace.callFrames));
if (!printed)
results.pop();
if (asyncStackTrace.callFrames.peekLast().functionName === "testFunction") if (asyncStackTrace.callFrames.peekLast().functionName === "testFunction")
break; break;
asyncStackTrace = asyncStackTrace.asyncStackTrace; asyncStackTrace = asyncStackTrace.asyncStackTrace;
......
Tests the async call stacks and framework black-boxing features working together.
Debugger was enabled.
Set timer for test function.
Call stack:
0) callback2 (async-callstack-and-framework-black-box.html:30)
1) Framework_inner1 (framework.js:59)
[setTimeout]
0) Framework.schedule (framework.js:45)
1) Framework_willSchedule (framework.js:51)
2) window.callbackFromFramework (async-callstack-and-framework-black-box.html:10)
3) Framework_inner2 (framework.js:63)
[setTimeout]
0) Framework.schedule (framework.js:45)
1) Framework_willSchedule (framework.js:51)
[setTimeout]
0) Framework.schedule (framework.js:45)
1) Framework.doSomeAsyncChainCalls (framework.js:67)
2) callback1 (async-callstack-and-framework-black-box.html:25)
3) Framework.safeRun (framework.js:8)
4) Framework.safeRun (framework.js:10)
5) timeout1 (async-callstack-and-framework-black-box.html:20)
[setTimeout]
0) testFunction (async-callstack-and-framework-black-box.html:15)
Visible call stack:
1) callback2 (async-callstack-and-framework-black-box.html:30)
[setTimeout (async)]
2) window.callbackFromFramework (async-callstack-and-framework-black-box.html:10)
[setTimeout (async)]
3) callback1 (async-callstack-and-framework-black-box.html:25)
4) timeout1 (async-callstack-and-framework-black-box.html:20)
[setTimeout (async)]
5) testFunction (async-callstack-and-framework-black-box.html:15)
Debugger was disabled.
...@@ -100,7 +100,7 @@ function test() ...@@ -100,7 +100,7 @@ function test()
InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on rootElement."); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on rootElement.");
InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')"); InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')");
InspectorTest.addResult("Append childElement to rootElement."); InspectorTest.addResult("Append childElement to rootElement.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
} }
}, },
...@@ -109,7 +109,7 @@ function test() ...@@ -109,7 +109,7 @@ function test()
InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit when appending a grandchild."); InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit when appending a grandchild.");
InspectorTest.evaluateInPageWithTimeout("appendElement('childElement', 'grandchildElement')"); InspectorTest.evaluateInPageWithTimeout("appendElement('childElement', 'grandchildElement')");
InspectorTest.addResult("Append grandchildElement to childElement."); InspectorTest.addResult("Append grandchildElement to childElement.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
}, },
function testRemoveChild(next) function testRemoveChild(next)
...@@ -117,7 +117,7 @@ function test() ...@@ -117,7 +117,7 @@ function test()
InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit when removing a child."); InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit when removing a child.");
InspectorTest.evaluateInPageWithTimeout("removeElement('grandchildElement')"); InspectorTest.evaluateInPageWithTimeout("removeElement('grandchildElement')");
InspectorTest.addResult("Remove grandchildElement."); InspectorTest.addResult("Remove grandchildElement.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
}, },
function testInnerHTML(next) function testInnerHTML(next)
...@@ -125,7 +125,7 @@ function test() ...@@ -125,7 +125,7 @@ function test()
InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit exactly once when setting innerHTML."); InspectorTest.addResult("Test that 'Subtree Modified' breakpoint is hit exactly once when setting innerHTML.");
InspectorTest.evaluateInPageWithTimeout("setInnerHTML('childElement', '<br><br>')"); InspectorTest.evaluateInPageWithTimeout("setInnerHTML('childElement', '<br><br>')");
InspectorTest.addResult("Set childElement.innerHTML."); InspectorTest.addResult("Set childElement.innerHTML.");
waitUntilPausedAndDumpStack(step2); InspectorTest.waitUntilPausedAndDumpStackAndResume(step2);
function step2() function step2()
{ {
...@@ -149,7 +149,7 @@ function test() ...@@ -149,7 +149,7 @@ function test()
InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement.");
InspectorTest.evaluateInPageWithTimeout("modifyAttribute('rootElement', 'data-test', 'foo')"); InspectorTest.evaluateInPageWithTimeout("modifyAttribute('rootElement', 'data-test', 'foo')");
InspectorTest.addResult("Modify rootElement data-test attribute."); InspectorTest.addResult("Modify rootElement data-test attribute.");
waitUntilPausedAndDumpStack(step2); InspectorTest.waitUntilPausedAndDumpStackAndResume(step2);
function step2(callFrames) function step2(callFrames)
{ {
...@@ -165,7 +165,7 @@ function test() ...@@ -165,7 +165,7 @@ function test()
InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement.");
InspectorTest.evaluateInPageWithTimeout("modifyAttrNode('rootElement', 'data-test', 'bar')"); InspectorTest.evaluateInPageWithTimeout("modifyAttrNode('rootElement', 'data-test', 'bar')");
InspectorTest.addResult("Modify rootElement data-test attribute."); InspectorTest.addResult("Modify rootElement data-test attribute.");
waitUntilPausedAndDumpStack(step2); InspectorTest.waitUntilPausedAndDumpStackAndResume(step2);
function step2(callFrames) function step2(callFrames)
{ {
...@@ -181,7 +181,7 @@ function test() ...@@ -181,7 +181,7 @@ function test()
InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement.");
InspectorTest.evaluateInPageWithTimeout("setAttrNode('rootElement', 'data-foo', 'bar')"); InspectorTest.evaluateInPageWithTimeout("setAttrNode('rootElement', 'data-foo', 'bar')");
InspectorTest.addResult("Modify rootElement data-foo attribute."); InspectorTest.addResult("Modify rootElement data-foo attribute.");
waitUntilPausedAndDumpStack(step2); InspectorTest.waitUntilPausedAndDumpStackAndResume(step2);
function step2(callFrames) function step2(callFrames)
{ {
...@@ -197,7 +197,7 @@ function test() ...@@ -197,7 +197,7 @@ function test()
InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement.");
InspectorTest.evaluateInPageWithTimeout("modifyStyleAttribute('rootElement', 'color', 'green')"); InspectorTest.evaluateInPageWithTimeout("modifyStyleAttribute('rootElement', 'color', 'green')");
InspectorTest.addResult("Modify rootElement style.color attribute."); InspectorTest.addResult("Modify rootElement style.color attribute.");
waitUntilPausedAndDumpStack(step2); InspectorTest.waitUntilPausedAndDumpStackAndResume(step2);
function step2(callFrames) function step2(callFrames)
{ {
...@@ -217,7 +217,7 @@ function test() ...@@ -217,7 +217,7 @@ function test()
InspectorTest.addResult("Set 'Node Removed' DOM breakpoint on elementToRemove."); InspectorTest.addResult("Set 'Node Removed' DOM breakpoint on elementToRemove.");
InspectorTest.evaluateInPageWithTimeout("removeElement('elementToRemove')"); InspectorTest.evaluateInPageWithTimeout("removeElement('elementToRemove')");
InspectorTest.addResult("Remove elementToRemove."); InspectorTest.addResult("Remove elementToRemove.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
} }
}, },
...@@ -243,7 +243,7 @@ function test() ...@@ -243,7 +243,7 @@ function test()
{ {
InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')"); InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')");
InspectorTest.addResult("Append childElement to rootElement."); InspectorTest.addResult("Append childElement to rootElement.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
} }
}, },
...@@ -259,7 +259,7 @@ function test() ...@@ -259,7 +259,7 @@ function test()
InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on author shadow root."); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on author shadow root.");
InspectorTest.evaluateInPageWithTimeout("appendElementToAuthorShadowRoot('childElement')"); InspectorTest.evaluateInPageWithTimeout("appendElementToAuthorShadowRoot('childElement')");
InspectorTest.addResult("Append childElement to author shadow root."); InspectorTest.addResult("Append childElement to author shadow root.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
} }
}, },
...@@ -287,49 +287,11 @@ function test() ...@@ -287,49 +287,11 @@ function test()
{ {
InspectorTest.evaluateInPageWithTimeout("appendElementToAuthorShadowTree('outerElement', 'childElement')"); InspectorTest.evaluateInPageWithTimeout("appendElementToAuthorShadowTree('outerElement', 'childElement')");
InspectorTest.addResult("Append childElement to outerElement."); InspectorTest.addResult("Append childElement to outerElement.");
waitUntilPausedAndDumpStack(next); InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
} }
} }
]); ]);
function waitUntilPausedAndDumpStack(callback)
{
InspectorTest.waitUntilPaused(paused);
InspectorTest.addSniffer(WebInspector.CallStackSidebarPane.prototype, "setStatus", setStatus);
var caption;
var callFrames;
function setStatus(status)
{
if (typeof status === "string")
caption = status;
else
caption = status.textContent;
if (callFrames)
step1();
}
function paused(frames)
{
callFrames = frames;
if (typeof caption === "string")
step1();
}
function step1()
{
InspectorTest.captureStackTrace(callFrames);
InspectorTest.addResult(caption);
InspectorTest.runAfterPendingDispatches(step2);
}
function step2()
{
InspectorTest.resumeExecution(InspectorTest.safeWrap(callback));
}
}
} }
</script> </script>
......
Tests framework black-boxing on DOM, XHR and Event breakpoints.
Debugger was enabled.
Running: testDOMBreakpoint
Call stack:
* 0) Framework.appendChild (framework.js:72)
1) appendElement (frameworks-dom-xhr-event-breakpoints.html:14)
2) (:1)
Paused on a "Subtree Modified" breakpoint set on div#rootElement, because a new child was added to that node.
Running: testXHRBreakpoint
Call stack:
* 0) Framework.sendXHR (framework.js:79)
1) sendXHR (frameworks-dom-xhr-event-breakpoints.html:19)
2) (:1)
Paused on a XMLHttpRequest.
Running: testEventListenerBreakpoint
Call stack:
0) testElementClicked (frameworks-dom-xhr-event-breakpoints.html:26)
* 1) Framework_bound (framework.js:105)
* 2) Framework_eventListener (framework.js:87)
3) addListenerAndClick (frameworks-dom-xhr-event-breakpoints.html:31)
4) (:1)
Paused on a "click" Event Listener.
Debugger was disabled.
<html>
<head>
<script src="../../../http/tests/inspector/inspector-test.js"></script>
<script src="../../../http/tests/inspector/elements-test.js"></script>
<script src="../../../http/tests/inspector/debugger-test.js"></script>
<script src="resources/framework.js"></script>
<script>
function appendElement(parentId, childId)
{
var child = document.createElement("div");
child.id = childId;
var parent = document.getElementById(parentId);
Framework.appendChild(parent, child);
}
function sendXHR(url)
{
Framework.sendXHR(url);
}
function addListenerAndClick()
{
function testElementClicked()
{
return 0;
}
var button = document.getElementById("test");
Framework.addEventListener(button, "click", Framework.bind(testElementClicked, null), true);
button.click();
}
function test()
{
var frameworkRegexString = "/framework\\.js$";
WebInspector.experimentsSettings.frameworksDebuggingSupport.enableForTest();
WebInspector.settings.skipStackFramesSwitch.set(true);
WebInspector.settings.skipStackFramesPattern.set(frameworkRegexString);
InspectorTest.setQuiet(true);
InspectorTest.runDebuggerTestSuite([
function testDOMBreakpoint(next)
{
InspectorTest.nodeWithId("rootElement", step1);
function step1(node)
{
var pane = WebInspector.domBreakpointsSidebarPane;
pane._setBreakpoint(node, pane._breakpointTypes.SubtreeModified, true);
InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')");
InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
}
},
function testXHRBreakpoint(next)
{
var pane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints;
pane._setBreakpoint("foo", true);
InspectorTest.evaluateInPageWithTimeout("sendXHR('/foo?a=b')");
InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
},
function testEventListenerBreakpoint(next)
{
var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints;
pane._setBreakpoint("listener:click");
InspectorTest.evaluateInPageWithTimeout("addListenerAndClick()");
InspectorTest.waitUntilPausedAndDumpStackAndResume(next);
}
]);
}
</script>
</head>
<body onload="runTest()">
<p>
Tests framework black-boxing on DOM, XHR and Event breakpoints.
</p>
<div id="rootElement"></div>
<input type=button id="test"></input>
</body>
</html>
Tests the skip stack frames feature when stepping.
Debugger was enabled.
Set timer for test function.
Call stack:
0) test1 (frameworks-skip-step-in.html:23)
1) testFunction (frameworks-skip-step-in.html:11)
Call stack:
0) test2 (frameworks-skip-step-in.html:29)
1) testFunction (frameworks-skip-step-in.html:11)
Call stack:
0) callback (frameworks-skip-step-in.html:16)
* 1) Framework.safeRun (framework.js:8)
* 2) Framework.safeRun (framework.js:10)
3) test3 (frameworks-skip-step-in.html:34)
4) testFunction (frameworks-skip-step-in.html:11)
Call stack:
0) test4 (frameworks-skip-step-in.html:41)
1) testFunction (frameworks-skip-step-in.html:11)
Call stack:
0) callback (frameworks-skip-step-in.html:16)
* 1) Framework.safeRun (framework.js:8)
* 2) Framework.safeRun (framework.js:13)
* 3) Framework.safeRun (framework.js:10)
4) test5 (frameworks-skip-step-in.html:46)
5) testFunction (frameworks-skip-step-in.html:11)
Debugger was disabled.
...@@ -51,15 +51,14 @@ function test() ...@@ -51,15 +51,14 @@ function test()
var frameworkRegexString = "/framework\\.js$"; var frameworkRegexString = "/framework\\.js$";
var totalDebuggerStatements = 5; var totalDebuggerStatements = 5;
WebInspector.experimentsSettings.frameworksDebuggingSupport.enableForTest();
WebInspector.settings.skipStackFramesSwitch.set(true);
WebInspector.settings.skipStackFramesPattern.set(frameworkRegexString);
InspectorTest.setQuiet(true); InspectorTest.setQuiet(true);
InspectorTest.startDebuggerTest(step1); InspectorTest.startDebuggerTest(step1);
function step1() function step1()
{
DebuggerAgent.skipStackFrames(frameworkRegexString, step2);
}
function step2()
{ {
InspectorTest.runTestFunctionAndWaitUntilPaused(didPause); InspectorTest.runTestFunctionAndWaitUntilPaused(didPause);
} }
......
Tests the async call stacks and framework black-boxing features working together.
Debugger was enabled.
Set timer for test function.
Call stack:
0) callback2 (frameworks-with-async-callstack.html:30)
* 1) Framework_inner1 (framework.js:59)
[setTimeout]
* 0) Framework.schedule (framework.js:45)
* 1) Framework_willSchedule (framework.js:51)
2) window.callbackFromFramework (frameworks-with-async-callstack.html:10)
* 3) Framework_inner2 (framework.js:63)
[setTimeout]
* 0) Framework.schedule (framework.js:45)
* 1) Framework_willSchedule (framework.js:51)
[setTimeout]
* 0) Framework.schedule (framework.js:45)
* 1) Framework.doSomeAsyncChainCalls (framework.js:67)
2) callback1 (frameworks-with-async-callstack.html:25)
* 3) Framework.safeRun (framework.js:8)
* 4) Framework.safeRun (framework.js:10)
5) timeout1 (frameworks-with-async-callstack.html:20)
[setTimeout]
0) testFunction (frameworks-with-async-callstack.html:15)
Printing visible call stack:
Call stack:
0) callback2 (frameworks-with-async-callstack.html:30)
[setTimeout]
0) window.callbackFromFramework (frameworks-with-async-callstack.html:10)
[setTimeout]
0) callback1 (frameworks-with-async-callstack.html:25)
1) timeout1 (frameworks-with-async-callstack.html:20)
[setTimeout]
0) testFunction (frameworks-with-async-callstack.html:15)
Debugger was disabled.
...@@ -54,23 +54,9 @@ function test() ...@@ -54,23 +54,9 @@ function test()
function didPause(callFrames, reason, breakpointIds, asyncStackTrace) function didPause(callFrames, reason, breakpointIds, asyncStackTrace)
{ {
InspectorTest.captureStackTrace(callFrames, asyncStackTrace); InspectorTest.captureStackTrace(callFrames, asyncStackTrace, { "dropFrameworkCallFrames": false });
InspectorTest.addResult("\nPrinting visible call stack:");
InspectorTest.addResult("\nVisible call stack:"); InspectorTest.captureStackTrace(callFrames, asyncStackTrace, { "dropFrameworkCallFrames": true });
var callStackPane = WebInspector.panels.sources.sidebarPanes.callstack;
var placards = callStackPane.placards;
var lastPlacard = null;
for (var i = 0, index = 0; i < placards.length; ++i) {
var placard = placards[i];
if (placard.isHidden())
continue;
if (lastPlacard && placard._asyncPlacard !== lastPlacard._asyncPlacard)
InspectorTest.addResult(" [" + placard._asyncPlacard.title + "]");
InspectorTest.addResult(" " + (++index) + ") " + placard.title + " (" + placard.subtitle + ")");
lastPlacard = placard;
}
InspectorTest.completeDebuggerTest(); InspectorTest.completeDebuggerTest();
} }
} }
......
...@@ -66,3 +66,47 @@ Framework.doSomeAsyncChainCalls = function(callback) ...@@ -66,3 +66,47 @@ Framework.doSomeAsyncChainCalls = function(callback)
}); });
Framework.schedule(func2); Framework.schedule(func2);
} }
Framework.appendChild = function(parent, child)
{
parent.appendChild(child);
}
Framework.sendXHR = function(url)
{
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.send();
}
Framework.addEventListener = function(element, eventType, listener, capture)
{
function Framework_eventListener()
{
if (listener)
listener();
}
function Framework_remover()
{
element.removeEventListener(eventType, Framework_eventListener, capture);
}
element.addEventListener(eventType, Framework_eventListener, capture);
return Framework_remover;
}
Framework.bind = function(func, thisObject, var_args)
{
var args = Array.prototype.slice.call(arguments, 2);
function Framework_bound(var_args)
{
return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments)));
}
Framework_bound.toString = function()
{
return "Framework_bound: " + func;
};
return Framework_bound;
}
Tests the skip stack frames feature when stepping.
Debugger was enabled.
Set timer for test function.
Call stack:
0) test1 (skip-stack-frames-steps.html:23)
1) testFunction (skip-stack-frames-steps.html:11)
Call stack:
0) test2 (skip-stack-frames-steps.html:29)
1) testFunction (skip-stack-frames-steps.html:11)
Call stack:
0) callback (skip-stack-frames-steps.html:16)
1) Framework.safeRun (framework.js:8)
2) Framework.safeRun (framework.js:10)
3) test3 (skip-stack-frames-steps.html:34)
4) testFunction (skip-stack-frames-steps.html:11)
Call stack:
0) test4 (skip-stack-frames-steps.html:41)
1) testFunction (skip-stack-frames-steps.html:11)
Call stack:
0) callback (skip-stack-frames-steps.html:16)
1) Framework.safeRun (framework.js:8)
2) Framework.safeRun (framework.js:13)
3) Framework.safeRun (framework.js:10)
4) test5 (skip-stack-frames-steps.html:46)
5) testFunction (skip-stack-frames-steps.html:11)
Debugger was disabled.
...@@ -104,6 +104,7 @@ InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedSc ...@@ -104,6 +104,7 @@ InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedSc
, m_frontend(0) , m_frontend(0)
, m_pausedScriptState(nullptr) , m_pausedScriptState(nullptr)
, m_javaScriptPauseScheduled(false) , m_javaScriptPauseScheduled(false)
, m_debuggerStepScheduled(false)
, m_listener(0) , m_listener(0)
, m_skipStepInCount(numberOfStepsBeforeStepOut) , m_skipStepInCount(numberOfStepsBeforeStepOut)
, m_skipAllPauses(false) , m_skipAllPauses(false)
...@@ -471,8 +472,7 @@ String InspectorDebuggerAgent::scriptURL(JavaScriptCallFrame* frame) ...@@ -471,8 +472,7 @@ String InspectorDebuggerAgent::scriptURL(JavaScriptCallFrame* frame)
ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause() ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause()
{ {
if (m_skipAllPauses) // FIXME: Fast return: if (!m_cachedSkipStackRegExp && !has_any_anti_breakpoint) return ScriptDebugListener::NoSkip;
return ScriptDebugListener::Continue;
RefPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoScopes(); RefPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoScopes();
if (!topFrame) if (!topFrame)
...@@ -522,17 +522,8 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptio ...@@ -522,17 +522,8 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptio
return ScriptDebugListener::NoSkip; return ScriptDebugListener::NoSkip;
} }
ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipBreakpointPause()
{
if (m_skipAllPauses)
return ScriptDebugListener::Continue;
return ScriptDebugListener::NoSkip;
}
ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause() ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause()
{ {
if (m_skipAllPauses)
return ScriptDebugListener::Continue;
if (!m_cachedSkipStackRegExp) if (!m_cachedSkipStackRegExp)
return ScriptDebugListener::NoSkip; return ScriptDebugListener::NoSkip;
...@@ -642,6 +633,7 @@ void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Deb ...@@ -642,6 +633,7 @@ void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Deb
return; return;
m_breakReason = breakReason; m_breakReason = breakReason;
m_breakAuxData = data; m_breakAuxData = data;
m_debuggerStepScheduled = true;
scriptDebugServer().setPauseOnNextStatement(true); scriptDebugServer().setPauseOnNextStatement(true);
} }
...@@ -650,6 +642,7 @@ void InspectorDebuggerAgent::cancelPauseOnNextStatement() ...@@ -650,6 +642,7 @@ void InspectorDebuggerAgent::cancelPauseOnNextStatement()
if (m_javaScriptPauseScheduled) if (m_javaScriptPauseScheduled)
return; return;
clearBreakDetails(); clearBreakDetails();
m_debuggerStepScheduled = false;
scriptDebugServer().setPauseOnNextStatement(false); scriptDebugServer().setPauseOnNextStatement(false);
} }
...@@ -752,14 +745,16 @@ void InspectorDebuggerAgent::pause(ErrorString*) ...@@ -752,14 +745,16 @@ void InspectorDebuggerAgent::pause(ErrorString*)
if (m_javaScriptPauseScheduled) if (m_javaScriptPauseScheduled)
return; return;
clearBreakDetails(); clearBreakDetails();
scriptDebugServer().setPauseOnNextStatement(true);
m_javaScriptPauseScheduled = true; m_javaScriptPauseScheduled = true;
m_debuggerStepScheduled = false;
scriptDebugServer().setPauseOnNextStatement(true);
} }
void InspectorDebuggerAgent::resume(ErrorString* errorString) void InspectorDebuggerAgent::resume(ErrorString* errorString)
{ {
if (!assertPaused(errorString)) if (!assertPaused(errorString))
return; return;
m_debuggerStepScheduled = false;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().continueProgram(); scriptDebugServer().continueProgram();
} }
...@@ -787,6 +782,7 @@ void InspectorDebuggerAgent::stepOver(ErrorString* errorString, const String* ca ...@@ -787,6 +782,7 @@ void InspectorDebuggerAgent::stepOver(ErrorString* errorString, const String* ca
ScriptValue frame = resolveCallFrame(errorString, callFrameId); ScriptValue frame = resolveCallFrame(errorString, callFrameId);
if (!errorString->isEmpty()) if (!errorString->isEmpty())
return; return;
m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().stepOverStatement(frame); scriptDebugServer().stepOverStatement(frame);
} }
...@@ -795,6 +791,7 @@ void InspectorDebuggerAgent::stepInto(ErrorString* errorString) ...@@ -795,6 +791,7 @@ void InspectorDebuggerAgent::stepInto(ErrorString* errorString)
{ {
if (!assertPaused(errorString)) if (!assertPaused(errorString))
return; return;
m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().stepIntoStatement(); scriptDebugServer().stepIntoStatement();
if (m_listener) if (m_listener)
...@@ -808,6 +805,7 @@ void InspectorDebuggerAgent::stepOut(ErrorString* errorString, const String* cal ...@@ -808,6 +805,7 @@ void InspectorDebuggerAgent::stepOut(ErrorString* errorString, const String* cal
ScriptValue frame = resolveCallFrame(errorString, callFrameId); ScriptValue frame = resolveCallFrame(errorString, callFrameId);
if (!errorString->isEmpty()) if (!errorString->isEmpty())
return; return;
m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().stepOutOfFunction(frame); scriptDebugServer().stepOutOfFunction(frame);
} }
...@@ -1104,13 +1102,19 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String ...@@ -1104,13 +1102,19 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
{ {
ScriptDebugListener::SkipPauseRequest result = ScriptDebugListener::NoSkip; ScriptDebugListener::SkipPauseRequest result;
if (!exception.isEmpty()) if (m_javaScriptPauseScheduled)
result = shouldSkipExceptionPause(); result = ScriptDebugListener::NoSkip; // Don't skip explicit pause requests from front-end.
else if (m_skipAllPauses)
result = ScriptDebugListener::Continue;
else if (!hitBreakpoints.isEmpty()) else if (!hitBreakpoints.isEmpty())
result = shouldSkipBreakpointPause(); result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints even if set in frameworks.
else else if (!exception.isEmpty())
result = shouldSkipExceptionPause();
else if (m_debuggerStepScheduled)
result = shouldSkipStepPause(); result = shouldSkipStepPause();
else
result = ScriptDebugListener::NoSkip;
if (result != ScriptDebugListener::NoSkip) if (result != ScriptDebugListener::NoSkip)
return result; return result;
...@@ -1146,6 +1150,7 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptSta ...@@ -1146,6 +1150,7 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptSta
m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds, currentAsyncStackTrace()); m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds, currentAsyncStackTrace());
m_javaScriptPauseScheduled = false; m_javaScriptPauseScheduled = false;
m_debuggerStepScheduled = false;
if (!m_continueToLocationBreakpointId.isEmpty()) { if (!m_continueToLocationBreakpointId.isEmpty()) {
scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
...@@ -1175,6 +1180,7 @@ void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E ...@@ -1175,6 +1180,7 @@ void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E
return; return;
m_breakReason = breakReason; m_breakReason = breakReason;
m_breakAuxData = data; m_breakAuxData = data;
m_debuggerStepScheduled = false;
scriptDebugServer().breakProgram(); scriptDebugServer().breakProgram();
} }
...@@ -1188,6 +1194,7 @@ void InspectorDebuggerAgent::clear() ...@@ -1188,6 +1194,7 @@ void InspectorDebuggerAgent::clear()
m_continueToLocationBreakpointId = String(); m_continueToLocationBreakpointId = String();
clearBreakDetails(); clearBreakDetails();
m_javaScriptPauseScheduled = false; m_javaScriptPauseScheduled = false;
m_debuggerStepScheduled = false;
ErrorString error; ErrorString error;
setOverlayMessage(&error, 0); setOverlayMessage(&error, 0);
} }
......
...@@ -195,7 +195,6 @@ protected: ...@@ -195,7 +195,6 @@ protected:
private: private:
SkipPauseRequest shouldSkipExceptionPause(); SkipPauseRequest shouldSkipExceptionPause();
SkipPauseRequest shouldSkipBreakpointPause();
SkipPauseRequest shouldSkipStepPause(); SkipPauseRequest shouldSkipStepPause();
void cancelPauseOnNextStatement(); void cancelPauseOnNextStatement();
...@@ -236,6 +235,7 @@ private: ...@@ -236,6 +235,7 @@ private:
InspectorFrontend::Debugger::Reason::Enum m_breakReason; InspectorFrontend::Debugger::Reason::Enum m_breakReason;
RefPtr<JSONObject> m_breakAuxData; RefPtr<JSONObject> m_breakAuxData;
bool m_javaScriptPauseScheduled; bool m_javaScriptPauseScheduled;
bool m_debuggerStepScheduled;
Listener* m_listener; Listener* m_listener;
int m_skipStepInCount; int m_skipStepInCount;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment