author | wartmanm <wartmanm@tutanota.com> |
Thu, 02 Jan 2020 18:42:46 +0000 | |
changeset 508629 | e954fcf487195136c45423a5a6a079d69a7db630 |
parent 508628 | 7d0cec2c6c40d070d643112bc348e632d19d4cc8 |
child 508630 | acc8cae5b23f98ed8189ac1688ccd4e04bb3c755 |
push id | 36974 |
push user | ncsoregi@mozilla.com |
push date | Fri, 03 Jan 2020 03:58:21 +0000 |
treeherder | mozilla-central@4d34e06619ed [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jlast |
bugs | 1575071 |
milestone | 73.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/devtools/server/actors/thread.js +++ b/devtools/server/actors/thread.js @@ -889,25 +889,21 @@ const ThreadActor = ActorClassWithSpec(t // onPop is called when we temporarily leave an async/generator if (completion.await || completion.yield) { thread.suspendedFrame = this; this.waitingOnStep = true; thread.dbg.onEnterFrame = undefined; return undefined; } - if (thread.sources.isFrameBlackBoxed(this)) { - return undefined; - } - // Note that we're popping this frame; we need to watch for // subsequent step events on its caller. this.reportedPop = true; - if (steppingType != "finish") { + if (steppingType != "finish" && !thread.sources.isFrameBlackBoxed(this)) { return pauseAndRespond(this, packet => thread.createCompletionGrip(packet, completion) ); } const parentFrame = thread._getNextStepFrame(this); if (parentFrame && parentFrame.script) { const { onStep, onPop } = thread._makeSteppingHooks({ @@ -988,17 +984,17 @@ const ThreadActor = ActorClassWithSpec(t }; }, _validFrameStepOffset: function(frame, startFrame, offset) { const meta = frame.script.getOffsetMetadata(offset); // Continue if: // 1. the location is not a valid breakpoint position - // 2. the source is not blackboxed + // 2. the source is blackboxed // 3. we have not moved since the last pause if ( !meta.isBreakpoint || this.sources.isFrameBlackBoxed(frame) || !this.hasMoved(frame) ) { return false; }
new file mode 100644 --- /dev/null +++ b/devtools/server/tests/unit/test_stepping-15.js @@ -0,0 +1,79 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Test stepping from inside a blackboxed function + * test-page: https://dbg-blackbox-stepping.glitch.me/ + */ + +async function invokeAndPause({ global, threadFront }, expression, url) { + return executeOnNextTickAndWaitForPause( + () => Cu.evalInSandbox(expression, global, "1.8", url, 1), + threadFront + ); +} +add_task( + threadFrontTest(async ({ threadFront, targetFront, debuggee }) => { + const consoleFront = await targetFront.getFront("console"); + const dbg = { global: debuggee, threadFront }; + + // Test stepping from a blackboxed location + async function testStepping(action, expectedLine) { + consoleFront.evaluateJSAsync(`outermost()`); + await waitForPause(threadFront); + await blackBox(blackboxedSourceFront); + const packet = await action(threadFront); + const { line, actor } = packet.frame.where; + equal(actor, unblackboxedActor, "paused in unblackboxed source"); + equal(line, expectedLine, "paused at correct line"); + await threadFront.resume(); + await unBlackBox(blackboxedSourceFront); + } + + invokeAndPause( + dbg, + `function outermost() { + const value = blackboxed1(); + return value + 1; + } + function innermost() { + return 1; + }`, + "http://example.com/unblackboxed.js" + ); + invokeAndPause( + dbg, + `function blackboxed1() { + return blackboxed2(); + } + function blackboxed2() { + return innermost(); + }`, + "http://example.com/blackboxed.js" + ); + + const { sources } = await getSources(threadFront); + const blackboxedSourceFront = threadFront.source( + sources.find(source => source.url == "http://example.com/blackboxed.js") + ); + const unblackboxedActor = sources.find( + source => source.url == "http://example.com/unblackboxed.js" + ).actor; + + await setBreakpoint(threadFront, { + sourceUrl: blackboxedSourceFront.url, + line: 5, + }); + + info("Step Out to outermost"); + await testStepping(stepOut, 3); + + info("Step Over to outermost"); + await testStepping(stepOver, 3); + + info("Step In to innermost"); + await testStepping(stepIn, 6); + }) +);
new file mode 100644 --- /dev/null +++ b/devtools/server/tests/unit/test_stepping-16.js @@ -0,0 +1,82 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Test stepping from inside a blackboxed function + * test-page: https://dbg-blackbox-stepping2.glitch.me/ + */ + +async function invokeAndPause({ global, threadFront }, expression, url) { + return executeOnNextTickAndWaitForPause( + () => Cu.evalInSandbox(expression, global, "1.8", url, 1), + threadFront + ); +} + +add_task( + threadFrontTest(async ({ threadFront, targetFront, debuggee }) => { + const consoleFront = await targetFront.getFront("console"); + const dbg = { global: debuggee, threadFront, consoleFront }; + invokeAndPause( + dbg, + `function outermost() { + blackboxed( + function inner1() { + return 1; + }, + function inner2() { + return 2; + } + ); + }`, + "http://example.com/unblackboxed.js" + ); + invokeAndPause( + dbg, + `function blackboxed(...args) { + for (const arg of args) { + arg(); + } + }`, + "http://example.com/blackboxed.js" + ); + + const { sources } = await getSources(threadFront); + const blackboxedSourceFront = threadFront.source( + sources.find(source => source.url == "http://example.com/blackboxed.js") + ); + const unblackboxedSource = sources.find( + source => source.url == "http://example.com/unblackboxed.js" + ); + const unblackboxedActor = unblackboxedSource.actor; + const unblackboxedSourceFront = threadFront.source(unblackboxedSource); + + await setBreakpoint(threadFront, { + sourceUrl: unblackboxedSourceFront.url, + line: 4, + }); + blackBox(blackboxedSourceFront); + + async function testStepping(action, expectedLine) { + consoleFront.evaluateJSAsync("outermost()"); + await waitForPause(threadFront); + await stepOver(threadFront); + const packet = await action(threadFront); + const { actor, line } = packet.frame.where; + equal(actor, unblackboxedActor, "Paused in unblackboxed source"); + equal(line, expectedLine, "Paused at correct line"); + await threadFront.resume(); + } + + info("Step Out to outermost"); + await testStepping(stepOut, 10); + + info("Step Over to outermost"); + await testStepping(stepOver, 10); + + info("Step In to inner2"); + await testStepping(stepIn, 7); + }) +);
--- a/devtools/server/tests/unit/xpcshell.ini +++ b/devtools/server/tests/unit/xpcshell.ini @@ -181,16 +181,18 @@ skip-if = true # breakpoint sliding is n [test_stepping-07.js] [test_stepping-08.js] [test_stepping-09.js] [test_stepping-10.js] [test_stepping-11.js] [test_stepping-12.js] [test_stepping-13.js] [test_stepping-14.js] +[test_stepping-15.js] +[test_stepping-16.js] [test_stepping-with-skip-breakpoints.js] [test_framebindings-01.js] [test_framebindings-02.js] [test_framebindings-03.js] [test_framebindings-04.js] [test_framebindings-05.js] [test_framebindings-06.js] [test_framebindings-07.js]