v8/test/inspector/debugger/other-pause-reasons.js
Kim-Anh Tran 5145860836 [debugger] Fix step out when instrumentation breaks are turned on
When triggering a step out action, we check whether we already
are at a return or suspend location. If not, we first flood all
return positions with breakpoints, set the fast_forward_to_return_
flag and continue.

With the new way of reporting instrumentation breakpoints, we now
may get into the situation where we stopped on an instrumentation,
but may still need to continue until we reach the return point for
the step out. This CL fixes a bug in which we ran into a DCHECK
that expected us to stop on a return location (since
fast_forward_to_return_ is set to true), but we didn't.

Drive-by: adapt other stepping tests to properly wait for all pauses

Bug: chromium:1229541
Change-Id: Ie5fd358922f4cdaf1f8584bb0b35e87b0e221fb8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3480094
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Kim-Anh Tran <kimanh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79226}
2022-02-23 11:16:36 +00:00

160 lines
5.5 KiB
JavaScript

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { session, contextGroup, Protocol } = InspectorTest.start(
`Test that all 'other' reasons are explicitly encoded on a pause event if they overlap with another reason`);
function handlePause(
noInstrumentationStepAction, options,
{params: {reason, data, callFrames}}) {
const scriptId = callFrames[0].functionLocation.scriptId;
InspectorTest.log(`Paused with reason ${reason}, data ${
data ? JSON.stringify(data) : '{}'} and scriptId: ${scriptId}.`);
if (reason === 'instrumentation') {
Protocol.Debugger.resume();
} else {
Protocol.Debugger[noInstrumentationStepAction](options);
}
}
const resumeOnPause = handlePause.bind(null, 'resume', null);
async function setUpEnvironment() {
await Protocol.Debugger.enable();
await Protocol.Runtime.enable();
}
async function tearDownEnvironment() {
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
}
InspectorTest.runAsyncTestSuite([
async function testBreakpointPauseReason() {
await setUpEnvironment()
Protocol.Debugger.onPaused(resumeOnPause);
await Protocol.Debugger .setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
const {result: { scriptId }} = await Protocol.Runtime.compileScript({
expression: `console.log('foo');`, sourceURL: 'foo.js', persistScript: true });
await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 0,
columnNumber: 0,
url: 'foo.js',
});
await Protocol.Runtime.runScript({ scriptId });
tearDownEnvironment();
},
async function testTriggeredPausePauseReason() {
await setUpEnvironment();
Protocol.Debugger.onPaused(resumeOnPause);
await Protocol.Debugger.setInstrumentationBreakpoint({
instrumentation: 'beforeScriptExecution'
});
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({
expression: `console.log('foo');//# sourceURL=foo.js`});
tearDownEnvironment();
},
async function testSteppingPauseReason() {
await setUpEnvironment();
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'});
const {result: {scriptId}} = await Protocol.Runtime.compileScript({
expression: `setTimeout('console.log(3);//# sourceURL=bar.js', 0);`,
sourceURL: 'foo.js',
persistScript: true
});
await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 0,
url: 'foo.js',
});
const runPromise = Protocol.Runtime.runScript({scriptId});
// Pausing 5 times:
// 2x instrumentation breaks,
// 1x breakpoint,
// 2x step ins: end of setTimeout function, start of inner script.
for (var i = 0; i < 5; ++i) {
const msg = await Protocol.Debugger.oncePaused();
handlePause('stepInto', null, msg);
}
await runPromise;
await tearDownEnvironment();
},
async function testOnlyReportOtherWithEmptyDataOnce() {
await setUpEnvironment();
Protocol.Debugger.onPaused(resumeOnPause);
Protocol.Debugger.pause();
const {result: {scriptId}} = await Protocol.Runtime.compileScript({
expression: 'console.log(foo);',
sourceURL: 'foo.js',
persistScript: true
});
await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 0,
url: 'foo.js',
});
await Protocol.Runtime.runScript({scriptId});
await tearDownEnvironment();
},
async function testDebuggerStatementReason() {
await setUpEnvironment();
Protocol.Debugger.onPaused(resumeOnPause);
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'});
const {result: {scriptId}} = await Protocol.Runtime.compileScript(
{expression: 'debugger;', sourceURL: 'foo.js', persistScript: true});
await Protocol.Runtime.runScript({scriptId});
await tearDownEnvironment();
},
async function testAsyncSteppingPauseReason() {
await setUpEnvironment();
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'});
const expression =
`debugger; setTimeout('console.log(3);//# sourceURL=bar.js', 0);`;
const {result: {scriptId}} = await Protocol.Runtime.compileScript(
{expression, sourceURL: 'foo.js', persistScript: true});
const runPromise = Protocol.Runtime.runScript({scriptId});
// Pausing 6 times:
// 2x instrumentation breaks,
// 1x debugger statement,
// 3x steps in: start of setTimeout, start of inner script, end of inner script.
for (var i = 0; i < 6; ++i) {
const msg = await Protocol.Debugger.oncePaused();
handlePause('stepInto', {breakOnAsyncCall: true}, msg);
}
await runPromise;
await tearDownEnvironment();
},
async function testSteppingOutPauseReason() {
await setUpEnvironment();
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'});
const expression = `
function test() {
debugger;
eval('console.log(3);//# sourceURL=bar.js');
}
test();
`
const {result: {scriptId}} = await Protocol.Runtime.compileScript(
{expression, sourceURL: 'foo.js', persistScript: true});
const runPromise = Protocol.Runtime.runScript({scriptId});
const stepOutOnPause = handlePause.bind(this, 'stepOut', null);
Protocol.Debugger.onPaused(stepOutOnPause);
await runPromise;
await tearDownEnvironment();
},
]);