Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,172 @@
Tests breakable locations in array destructuring.
Running test: testBreakLocations
function testFunction() {
var [a, b, c = 4] = |C|generator1();
|_|[[a, b], c] = |C|generator2();
|_|[a, ...b] = |C|generator1();
|R|}
function generator1() {
|_|return {
[Symbol.iterator]() {
const it = |_|[1, 2].|C|values();
|_|return {next() { |_|return it.|C|next();|R| }};|R|
}
};|R|
}
function generator2() {
|_|return {
[Symbol.iterator]() {
const it = |_|[|C|generator1(), 3].|C|values();
|_|return {next() { |_|return it.|C|next();|R| }};|R|
}
};|R|
}
|R|
Running test: testStepping
Execution paused in testFunction:
function testFunction() {
var [a, b, c = 4] = #generator1();
[[a, b], c] = generator2();
Execution paused in generator1:
function generator1() {
#return {
[Symbol.iterator]() {
Called from testFunction:
function testFunction() {
var [a, b, c = 4] = #generator1();
[[a, b], c] = generator2();
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[1, 2].values();
return {next() { return it.next(); }};
Called from testFunction:
function testFunction() {
var [a, b, c = 4] = #generator1();
[[a, b], c] = generator2();
Execution paused in next:
const it = [1, 2].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
function testFunction() {
var [#a, b, c = 4] = generator1();
[[a, b], c] = generator2();
Execution paused in testFunction:
var [a, b, c = 4] = generator1();
#[[a, b], c] = generator2();
[a, ...b] = generator1();
Execution paused in generator2:
function generator2() {
#return {
[Symbol.iterator]() {
Called from testFunction:
var [a, b, c = 4] = generator1();
[[a, b], c] = #generator2();
[a, ...b] = generator1();
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[generator1(), 3].values();
return {next() { return it.next(); }};
Called from testFunction:
var [a, b, c = 4] = generator1();
[[a, b], c] #= generator2();
[a, ...b] = generator1();
Execution paused in next:
const it = [generator1(), 3].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
var [a, b, c = 4] = generator1();
[#[a, b], c] = generator2();
[a, ...b] = generator1();
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[1, 2].values();
return {next() { return it.next(); }};
Called from testFunction:
var [a, b, c = 4] = generator1();
[#[a, b], c] = generator2();
[a, ...b] = generator1();
Execution paused in next:
const it = [1, 2].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
var [a, b, c = 4] = generator1();
[[#a, b], c] = generator2();
[a, ...b] = generator1();
Execution paused in next:
const it = [generator1(), 3].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
var [a, b, c = 4] = generator1();
[[a, b], #c] = generator2();
[a, ...b] = generator1();
Execution paused in testFunction:
[[a, b], c] = generator2();
#[a, ...b] = generator1();
}
Execution paused in generator1:
function generator1() {
#return {
[Symbol.iterator]() {
Called from testFunction:
[[a, b], c] = generator2();
[a, ...b] = #generator1();
}
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[1, 2].values();
return {next() { return it.next(); }};
Called from testFunction:
[[a, b], c] = generator2();
[a, ...b] #= generator1();
}
Execution paused in next:
const it = [1, 2].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
[[a, b], c] = generator2();
[#a, ...b] = generator1();
}
Execution paused in testFunction:
[a, ...b] = generator1();
#}
Resuming and finishing...

View File

@ -0,0 +1,102 @@
// Copyright 2022 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests breakable locations in array destructuring.');
const source = `
function testFunction() {
var [a, b, c = 4] = generator1();
[[a, b], c] = generator2();
[a, ...b] = generator1();
}
function generator1() {
return {
[Symbol.iterator]() {
const it = [1, 2].values();
return {next() { return it.next(); }};
}
};
}
function generator2() {
return {
[Symbol.iterator]() {
const it = [generator1(), 3].values();
return {next() { return it.next(); }};
}
};
}
`;
const url = 'test.js';
contextGroup.addScript(source, 0, 0, url);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testBreakLocations() {
let [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
let {result: {locations}} = await Protocol.Debugger.getPossibleBreakpoints(
{start: {lineNumber: 0, columnNumber: 0, scriptId}});
await session.logBreakLocations(locations);
await Promise.all([
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepping() {
let [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
const {breakpointId} = await Protocol.Debugger.setBreakpoint({
location: {
scriptId,
lineNumber: 2,
}
});
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
for (;;) {
const {method, params} = await Promise.race([
evalPromise,
Protocol.Debugger.oncePaused(),
]);
if (method !== 'Debugger.paused') {
break;
}
const callFrames = params.callFrames.filter(
callFrame => callFrame.location.scriptId === scriptId);
if (callFrames.length === 0) {
InspectorTest.log('Resuming and finishing...');
await Protocol.Debugger.resume();
} else {
const [{functionName, location}, ...callerFrames] = callFrames;
InspectorTest.log(`Execution paused in ${functionName}:`);
await session.logSourceLocation(location);
for (const {location, functionName} of callerFrames) {
InspectorTest.log(`Called from ${functionName}:`);
await session.logSourceLocation(location);
}
if (functionName === 'testFunction') {
await Protocol.Debugger.stepInto();
} else {
await Protocol.Debugger.stepOut();
}
}
}
await Promise.all([
Protocol.Debugger.removeBreakpoint({breakpointId}),
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
}
]);

View File

@ -0,0 +1,75 @@
Tests breakable locations in array spread.
Running test: testBreakLocations
function testFunction() {
var a = |_|[...iterable];
var b = [...|_|a, ...iterable, ...a];
|R|}
const iterable = |_|{
[Symbol.iterator]() {
const it = |_|[1, 2].|C|values();
|_|return {next() { |_|return it.|C|next();|R| }};|R|
}
};
|R|
Running test: testStepping
Execution paused in testFunction:
function testFunction() {
var a = #[...iterable];
var b = [...a, ...iterable, ...a];
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[1, 2].values();
return {next() { return it.next(); }};
Called from testFunction:
function testFunction() {
var a = [...#iterable];
var b = [...a, ...iterable, ...a];
Execution paused in next:
const it = [1, 2].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
function testFunction() {
var a = [...#iterable];
var b = [...a, ...iterable, ...a];
Execution paused in testFunction:
var a = [...iterable];
var b = [...#a, ...iterable, ...a];
}
Execution paused in [Symbol.iterator]:
[Symbol.iterator]() {
const it = #[1, 2].values();
return {next() { return it.next(); }};
Called from testFunction:
var a = [...iterable];
var b = [...a, ...#iterable, ...a];
}
Execution paused in next:
const it = [1, 2].values();
return {next() { #return it.next(); }};
}
Called from testFunction:
var a = [...iterable];
var b = [...a, ...#iterable, ...a];
}
Execution paused in testFunction:
var b = [...a, ...iterable, ...a];
#}
Resuming and finishing...

View File

@ -0,0 +1,90 @@
// Copyright 2022 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests breakable locations in array spread.');
const source = `
function testFunction() {
var a = [...iterable];
var b = [...a, ...iterable, ...a];
}
const iterable = {
[Symbol.iterator]() {
const it = [1, 2].values();
return {next() { return it.next(); }};
}
};
`;
const url = 'test.js';
contextGroup.addScript(source, 0, 0, url);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testBreakLocations() {
let [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
let {result: {locations}} = await Protocol.Debugger.getPossibleBreakpoints(
{start: {lineNumber: 0, columnNumber: 0, scriptId}});
await session.logBreakLocations(locations);
await Promise.all([
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepping() {
let [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
const {breakpointId} = await Protocol.Debugger.setBreakpoint({
location: {
scriptId,
lineNumber: 2,
}
});
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
for (;;) {
const {method, params} = await Promise.race([
evalPromise,
Protocol.Debugger.oncePaused(),
]);
if (method !== 'Debugger.paused') {
break;
}
const callFrames = params.callFrames.filter(
callFrame => callFrame.location.scriptId === scriptId);
if (callFrames.length === 0) {
InspectorTest.log('Resuming and finishing...');
await Protocol.Debugger.resume();
} else {
const [{functionName, location}, ...callerFrames] = callFrames;
InspectorTest.log(`Execution paused in ${functionName}:`);
await session.logSourceLocation(location);
for (const {location, functionName} of callerFrames) {
InspectorTest.log(`Called from ${functionName}:`);
await session.logSourceLocation(location);
}
if (functionName === 'testFunction') {
await Protocol.Debugger.stepInto();
} else {
await Protocol.Debugger.stepOut();
}
}
}
await Promise.all([
Protocol.Debugger.removeBreakpoint({breakpointId}),
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
}
]);

View File

@ -0,0 +1,64 @@
This test runs asm.js which calls back to JS. Before executing (after the script is parsed) we set breakpoints in the asm.js code.
Running test: enableDebugger
Running test: addScript
Script nr 1 parsed!
First script; assuming testFunction.
Flooding script with breakpoints for the lines 3 to 19...
Setting breakpoint on line 3
error: undefined
Setting breakpoint on line 4
error: undefined
Setting breakpoint on line 5
error: undefined
Setting breakpoint on line 6
error: undefined
Setting breakpoint on line 7
error: undefined
Setting breakpoint on line 8
error: undefined
Setting breakpoint on line 9
error: undefined
Setting breakpoint on line 10
error: undefined
Setting breakpoint on line 11
error: undefined
Setting breakpoint on line 12
error: undefined
Setting breakpoint on line 13
error: undefined
Setting breakpoint on line 14
error: undefined
Setting breakpoint on line 15
error: undefined
Setting breakpoint on line 16
error: undefined
Setting breakpoint on line 17
error: undefined
Setting breakpoint on line 18
error: undefined
Running test: runTestFunction
Script nr 2 parsed!
Paused #1
- [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":17,"columnNumber":12}
- [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Paused #2
- [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Paused #3
- [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
- [1] {"functionName":"callDebugger","function_lineNumber":0,"function_columnNumber":105,"lineNumber":5,"columnNumber":6}
- [2] {"functionName":"redirectFun","function_lineNumber":0,"function_columnNumber":110,"lineNumber":8,"columnNumber":6}
- [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Paused #4
- [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":15,"columnNumber":2}
- [1] {"functionName":"callDebugger","function_lineNumber":0,"function_columnNumber":105,"lineNumber":5,"columnNumber":6}
- [2] {"functionName":"redirectFun","function_lineNumber":0,"function_columnNumber":110,"lineNumber":8,"columnNumber":6}
- [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Running test: finished
Finished TestSuite.

View File

@ -0,0 +1,134 @@
// Copyright 2016 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.
// Flags: --validate-asm --allow-natives-syntax
let {session, contextGroup, Protocol} = InspectorTest.start(
'This test runs asm.js which calls back to JS. Before executing (after ' +
'the script is parsed) we set breakpoints in the asm.js code.');
function testFunction() {
function generateAsmJs(stdlib, foreign, heap) {
'use asm';
var debugger_fun = foreign.call_debugger;
function callDebugger() {
debugger_fun();
}
function redirectFun() {
callDebugger();
}
return redirectFun;
}
function call_debugger() {
debugger;
}
var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
fun();
}
Protocol.Debugger.onPaused(handleDebuggerPaused);
Protocol.Debugger.onScriptParsed(handleScriptParsed);
function printResultAndContinue(next, message) {
if (message.result && message.result.exceptionDetails)
InspectorTest.logMessage(message.result.exceptionDetails);
else if (message.error)
InspectorTest.logMessage(message.error);
else if (message.result && message.result.type !== undefined)
InspectorTest.logMessage(message.result);
next();
}
InspectorTest.runTestSuite([
function enableDebugger(next) {
Protocol.Debugger.enable().then(next);
},
function addScript(next) {
afterScriptParsedCallback = next;
contextGroup.addScript(testFunction.toString());
},
function runTestFunction(next) {
Protocol.Runtime.evaluate({'expression': 'testFunction()'})
.then(printResultAndContinue.bind(null, next));
},
function finished(next) {
InspectorTest.log('Finished TestSuite.');
next();
},
]);
function locationToString(callFrame) {
var res = {functionName: callFrame.functionName};
for (var attr in callFrame.functionLocation) {
if (attr == 'scriptId') continue;
res['function_' + attr] = callFrame.functionLocation[attr];
}
for (var attr in callFrame.location) {
if (attr == 'scriptId') continue;
res[attr] = callFrame.location[attr];
}
return JSON.stringify(res);
}
function logStackTrace(messageObject) {
var frames = messageObject.params.callFrames;
for (var i = 0; i < frames.length; ++i) {
InspectorTest.log(' - [' + i + '] ' + locationToString(frames[i]));
}
}
var numPaused = 0;
function handleDebuggerPaused(messageObject)
{
++numPaused;
InspectorTest.log('Paused #' + numPaused);
logStackTrace(messageObject);
Protocol.Debugger.resume();
}
var numScripts = 0;
function handleScriptParsed(messageObject)
{
var scriptId = messageObject.params.scriptId;
++numScripts;
InspectorTest.log('Script nr ' + numScripts + ' parsed!');
if (numScripts > 1) return;
var startLine = messageObject.params.startLine + 3;
var endLine = messageObject.params.endLine;
if (startLine > endLine) {
InspectorTest.log(
`Terminating early: start line ${startLine} is after end line ${endLine}.`
);
return;
}
InspectorTest.log('First script; assuming testFunction.');
InspectorTest.log(
'Flooding script with breakpoints for the lines ' + startLine + ' to ' +
endLine + '...');
var currentLine = startLine;
function setNextBreakpoint(message) {
if (message) InspectorTest.logMessage('error: ' + message.error);
if (currentLine == endLine) {
afterScriptParsedCallback();
return;
}
var thisLine = currentLine;
currentLine += 1;
InspectorTest.log('Setting breakpoint on line ' + thisLine);
Protocol.Debugger
.setBreakpoint(
{'location': {'scriptId': scriptId, 'lineNumber': thisLine}})
.then(setNextBreakpoint);
}
setNextBreakpoint();
}

View File

@ -0,0 +1,84 @@
This test runs asm.js which calls back to JS. JS triggers a break, on pause we set breakpoints in the asm.js code.
Running test: enableDebugger
Running test: addScript
Script nr 1 parsed!
Running test: runTestFunction
Script nr 2 parsed!
Paused #1
- [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
- [1] {"functionName":"callDebugger","function_lineNumber":0,"function_columnNumber":105,"lineNumber":5,"columnNumber":6}
- [2] {"functionName":"redirectFun","function_lineNumber":0,"function_columnNumber":110,"lineNumber":8,"columnNumber":6}
- [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
First time paused, setting breakpoints!
Flooding script with breakpoints for all lines (0 - 22)...
Setting breakpoint on line 0
error: undefined
Setting breakpoint on line 1
error: undefined
Setting breakpoint on line 2
error: undefined
Setting breakpoint on line 3
error: undefined
Setting breakpoint on line 4
error: undefined
Setting breakpoint on line 5
error: undefined
Setting breakpoint on line 6
error: undefined
Setting breakpoint on line 7
error: undefined
Setting breakpoint on line 8
error: undefined
Setting breakpoint on line 9
error: undefined
Setting breakpoint on line 10
error: undefined
Setting breakpoint on line 11
error: undefined
Setting breakpoint on line 12
error: undefined
Setting breakpoint on line 13
error: undefined
Setting breakpoint on line 14
error: undefined
Setting breakpoint on line 15
error: undefined
Setting breakpoint on line 16
error: undefined
Setting breakpoint on line 17
error: undefined
Setting breakpoint on line 18
error: undefined
Setting breakpoint on line 19
error: undefined
Setting breakpoint on line 20
error: undefined
Setting breakpoint on line 21
error: undefined
Script nr 3 parsed!
Resuming...
Paused #2
- [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":15,"columnNumber":2}
- [1] {"functionName":"callDebugger","function_lineNumber":0,"function_columnNumber":105,"lineNumber":5,"columnNumber":6}
- [2] {"functionName":"redirectFun","function_lineNumber":0,"function_columnNumber":110,"lineNumber":8,"columnNumber":6}
- [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Script nr 4 parsed!
Resuming...
Paused #3
- [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":20,"columnNumber":17}
- [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Script nr 5 parsed!
Resuming...
Paused #4
- [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":21,"columnNumber":2}
- [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Script nr 6 parsed!
Resuming...
Running test: finished
Finished TestSuite.

View File

@ -0,0 +1,164 @@
// Copyright 2016 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.
// Flags: --validate-asm --allow-natives-syntax
let {session, contextGroup, Protocol} = InspectorTest.start(
'This test runs asm.js which calls back to JS. JS triggers a break, on ' +
'pause we set breakpoints in the asm.js code.');
function testFunction() {
function generateAsmJs(stdlib, foreign, heap) {
'use asm';
var debugger_fun = foreign.call_debugger;
function callDebugger() {
debugger_fun();
}
function redirectFun() {
callDebugger();
}
return redirectFun;
}
function call_debugger() {
debugger;
}
var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
fun();
var finished = 'finished';
debugger;
}
Protocol.Debugger.onPaused(handleDebuggerPaused);
Protocol.Debugger.onScriptParsed(handleScriptParsed);
function printResultAndContinue(next, message) {
if (message.result && message.result.exceptionDetails)
InspectorTest.logMessage(message.result.exceptionDetails);
else if (message.error)
InspectorTest.logMessage(message.error);
else if (message.result && message.result.type !== undefined)
InspectorTest.logMessage(message.result);
if (next) next();
}
InspectorTest.runTestSuite([
function enableDebugger(next) {
Protocol.Debugger.enable().then(next);
},
function addScript(next) {
afterScriptParsedCallback = next;
contextGroup.addScript(testFunction.toString());
},
function runTestFunction(next) {
afterFinishedTestFunctionCallback = next;
Protocol.Runtime.evaluate({'expression': 'testFunction()'})
.then(printResultAndContinue.bind(null, null));
},
function finished(next) {
InspectorTest.log('Finished TestSuite.');
next();
},
]);
function locationToString(callFrame) {
var res = {functionName: callFrame.functionName};
for (var attr in callFrame.functionLocation) {
if (attr == 'scriptId') continue;
res['function_' + attr] = callFrame.functionLocation[attr];
}
for (var attr in callFrame.location) {
if (attr == 'scriptId') continue;
res[attr] = callFrame.location[attr];
}
return JSON.stringify(res);
}
function logStackTrace(messageObject) {
var frames = messageObject.params.callFrames;
for (var i = 0; i < frames.length; ++i) {
InspectorTest.log(' - [' + i + '] ' + locationToString(frames[i]));
}
}
var numPaused = 0;
var parsedScriptParams;
function handleDebuggerPaused(messageObject)
{
++numPaused;
InspectorTest.log('Paused #' + numPaused);
logStackTrace(messageObject);
function cont() {
var topFrameId = messageObject.params.callFrames[0].callFrameId;
Protocol.Debugger
.evaluateOnCallFrame({
callFrameId: topFrameId,
expression: 'typeof finished'
})
.then(callbackEvaluate);
function callbackEvaluate(message) {
var finished = message.result && message.result.result &&
message.result.result.value === 'string';
InspectorTest.log('Resuming...');
Protocol.Debugger.resume();
if (finished)
afterFinishedTestFunctionCallback();
}
}
if (numPaused > 1) {
cont();
return;
}
InspectorTest.log('First time paused, setting breakpoints!');
var startLine = parsedScriptParams.startLine;
var endLine = parsedScriptParams.endLine;
InspectorTest.log(
'Flooding script with breakpoints for all lines (' + startLine + ' - ' +
endLine + ')...');
var currentLine = startLine;
function setNextBreakpoint(message) {
if (message) InspectorTest.logMessage('error: ' + message.error);
if (currentLine == endLine) {
cont();
return;
}
var thisLine = currentLine;
currentLine += 1;
InspectorTest.log('Setting breakpoint on line ' + thisLine);
Protocol.Debugger
.setBreakpoint({
'location': {
'scriptId': parsedScriptParams.scriptId,
'lineNumber': thisLine
}
})
.then(setNextBreakpoint);
}
setNextBreakpoint();
}
var numScripts = 0;
function handleScriptParsed(messageObject)
{
var scriptId = messageObject.params.scriptId;
++numScripts;
InspectorTest.log('Script nr ' + numScripts + ' parsed!');
if (numScripts == 1) {
parsedScriptParams = JSON.parse(JSON.stringify(messageObject.params));
afterScriptParsedCallback();
}
}

View File

@ -0,0 +1,18 @@
Tests that asm-js scripts produce correct stack
Paused on 'debugger;'
Number of frames: 5
- [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
- [1] {"functionName":"callDebugger","function_lineNumber":0,"function_columnNumber":105,"lineNumber":5,"columnNumber":6}
- [2] {"functionName":"redirectFun","function_lineNumber":0,"function_columnNumber":110,"lineNumber":8,"columnNumber":6}
- [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
- [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
Getting v8-generated stack trace...
Result of evaluate (string):
Error: getting stack trace
-- skipped --
at call_debugger (<anonymous>:15:5)
at callDebugger (<anonymous>:6:7)
at redirectFun (<anonymous>:9:7)
at testFunction (<anonymous>:19:3)
at <anonymous>:1:1
Finished!

View File

@ -0,0 +1,81 @@
// Copyright 2016 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.
// Flags: --validate-asm
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that asm-js scripts produce correct stack');
function testFunction() {
function generateAsmJs(stdlib, foreign, heap) {
'use asm';
var debugger_fun = foreign.call_debugger;
function callDebugger() {
debugger_fun();
}
function redirectFun() {
callDebugger();
}
return redirectFun;
}
function call_debugger() {
debugger;
}
var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
fun();
}
contextGroup.addScript(testFunction.toString());
Protocol.Debugger.enable();
Protocol.Debugger.oncePaused().then(handleDebuggerPaused);
Protocol.Runtime.evaluate({'expression': 'testFunction()'});
function locationToString(callFrame) {
var res = {functionName: callFrame.functionName};
for (var attr in callFrame.functionLocation) {
if (attr == 'scriptId') continue;
res['function_'+attr] = callFrame.functionLocation[attr];
}
for (var attr in callFrame.location) {
if (attr == 'scriptId') continue;
res[attr] = callFrame.location[attr];
}
return JSON.stringify(res);
}
function logStackTrace(messageObject) {
var frames = messageObject.params.callFrames;
InspectorTest.log('Number of frames: ' + frames.length);
for (var i = 0; i < frames.length; ++i) {
InspectorTest.log(' - [' + i + '] ' + locationToString(frames[i]));
}
}
function handleDebuggerPaused(messageObject)
{
InspectorTest.log('Paused on \'debugger;\'');
logStackTrace(messageObject);
InspectorTest.log('Getting v8-generated stack trace...');
var topFrameId = messageObject.params.callFrames[0].callFrameId;
Protocol.Debugger
.evaluateOnCallFrame({
callFrameId: topFrameId,
expression: '(new Error("getting stack trace")).stack'
})
.then(callbackEvaluate);
}
function callbackEvaluate(response)
{
InspectorTest.log(
'Result of evaluate (' + response.result.result.type + '):');
var result_lines = response.result.result.value.split("\n");
// Skip the second line, containing the 'evaluate' position.
result_lines[1] = " -- skipped --";
InspectorTest.log(result_lines.join('\n'));
InspectorTest.log('Finished!');
InspectorTest.completeTest();
}

View File

@ -0,0 +1,134 @@
Tests different combinations of async stacks in chains.
Regular
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
runWithNone (utils.js:27:2)
(anonymous) (test.js:3:10)
Regular - Regular
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
-- outer async --
runWithRegular (utils.js:2:12)
(anonymous) (test.js:3:10)
Regular - EmptyName
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
-- <empty> --
runWithEmptyName (utils.js:6:12)
(anonymous) (test.js:3:10)
Regular - EmptyStack
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
Regular - EmptyNameEmptyStack
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
Regular - External
userFunction (test.js:1:36)
-- inner async --
runWithRegular (utils.js:2:12)
inner (test.js:2:28)
(anonymous) (utils.js:21:4)
<external stack>
EmptyName
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
runWithNone (utils.js:27:2)
(anonymous) (test.js:3:10)
EmptyName - Regular
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
-- outer async --
runWithRegular (utils.js:2:12)
(anonymous) (test.js:3:10)
EmptyName - EmptyName
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
-- <empty> --
runWithEmptyName (utils.js:6:12)
(anonymous) (test.js:3:10)
EmptyName - EmptyStack
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
EmptyName - EmptyNameEmptyStack
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
EmptyName - External
userFunction (test.js:1:36)
-- <empty> --
runWithEmptyName (utils.js:6:12)
inner (test.js:2:28)
(anonymous) (utils.js:21:4)
<external stack>
EmptyStack
userFunction (test.js:1:36)
EmptyStack - Regular
userFunction (test.js:1:36)
EmptyStack - EmptyName
userFunction (test.js:1:36)
EmptyStack - EmptyStack
userFunction (test.js:1:36)
EmptyStack - EmptyNameEmptyStack
userFunction (test.js:1:36)
EmptyStack - External
userFunction (test.js:1:36)
EmptyNameEmptyStack
userFunction (test.js:1:36)
EmptyNameEmptyStack - Regular
userFunction (test.js:1:36)
EmptyNameEmptyStack - EmptyName
userFunction (test.js:1:36)
EmptyNameEmptyStack - EmptyStack
userFunction (test.js:1:36)
EmptyNameEmptyStack - EmptyNameEmptyStack
userFunction (test.js:1:36)
EmptyNameEmptyStack - External
userFunction (test.js:1:36)
External
userFunction (test.js:1:36)
(anonymous) (utils.js:21:4)
<external stack>

View File

@ -0,0 +1,77 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Tests different combinations of async stacks in chains.');
contextGroup.addScript(`
function runWithRegular(f, name) {
inspector.scheduleWithAsyncStack(f, name, false);
}
function runWithEmptyName(f) {
inspector.scheduleWithAsyncStack(f, '', false);
}
function runWithEmptyStack(f, name) {
inspector.scheduleWithAsyncStack(f, name, true);
}
function runWithEmptyNameEmptyStack(f) {
inspector.scheduleWithAsyncStack(f, '', true);
}
function runWithExternal(f) {
const id = inspector.storeCurrentStackTrace('external');
runWithRegular(() => {
inspector.externalAsyncTaskStarted(id);
f();
inspector.externalAsyncTaskFinished(id);
}, 'not-used-async');
}
function runWithNone(f) {
f();
}
//# sourceURL=utils.js`);
session.setupScriptMap();
(async function test() {
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
const first = ['Regular', 'EmptyName', 'EmptyStack', 'EmptyNameEmptyStack', 'External']
const second = ['None', 'Regular', 'EmptyName', 'EmptyStack', 'EmptyNameEmptyStack', 'External']
for (const stack1 of first) {
for (const stack2 of second) {
if (stack1 === 'External' && stack2 !== 'None') continue;
InspectorTest.log(stack2 === 'None' ? stack1 : `${stack1} - ${stack2}`);
Protocol.Runtime.evaluate({
expression: `
var userFunction = () => {debugger};
var inner = () => runWith${stack1}(userFunction, 'inner async');
runWith${stack2}(inner, 'outer async');
//# sourceURL=test.js`
});
await pauseAndDumpStack();
}
}
await Protocol.Debugger.disable();
InspectorTest.completeTest();
})();
async function pauseAndDumpStack() {
const {params:{callFrames, asyncStackTrace, asyncStackTraceId}}
= await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
if (asyncStackTrace)
session.logAsyncStackTrace(asyncStackTrace);
if (asyncStackTraceId)
InspectorTest.log(' <external stack>');
InspectorTest.log('');
return Protocol.Debugger.resume();
}

View File

@ -0,0 +1 @@
setTimeout(console.count, 0) doesn't crash with enabled async stacks.

View File

@ -0,0 +1,10 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start("setTimeout(console.count, 0) doesn't crash with enabled async stacks.")
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 1 });
Protocol.Runtime.evaluate({ expression: "setTimeout(console.count, 0)" });
InspectorTest.waitForPendingTasks().then(InspectorTest.completeTest);

View File

@ -0,0 +1,54 @@
Checks that async chains for for-await-of are correct.
Running test: testBasic
Debugger (test.js:10:2)
Basic (test.js:48:4)
-- await --
(anonymous) (testBasic.js:0:0)
Running test: testUncaughtReject
Debugger (test.js:10:2)
-- Promise.catch --
UncaughtReject (test.js:58:21)
(anonymous) (testUncaughtReject.js:0:0)
Running test: testUncaughtThrow
Debugger (test.js:10:2)
-- Promise.catch --
UncaughtThrow (test.js:67:21)
(anonymous) (testUncaughtThrow.js:0:0)
Running test: testCaughtReject
Debugger (test.js:10:2)
CaughtReject (test.js:76:4)
-- await --
(anonymous) (testCaughtReject.js:0:0)
Running test: testCaughtThrow
Debugger (test.js:10:2)
CaughtThrow (test.js:86:4)
-- await --
(anonymous) (testCaughtThrow.js:0:0)
Running test: testUncaughtRejectOnBreak
Running test: testUncaughtThrowOnBreak
Debugger (test.js:10:2)
-- Promise.catch --
UncaughtThrowOnBreak (test.js:105:21)
(anonymous) (testUncaughtThrowOnBreak.js:0:0)
Running test: testCaughtRejectOnBreak
Running test: testCaughtThrowOnBreak
Debugger (test.js:10:2)
CaughtThrowOnBreak (test.js:124:4)
-- await --
(anonymous) (testCaughtThrowOnBreak.js:0:0)

View File

@ -0,0 +1,161 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async chains for for-await-of are correct.');
contextGroup.addInlineScript(`
function Debugger(value) {
debugger;
}
function Reject(reason) {
var reject;
var promise = new Promise(function(resolvefn, rejectfn) {
reject = rejectfn;
});
setTimeout(reject.bind(undefined, reason), 0);
return promise;
}
function Throw(reason) {
return {
get then() { throw reason; }
};
}
function ThrowOnReturn(items) {
var it = items[Symbol.iterator]();
return {
[Symbol.iterator]() { return this; },
next(v) { return it.next(v); },
return(v) { throw new Error("boop"); }
};
}
function RejectOnReturn(items) {
var it = items[Symbol.iterator]();
return {
[Symbol.iterator]() { return this; },
next(v) { return it.next(v); },
return(v) { return Reject(new Error("boop")); }
};
}
async function Basic() {
for await (let x of ["a"]) {
Debugger();
}
}
async function UncaughtReject() {
async function loop() {
for await (let x of [Reject(new Error("boop"))]) {
Debugger();
}
}
return loop().catch(Debugger);
}
async function UncaughtThrow() {
async function loop() {
for await (let x of [Throw(new Error("boop"))]) {
Debugger();
}
}
return loop().catch(Debugger);
}
async function CaughtReject() {
try {
for await (let x of [Reject(new Error("boop"))]) {
Debugger(x);
}
} catch (e) {
Debugger(e);
}
}
async function CaughtThrow() {
try {
for await (let x of [Throw(new Error("boop"))]) {
Debugger(x);
}
} catch (e) {
Debugger(e);
}
}
async function UncaughtRejectOnBreak() {
async function loop() {
for await (let x of RejectOnReturn(["0", "1"])) {
break;
}
}
return loop().catch(Debugger);
}
async function UncaughtThrowOnBreak() {
async function loop() {
for await (let x of ThrowOnReturn(["0", "1"])) {
break;
}
}
return loop().catch(Debugger);
}
async function CaughtRejectOnBreak() {
try {
for await (let x of RejectOnReturn(["0", "1"])) {
break;
}
} catch (e) {
Debugger(e);
}
}
async function CaughtThrowOnBreak() {
try {
for await (let x of ThrowOnReturn(["0", "1"])) {
break;
}
} catch (e) {
Debugger(e);
}
}`, 'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
var testList = [
'Basic',
'UncaughtReject',
'UncaughtThrow',
'CaughtReject',
'CaughtThrow',
'UncaughtRejectOnBreak',
'UncaughtThrowOnBreak',
'CaughtRejectOnBreak',
'CaughtThrowOnBreak',
]
InspectorTest.runTestSuite(testList.map(name => {
return eval(`
(function test${capitalize(name)}(next) {
Protocol.Runtime.evaluate({ expression: \`${name}()
//# sourceURL=test${capitalize(name)}.js\`, awaitPromise: true})
.then(next);
})
`);
}));
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

View File

@ -0,0 +1,178 @@
stepOut async function
Running test: testTrivial
Check that we have proper async stack at return
bar (testTrivial.js:28:8)
-- await --
foo (testTrivial.js:23:14)
-- await --
test (testTrivial.js:18:14)
-- await --
(anonymous) (:0:0)
foo (testTrivial.js:24:6)
-- await --
test (testTrivial.js:18:14)
-- await --
(anonymous) (:0:0)
test (testTrivial.js:19:6)
-- await --
(anonymous) (:0:0)
Running test: testStepOutPrecision
Check that stepOut go to resumed outer generator
bar (testStepOutPrecision.js:61:8)
-- await --
foo (testStepOutPrecision.js:55:14)
-- await --
test (testStepOutPrecision.js:48:14)
-- await --
(anonymous) (:0:0)
foo (testStepOutPrecision.js:56:8)
-- await --
test (testStepOutPrecision.js:48:14)
-- await --
(anonymous) (:0:0)
test (testStepOutPrecision.js:49:8)
-- await --
(anonymous) (:0:0)
floodWithTimeouts (testStepOutPrecision.js:40:15)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
test (testStepOutPrecision.js:46:8)
(anonymous) (:0:0)
test (testStepOutPrecision.js:50:8)
-- await --
(anonymous) (:0:0)
floodWithTimeouts (testStepOutPrecision.js:40:15)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
-- setTimeout --
floodWithTimeouts (testStepOutPrecision.js:41:10)
test (testStepOutPrecision.js:46:8)
(anonymous) (:0:0)
Running test: testStepIntoAtReturn
Check that stepInto at return go to resumed outer generator
bar (testStepIntoAtReturn.js:93:8)
-- await --
foo (testStepIntoAtReturn.js:88:14)
-- await --
test (testStepIntoAtReturn.js:82:14)
-- await --
(anonymous) (:0:0)
bar (testStepIntoAtReturn.js:94:6)
-- await --
foo (testStepIntoAtReturn.js:88:14)
-- await --
test (testStepIntoAtReturn.js:82:14)
-- await --
(anonymous) (:0:0)
foo (testStepIntoAtReturn.js:89:6)
-- await --
test (testStepIntoAtReturn.js:82:14)
-- await --
(anonymous) (:0:0)
test (testStepIntoAtReturn.js:83:8)
-- await --
(anonymous) (:0:0)
test (testStepIntoAtReturn.js:84:6)
-- await --
(anonymous) (:0:0)
floodWithTimeouts (testStepIntoAtReturn.js:74:15)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:75:10)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:75:10)
test (testStepIntoAtReturn.js:80:8)
(anonymous) (:0:0)
Running test: testStepOverAtReturn
Check that stepOver at return go to resumed outer generator
bar (testStepIntoAtReturn.js:124:8)
-- await --
foo (testStepIntoAtReturn.js:119:14)
-- await --
test (testStepIntoAtReturn.js:113:14)
-- await --
(anonymous) (:0:0)
bar (testStepIntoAtReturn.js:125:6)
-- await --
foo (testStepIntoAtReturn.js:119:14)
-- await --
test (testStepIntoAtReturn.js:113:14)
-- await --
(anonymous) (:0:0)
foo (testStepIntoAtReturn.js:120:6)
-- await --
test (testStepIntoAtReturn.js:113:14)
-- await --
(anonymous) (:0:0)
test (testStepIntoAtReturn.js:114:8)
-- await --
(anonymous) (:0:0)
test (testStepIntoAtReturn.js:115:6)
-- await --
(anonymous) (:0:0)
floodWithTimeouts (testStepIntoAtReturn.js:105:15)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:106:10)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:106:10)
test (testStepIntoAtReturn.js:111:8)
(anonymous) (:0:0)
Running test: testStepOutFromNotAwaitedCall
Checks stepOut from not awaited call
bar (testStepIntoAtReturn.js:158:8)
-- await --
foo (testStepIntoAtReturn.js:152:8)
-- await --
test (testStepIntoAtReturn.js:144:14)
-- await --
(anonymous) (:0:0)
test (testStepIntoAtReturn.js:145:8)
-- await --
(anonymous) (:0:0)
floodWithTimeouts (testStepIntoAtReturn.js:136:15)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:137:10)
-- setTimeout --
floodWithTimeouts (testStepIntoAtReturn.js:137:10)
test (testStepIntoAtReturn.js:142:8)
(anonymous) (:0:0)

View File

@ -0,0 +1,185 @@
// Copyright 2018 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('stepOut async function');
session.setupScriptMap();
Protocol.Runtime.enable();
InspectorTest.runAsyncTestSuite([
async function testTrivial() {
InspectorTest.log('Check that we have proper async stack at return');
contextGroup.addInlineScript(`
async function test() {
await Promise.resolve();
await foo();
}
async function foo() {
await Promise.resolve();
await bar();
}
async function bar() {
await Promise.resolve();
debugger;
}`, 'testTrivial.js');
await runTestAndStepAction('stepOut');
},
async function testStepOutPrecision() {
InspectorTest.log('Check that stepOut go to resumed outer generator');
contextGroup.addInlineScript(`
function wait() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function floodWithTimeouts(a) {
if (!a.stop)
setTimeout(floodWithTimeouts.bind(this, a), 0);
}
async function test() {
let a = {};
floodWithTimeouts(a)
await wait();
await foo();
await wait();
a.stop = true;
}
async function foo() {
await Promise.resolve();
await bar();
await wait();
}
async function bar() {
await Promise.resolve();
debugger;
await wait();
}`, 'testStepOutPrecision.js');
await runTestAndStepAction('stepOut');
},
async function testStepIntoAtReturn() {
InspectorTest.log('Check that stepInto at return go to resumed outer generator');
contextGroup.addInlineScript(`
function wait() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function floodWithTimeouts(a) {
if (!a.stop)
setTimeout(floodWithTimeouts.bind(this, a), 0);
}
async function test() {
let a = {};
floodWithTimeouts(a)
await wait();
await foo();
a.stop = true;
}
async function foo() {
await Promise.resolve();
await bar();
}
async function bar() {
await Promise.resolve();
debugger;
}`, 'testStepIntoAtReturn.js');
await runTestAndStepAction('stepInto');
},
async function testStepOverAtReturn() {
InspectorTest.log('Check that stepOver at return go to resumed outer generator');
contextGroup.addInlineScript(`
function wait() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function floodWithTimeouts(a) {
if (!a.stop)
setTimeout(floodWithTimeouts.bind(this, a), 0);
}
async function test() {
let a = {};
floodWithTimeouts(a)
await wait();
await foo();
a.stop = true;
}
async function foo() {
await Promise.resolve();
await bar();
}
async function bar() {
await Promise.resolve();
debugger;
}`, 'testStepIntoAtReturn.js');
await runTestAndStepAction('stepOver');
},
async function testStepOutFromNotAwaitedCall() {
InspectorTest.log('Checks stepOut from not awaited call');
contextGroup.addInlineScript(`
function wait() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function floodWithTimeouts(a) {
if (!a.stop)
setTimeout(floodWithTimeouts.bind(this, a), 0);
}
async function test() {
let a = {};
floodWithTimeouts(a)
await wait();
await foo();
a.stop = true;
}
async function foo() {
let a = {};
floodWithTimeouts(a);
await Promise.resolve();
bar();
a.stop = true;
}
async function bar() {
await Promise.resolve();
debugger;
}`, 'testStepIntoAtReturn.js');
await runTestAndStepAction('stepOut');
}
]);
async function runTestAndStepAction(action) {
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
let finished =
Protocol.Runtime.evaluate({expression: 'test()', awaitPromise: true})
.then(() => false);
while (true) {
const r = await Promise.race([finished, waitPauseAndDumpStack()]);
if (!r) break;
Protocol.Debugger[action]();
}
await Protocol.Debugger.disable();
}
async function waitPauseAndDumpStack() {
const {params} = await Protocol.Debugger.oncePaused();
session.logCallFrames(params.callFrames);
session.logAsyncStackTrace(params.asyncStackTrace);
InspectorTest.log('');
return true;
}

View File

@ -0,0 +1,43 @@
Checks async instrumentation enabled in the middle.
Running test: beforeAsyncTaskScheduled
test (test.js:16:2)
(anonymous) (expr1.js:0:0)
test (test.js:21:2)
(anonymous) (expr1.js:0:0)
foo (test.js:10:2)
-- Promise.then --
test (test.js:19:14)
(anonymous) (expr1.js:0:0)
foo (test.js:12:2)
-- Promise.then --
test (test.js:19:14)
(anonymous) (expr1.js:0:0)
Running test: afterAsyncTaskScheduled
test (test.js:16:2)
(anonymous) (expr1.js:0:0)
test (test.js:21:2)
(anonymous) (expr1.js:0:0)
foo (test.js:10:2)
foo (test.js:12:2)
Running test: afterAsyncTaskStarted
test (test.js:16:2)
(anonymous) (expr1.js:0:0)
test (test.js:21:2)
(anonymous) (expr1.js:0:0)
foo (test.js:10:2)
foo (test.js:12:2)

View File

@ -0,0 +1,68 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks async instrumentation enabled in the middle.');
contextGroup.addInlineScript(
`
function foo() {
// asyncTaskStarted
debugger;
// asyncTaskFinished
debugger;
}
function test() {
debugger;
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p2 = p1.then(foo);
resolve1(); // asyncTaskScheduled
debugger;
return p2;
}`,
'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
if (enableOnPause-- === 0)
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
session.logCallFrames(message.params.callFrames);
var asyncStackTrace = message.params.asyncStackTrace;
while (asyncStackTrace) {
InspectorTest.log(`-- ${asyncStackTrace.description} --`);
session.logCallFrames(asyncStackTrace.callFrames);
asyncStackTrace = asyncStackTrace.parent;
}
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
var enableOnPause = 0;
InspectorTest.runTestSuite([
function beforeAsyncTaskScheduled(next) {
enableOnPause = 0;
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
awaitPromise: true })
.then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
.then(next);
},
function afterAsyncTaskScheduled(next) {
enableOnPause = 2;
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
awaitPromise: true })
.then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
.then(next);
},
function afterAsyncTaskStarted(next) {
enableOnPause = 3;
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
awaitPromise: true })
.then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
.then(next);
}
]);

View File

@ -0,0 +1,16 @@
Checks async stack for late .then handlers with gc
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:18:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:22:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:11:2)
-- Promise.then --
test (test.js:24:14)
(anonymous) (expr.js:0:0)

View File

@ -0,0 +1,49 @@
// Copyright 2016 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.
// Flags: --expose-gc
let {session, contextGroup, Protocol} = InspectorTest.start('Checks async stack for late .then handlers with gc');
contextGroup.addInlineScript(
`
function foo1() {
gc();
debugger;
}
function test() {
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
gc();
var p2 = p1.then(foo1);
gc();
resolve1();
gc();
var p3 = p1.then(foo1);
gc();
var p4 = p1.then(foo1);
gc();
return Promise.all([p2,p3,p4]);
}`,
'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
var asyncStackTrace = message.params.asyncStackTrace;
while (asyncStackTrace) {
InspectorTest.log(`-- ${asyncStackTrace.description} --`);
session.logCallFrames(asyncStackTrace.callFrames);
asyncStackTrace = asyncStackTrace.parent;
}
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js',
awaitPromise: true })
.then(() => Protocol.Runtime.evaluate({ expression: 'gc()'}))
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,11 @@
Checks that async stack contains setTimeout
inner1 (test.js:11:4)
foo1 (test.js:14:2)
-- setTimeout --
inner2 (test.js:18:4)
foo2 (test.js:20:2)
-- setTimeout --
inner3 (test.js:25:4)
foo3 (test.js:27:2)
(anonymous) (expr.js:0:0)

View File

@ -0,0 +1,49 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async stack contains setTimeout');
contextGroup.addInlineScript(
`
var resolveCallback;
function foo1() {
function inner1() {
debugger;
resolveCallback();
}
inner1();
}
function foo2() {
function inner2() {
setTimeout(foo1, 0);
}
inner2();
}
function foo3() {
var promise = new Promise(resolve => resolveCallback = resolve);
function inner3() {
setTimeout(foo2, 0);
}
inner3();
return promise;
}`,
'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
var asyncStackTrace = message.params.asyncStackTrace;
while (asyncStackTrace) {
InspectorTest.log(`-- ${asyncStackTrace.description} --`);
session.logCallFrames(asyncStackTrace.callFrames);
asyncStackTrace = asyncStackTrace.parent;
}
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
Protocol.Runtime.evaluate({ expression: "foo3()//# sourceURL=expr.js", awaitPromise: true })
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,37 @@
Checks that async stacks works for async/await
foo2 (test.js:15:2)
-- await --
test (test.js:24:8)
(anonymous) (expr.js:0:0)
foo2 (test.js:17:2)
-- await --
test (test.js:24:8)
(anonymous) (expr.js:0:0)
foo1 (test.js:9:2)
foo2 (test.js:18:8)
-- await --
test (test.js:24:8)
(anonymous) (expr.js:0:0)
foo1 (test.js:9:2)
-- Promise.then --
foo2 (test.js:19:43)
-- await --
test (test.js:24:8)
(anonymous) (expr.js:0:0)
foo2 (test.js:20:2)
-- await --
test (test.js:24:8)
(anonymous) (expr.js:0:0)
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}

View File

@ -0,0 +1,40 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async stacks works for async/await');
contextGroup.addInlineScript(`
async function foo1() {
debugger;
return Promise.resolve();
}
async function foo2() {
await Promise.resolve();
debugger;
await Promise.resolve();
debugger;
await foo1();
await Promise.all([ Promise.resolve() ]).then(foo1);
debugger;
}
async function test() {
await foo2();
}`, 'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js',
awaitPromise: true })
.then(InspectorTest.logMessage)
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,91 @@
Checks created frame for async call chain
Running test: testPromise
foo1 (test.js:10:2)
-- Promise.then --
promise (test.js:20:14)
(anonymous) (expr.js:0:0)
Running test: testPromiseThen
foo1 (test.js:10:2)
-- Promise.then --
promiseThen (test.js:28:14)
(anonymous) (expr.js:0:0)
foo2 (test.js:14:2)
-- Promise.then --
promiseThen (test.js:29:14)
(anonymous) (expr.js:0:0)
Running test: testPromiseThenThen
foo1 (test.js:10:2)
-- Promise.then --
promiseThenThen (test.js:37:14)
(anonymous) (expr.js:0:0)
foo1 (test.js:10:2)
-- Promise.then --
promiseThenThen (test.js:38:14)
(anonymous) (expr.js:0:0)
foo2 (test.js:14:2)
-- Promise.then --
promiseThenThen (test.js:37:25)
(anonymous) (expr.js:0:0)
Running test: testPromiseResolve
foo1 (test.js:10:2)
-- Promise.then --
promiseResolve (test.js:44:27)
(anonymous) (expr.js:0:0)
Running test: testPromiseReject
foo1 (test.js:10:2)
-- Promise.catch --
promiseReject (test.js:48:31)
(anonymous) (expr.js:0:0)
Running test: testPromiseAll
foo1 (test.js:10:2)
-- Promise.then --
promiseAll (test.js:52:44)
(anonymous) (expr.js:0:0)
Running test: testPromiseRace
foo1 (test.js:10:2)
-- Promise.then --
promiseRace (test.js:56:45)
(anonymous) (expr.js:0:0)
Running test: testThenableJob1
foo1 (test.js:10:2)
-- Promise.then --
thenableJob1 (test.js:60:72)
(anonymous) (expr.js:0:0)
Running test: testThenableJob2
foo1 (test.js:10:2)
-- Promise.then --
thenableJob2 (test.js:64:57)
(anonymous) (expr.js:0:0)
Running test: testSetTimeouts
foo1 (test.js:10:2)
(anonymous) (test.js:72:25)
-- setTimeout --
(anonymous) (test.js:72:6)
-- setTimeout --
(anonymous) (test.js:71:4)
-- setTimeout --
setTimeouts (test.js:70:2)
(anonymous) (expr.js:0:0)

View File

@ -0,0 +1,177 @@
// Copyright 2017 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.
// TODO(kozyatinskiy): fix this test.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks created frame for async call chain');
contextGroup.addInlineScript(
`
function foo1() {
debugger;
}
function foo2() {
debugger;
}
function promise() {
var resolve;
var p1 = new Promise(r => resolve = r);
var p2 = p1.then(foo1);
resolve();
return p2;
}
function promiseThen() {
var resolve;
var p1 = new Promise(r => resolve = r);
var p2 = p1.then(foo1);
var p3 = p2.then(foo2);
resolve();
return p3;
}
function promiseThenThen() {
var resolve;
var p1 = new Promise(r => resolve = r);
var p2 = p1.then(foo1).then(foo2);
var p3 = p1.then(foo1);
resolve();
return p2;
}
function promiseResolve() {
return Promise.resolve().then(foo1);
}
function promiseReject() {
return Promise.reject().catch(foo1);
}
function promiseAll() {
return Promise.all([ Promise.resolve() ]).then(foo1);
}
function promiseRace() {
return Promise.race([ Promise.resolve() ]).then(foo1);
}
function thenableJob1() {
return Promise.resolve().then(() => Promise.resolve().then(() => 42)).then(foo1);
}
function thenableJob2() {
return Promise.resolve().then(() => Promise.resolve()).then(foo1);
}
function setTimeouts() {
var resolve;
var p = new Promise(r => resolve = r);
setTimeout(() =>
setTimeout(() =>
setTimeout(() => { foo1(); resolve(); }, 0), 0), 0);
return p;
}`,
'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
InspectorTest.runTestSuite([
function testPromise(next) {
Protocol.Runtime
.evaluate(
{expression: 'promise()//# sourceURL=expr.js', awaitPromise: true})
.then(next);
},
function testPromiseThen(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseThen()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testPromiseThenThen(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseThenThen()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testPromiseResolve(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseResolve()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testPromiseReject(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseReject()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testPromiseAll(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseAll()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testPromiseRace(next) {
Protocol.Runtime
.evaluate({
expression: 'promiseRace()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testThenableJob1(next) {
Protocol.Runtime
.evaluate({
expression: 'thenableJob1()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testThenableJob2(next) {
Protocol.Runtime
.evaluate({
expression: 'thenableJob2()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
},
function testSetTimeouts(next) {
Protocol.Runtime
.evaluate({
expression: 'setTimeouts()//# sourceURL=expr.js',
awaitPromise: true
})
.then(next);
}
]);

View File

@ -0,0 +1,133 @@
Checks that async chains for promises are correct.
Running test: testPromise
foo1 (test.js:9:2)
-- Promise.then --
promise (test.js:19:14)
(anonymous) (testPromise.js:0:0)
Running test: testPromiseResolvedBySetTimeout
foo1 (test.js:9:2)
-- Promise.then --
promiseResolvedBySetTimeout (test.js:27:14)
(anonymous) (testPromiseResolvedBySetTimeout.js:0:0)
Running test: testPromiseAll
foo1 (test.js:9:2)
-- Promise.then --
promiseAll (test.js:37:35)
(anonymous) (testPromiseAll.js:0:0)
Running test: testPromiseAllReverseOrder
foo1 (test.js:9:2)
-- Promise.then --
promiseAllReverseOrder (test.js:48:35)
(anonymous) (testPromiseAllReverseOrder.js:0:0)
Running test: testPromiseRace
foo1 (test.js:9:2)
-- Promise.then --
promiseRace (test.js:59:36)
(anonymous) (testPromiseRace.js:0:0)
Running test: testTwoChainedCallbacks
foo1 (test.js:9:2)
-- Promise.then --
twoChainedCallbacks (test.js:68:14)
(anonymous) (testTwoChainedCallbacks.js:0:0)
foo2 (test.js:13:2)
-- Promise.then --
twoChainedCallbacks (test.js:68:25)
(anonymous) (testTwoChainedCallbacks.js:0:0)
Running test: testPromiseResolve
foo1 (test.js:9:2)
-- Promise.then --
promiseResolve (test.js:74:27)
(anonymous) (testPromiseResolve.js:0:0)
foo2 (test.js:13:2)
-- Promise.then --
promiseResolve (test.js:74:38)
(anonymous) (testPromiseResolve.js:0:0)
Running test: testThenableJobResolvedInSetTimeout
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedInSetTimeout (test.js:86:40)
(anonymous) (testThenableJobResolvedInSetTimeout.js:0:0)
Running test: testThenableJobResolvedInSetTimeoutWithStack
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedInSetTimeoutWithStack (test.js:104:40)
(anonymous) (testThenableJobResolvedInSetTimeoutWithStack.js:0:0)
Running test: testThenableJobResolvedByPromise
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedByPromise (test.js:118:40)
(anonymous) (testThenableJobResolvedByPromise.js:0:0)
Running test: testThenableJobResolvedByPromiseWithStack
foo1 (test.js:9:2)
-- Promise.then --
thenableJobResolvedByPromiseWithStack (test.js:136:40)
(anonymous) (testThenableJobResolvedByPromiseWithStack.js:0:0)
Running test: testLateThenCallback
foo1 (test.js:9:2)
-- Promise.then --
lateThenCallback (test.js:145:12)
(anonymous) (testLateThenCallback.js:0:0)
Running test: testComplex
inner1 (test.js:154:6)
foo1 (test.js:156:4)
-- Promise.then --
complex (test.js:202:5)
(anonymous) (testComplex.js:0:0)
(anonymous) (test.js:207:8)
-- Promise.then --
(anonymous) (test.js:206:8)
-- Promise.then --
(anonymous) (test.js:205:6)
-- setTimeout --
complex (test.js:204:2)
(anonymous) (testComplex.js:0:0)
Running test: testReject
foo1 (test.js:9:2)
-- Promise.catch --
reject (test.js:217:31)
(anonymous) (testReject.js:0:0)
Running test: testFinally1
foo1 (test.js:9:2)
-- Promise.finally --
finally1 (test.js:221:33)
(anonymous) (testFinally1.js:0:0)
Running test: testFinally2
foo1 (test.js:9:2)
-- Promise.finally --
finally2 (test.js:225:34)
(anonymous) (testFinally2.js:0:0)

View File

@ -0,0 +1,260 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async chains for promises are correct.');
contextGroup.addInlineScript(
`
function foo1() {
debugger;
}
function foo2() {
debugger;
}
function promise() {
var resolve;
var p1 = new Promise(r => resolve = r);
var p2 = p1.then(foo1);
resolve();
return p2;
}
function promiseResolvedBySetTimeout() {
var resolve;
var p1 = new Promise(r => resolve = r);
var p2 = p1.then(foo1);
setTimeout(resolve, 0);
return p2;
}
function promiseAll() {
var resolve1;
var resolve2;
var p1 = new Promise(resolve => resolve1 = resolve);
var p2 = new Promise(resolve => resolve2 = resolve);
var p3 = Promise.all([ p1, p2 ]).then(foo1);
resolve1();
resolve2();
return p3;
}
function promiseAllReverseOrder() {
var resolve1;
var resolve2;
var p1 = new Promise(resolve => resolve1 = resolve);
var p2 = new Promise(resolve => resolve2 = resolve);
var p3 = Promise.all([ p1, p2 ]).then(foo1);
resolve2();
resolve1();
return p3;
}
function promiseRace() {
var resolve1;
var resolve2;
var p1 = new Promise(resolve => resolve1 = resolve);
var p2 = new Promise(resolve => resolve2 = resolve);
var p3 = Promise.race([ p1, p2 ]).then(foo1);
resolve1();
resolve2();
return p3;
}
function twoChainedCallbacks() {
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p2 = p1.then(foo1).then(foo2);
resolve1();
return p2;
}
function promiseResolve() {
return Promise.resolve().then(foo1).then(foo2);
}
function thenableJobResolvedInSetTimeout() {
function thenableJob() {
var resolve2;
var p2 = new Promise(resolve => resolve2 = resolve);
setTimeout(resolve2, 0);
return p2;
}
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p3 = p1.then(() => thenableJob()).then(foo1);
resolve1();
return p3;
}
function thenableJobResolvedInSetTimeoutWithStack() {
function thenableJob() {
function inner() {
resolve2();
}
var resolve2;
var p2 = new Promise(resolve => resolve2 = resolve);
setTimeout(inner, 0);
return p2;
}
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p3 = p1.then(() => thenableJob()).then(foo1);
resolve1();
return p3;
}
function thenableJobResolvedByPromise() {
function thenableJob() {
var resolve2;
var p2 = new Promise(resolve => resolve2 = resolve);
Promise.resolve().then(resolve2);
return p2;
}
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p3 = p1.then(() => thenableJob()).then(foo1);
resolve1();
return p3;
}
function thenableJobResolvedByPromiseWithStack() {
function thenableJob() {
function inner() {
resolve2();
}
var resolve2;
var p2 = new Promise(resolve => resolve2 = resolve);
Promise.resolve().then(inner);
return p2;
}
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
var p3 = p1.then(() => thenableJob()).then(foo1);
resolve1();
return p3;
}
function lateThenCallback() {
var resolve1;
var p1 = new Promise(resolve => resolve1 = resolve);
resolve1();
return p1.then(foo1);
}
function complex() {
var testResolve;
var testPromise = new Promise(resolve => testResolve = resolve);
function foo1() {
function inner1() {
debugger;
}
inner1();
}
function foo2() {
var resolve20;
function inner2() {
resolve20();
}
var p20 = new Promise(resolve => resolve20 = resolve);
Promise.resolve().then(inner2);
return p20;
}
function foo3() {
var resolve17;
function inner3() {
resolve17();
}
var p17 = new Promise(resolve => resolve17 = resolve);
setTimeout(inner3, 0);
return p17;
}
function foo4() {
function inner4() {
return;
}
return inner4();
}
function foo5() {
return Promise.all([ Promise.resolve(), Promise.resolve() ])
.then(() => 42);
}
function foo6() {
return Promise.race([ Promise.resolve(), Promise.resolve()])
.then(() => 42);
}
var p = Promise.resolve()
.then(foo6)
.then(foo5)
.then(foo4)
.then(foo3)
.then(foo2)
.then(foo1);
setTimeout(() => {
p.then(() => {
p.then(() => {
debugger;
testResolve();
})
})
}, 0)
return testPromise;
}
function reject() {
return Promise.reject().catch(foo1);
}
function finally1() {
return Promise.reject().finally(foo1);
}
function finally2() {
return Promise.resolve().finally(foo1);
}`,
'test.js');
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
var testList = [
'promise', 'promiseResolvedBySetTimeout', 'promiseAll',
'promiseAllReverseOrder', 'promiseRace', 'twoChainedCallbacks',
'promiseResolve', 'thenableJobResolvedInSetTimeout',
'thenableJobResolvedInSetTimeoutWithStack', 'thenableJobResolvedByPromise',
'thenableJobResolvedByPromiseWithStack', 'lateThenCallback', 'complex',
'reject', 'finally1', 'finally2'
]
InspectorTest.runTestSuite(testList.map(name => {
return eval(`
(function test${capitalize(name)}(next) {
Protocol.Runtime.evaluate({ expression: \`${name}()
//# sourceURL=test${capitalize(name)}.js\`, awaitPromise: true})
.then(next);
})
`);
}));
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

View File

@ -0,0 +1,44 @@
Tests super long async stacks.
Running test: test
(anonymous) (expr.js:0:26)
callWithAsyncStack (utils.js:3:4)
call1 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call2 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call3 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call4 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call5 (wrapper.js:0:20)
(fetch parent..)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call6 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call7 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call8 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call9 (wrapper.js:0:20)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call10 (wrapper.js:0:21)
(fetch parent..)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call11 (wrapper.js:0:21)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
call12 (wrapper.js:0:21)
--Promise.then--
callWithAsyncStack (utils.js:7:20)
(anonymous) (expr.js:0:0)

View File

@ -0,0 +1,45 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests super long async stacks.');
contextGroup.addScript(`
function callWithAsyncStack(f, depth) {
if (depth === 0) {
f();
return;
}
wrapper = eval('(function call' + depth + '() { callWithAsyncStack(f, depth - 1) }) //# sourceURL=wrapper.js');
Promise.resolve().then(wrapper);
}
//# sourceURL=utils.js`);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([async function test() {
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 4});
Protocol.Runtime.evaluate({
expression: 'callWithAsyncStack(() => {debugger}, 12)//# sourceURL=expr.js'
});
let {params} = await Protocol.Debugger.oncePaused();
let {callFrames, asyncStackTrace, externalAsyncStackTrace} = params;
while (true) {
session.logCallFrames(callFrames);
if (externalAsyncStackTrace) {
InspectorTest.log('(fetch parent..)');
asyncStackTrace = (await Protocol.Debugger.getStackTrace({
stackTraceId: externalAsyncStackTrace
})).result.stackTrace;
}
if (asyncStackTrace) {
InspectorTest.log('--' + asyncStackTrace.description + '--');
callFrames = asyncStackTrace.callFrames;
externalAsyncStackTrace = asyncStackTrace.parentId;
asyncStackTrace = asyncStackTrace.parent;
} else {
break;
}
}
}]);

View File

@ -0,0 +1,219 @@
Break locations around function calls
Running test: testFunctionCallAsArgument
Break locations in expression:
function test() {
|C|foo2(|C|foo1())
}
Breakpoint at:
function test() {
#foo2(foo1())
}
Break at:
function test() {
#foo2(foo1())
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo2(#foo1())
}
Break at:
function test() {
foo2(#foo1())
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at expression line.
function test() {
#foo2(foo1())
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Running test: testFunctionCallAsArgument
Break locations in expression:
function test() {
|C|foo2(|C|foo1());
}
Breakpoint at:
function test() {
#foo2(foo1());
}
Break at:
function test() {
#foo2(foo1());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo2(#foo1());
}
Break at:
function test() {
foo2(#foo1());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at expression line.
function test() {
#foo2(foo1());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Running test: testFunctionCallAsArguments
Break locations in expression:
function test() {
|C|foo3(|C|foo1(), |C|foo2());
}
Breakpoint at:
function test() {
#foo3(foo1(), foo2());
}
Break at:
function test() {
#foo3(foo1(), foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo3(#foo1(), foo2());
}
Break at:
function test() {
foo3(#foo1(), foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo3(foo1(), #foo2());
}
Break at:
function test() {
foo3(foo1(), #foo2());
}
Debugger.stepInto called
function foo1() {}
function foo2() {#}
function foo3() {}
Breakpoint at expression line.
function test() {
#foo3(foo1(), foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Running test: testFunctionCallInBinaryExpression
Break locations in expression:
function test() {
|C|foo3(|C|foo1() + |C|foo2());
}
Breakpoint at:
function test() {
#foo3(foo1() + foo2());
}
Break at:
function test() {
#foo3(foo1() + foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo3(#foo1() + foo2());
}
Break at:
function test() {
foo3(#foo1() + foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}
Breakpoint at:
function test() {
foo3(foo1() + #foo2());
}
Break at:
function test() {
foo3(foo1() + #foo2());
}
Debugger.stepInto called
function foo1() {}
function foo2() {#}
function foo3() {}
Breakpoint at expression line.
function test() {
#foo3(foo1() + foo2());
}
Debugger.stepInto called
function foo1() {#}
function foo2() {}

View File

@ -0,0 +1,82 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Break locations around function calls');
contextGroup.addScript(`
function foo1() {}
function foo2() {}
function foo3() {}
//# sourceURL=test.js`);
InspectorTest.logProtocolCommandCalls('Debugger.stepInto');
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testFunctionCallAsArgument() {
await testExpression('foo2(foo1())');
},
async function testFunctionCallAsArgument() {
await testExpression('foo2(foo1());');
},
async function testFunctionCallAsArguments() {
await testExpression('foo3(foo1(), foo2());');
},
async function testFunctionCallInBinaryExpression() {
await testExpression('foo3(foo1() + foo2());');
},
]);
async function logPauseLocation() {
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logSourceLocation(callFrames[0].location);
}
async function testExpression(expression) {
await Protocol.Debugger.enable();
let wrapper = `function test() {
${expression}
}
//# sourceURL=test-function.js`;
Protocol.Runtime.evaluate({expression: wrapper});
let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
start: {lineNumber: 0, columnNumber : 0, scriptId}});
locations = locations.filter(location => location.lineNumber === 1);
InspectorTest.log('Break locations in expression:');
await session.logBreakLocations(locations);
for (let location of locations) {
InspectorTest.log('Breakpoint at:');
await session.logSourceLocation(location);
let {result:{breakpointId}} = await Protocol.Debugger.setBreakpoint({
location});
let evaluate = Protocol.Runtime.evaluate({
expression: 'test();\n//# sourceURL=expr.js'});
InspectorTest.log('Break at:');
await logPauseLocation();
Protocol.Debugger.stepInto();
await logPauseLocation();
await Protocol.Debugger.removeBreakpoint({breakpointId});
Protocol.Debugger.resume();
await evaluate;
}
InspectorTest.log('Breakpoint at expression line.')
let {result:{breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 1, url: 'test-function.js'});
let evaluate = Protocol.Runtime.evaluate({
expression: 'test();\n//# sourceURL=expr.js'});
await logPauseLocation();
Protocol.Debugger.stepInto();
await logPauseLocation();
await Protocol.Debugger.removeBreakpoint({breakpointId});
Protocol.Debugger.resume();
await evaluate;
await Protocol.Debugger.disable();
}

View File

@ -0,0 +1,361 @@
Tests breakable locations in await expression.
Running test: testBreakLocations
function testFunction() {
async function f1() {
for (let x = |_|0; x |_|< 1; ++|_|x) |_|await x;
|_|return await Promise.|C|resolve(2);|R|
}
async function f2() {
let r = |_|await |C|f1() + await |C|f1();
|_|await |C|f1();
|_|await |C|f1().|C|then(x => x |_|* 2|R|);
|_|await [1].|C|map(x => Promise.|C|resolve(x)|R|)[0];
|_|await Promise.|C|resolve().|C|then(x => x |_|* 2|R|);
let p = |_|Promise.|C|resolve(42);
|_|await p;
|_|return r;|R|
}
return |C|f2();|R|
}
Running test: testStepInto
(anonymous) (expr.js:0:0)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
return #f2();
}
f2 (test.js:8:12)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
async function f2() {
let r = #await f1() + await f1();
await f1();
f1 (test.js:3:17)
f2 (test.js:8:18)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
async function f1() {
for (let x = #0; x < 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
f2 (test.js:8:18)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:32)
f2 (test.js:8:18)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
async function f1() {
for (let x = 0; x < 1; ++x) #await x;
return await Promise.resolve(2);
f1 (test.js:3:29)
async function f1() {
for (let x = 0; x < 1; ++#x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:4:4)
for (let x = 0; x < 1; ++x) await x;
#return await Promise.resolve(2);
}
f1 (test.js:4:36)
for (let x = 0; x < 1; ++x) await x;
return await Promise.resolve(2);#
}
f2 (test.js:8:31)
async function f2() {
let r = await f1() + await #f1();
await f1();
f1 (test.js:3:17)
f2 (test.js:8:31)
async function f1() {
for (let x = #0; x < 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
f2 (test.js:8:31)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:32)
f2 (test.js:8:31)
async function f1() {
for (let x = 0; x < 1; ++x) #await x;
return await Promise.resolve(2);
f1 (test.js:3:29)
async function f1() {
for (let x = 0; x < 1; ++#x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:4:4)
for (let x = 0; x < 1; ++x) await x;
#return await Promise.resolve(2);
}
f1 (test.js:4:36)
for (let x = 0; x < 1; ++x) await x;
return await Promise.resolve(2);#
}
f2 (test.js:9:4)
let r = await f1() + await f1();
#await f1();
await f1().then(x => x * 2);
f1 (test.js:3:17)
f2 (test.js:9:10)
async function f1() {
for (let x = #0; x < 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
f2 (test.js:9:10)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:32)
f2 (test.js:9:10)
async function f1() {
for (let x = 0; x < 1; ++x) #await x;
return await Promise.resolve(2);
f1 (test.js:3:29)
async function f1() {
for (let x = 0; x < 1; ++#x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:4:4)
for (let x = 0; x < 1; ++x) await x;
#return await Promise.resolve(2);
}
f1 (test.js:4:36)
for (let x = 0; x < 1; ++x) await x;
return await Promise.resolve(2);#
}
f2 (test.js:10:4)
await f1();
#await f1().then(x => x * 2);
await [1].map(x => Promise.resolve(x))[0];
f1 (test.js:3:17)
f2 (test.js:10:10)
async function f1() {
for (let x = #0; x < 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
f2 (test.js:10:10)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:32)
f2 (test.js:10:10)
async function f1() {
for (let x = 0; x < 1; ++x) #await x;
return await Promise.resolve(2);
f1 (test.js:3:29)
async function f1() {
for (let x = 0; x < 1; ++#x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:4:4)
for (let x = 0; x < 1; ++x) await x;
#return await Promise.resolve(2);
}
f1 (test.js:4:36)
for (let x = 0; x < 1; ++x) await x;
return await Promise.resolve(2);#
}
(anonymous) (test.js:10:27)
await f1();
await f1().then(x => x #* 2);
await [1].map(x => Promise.resolve(x))[0];
(anonymous) (test.js:10:30)
await f1();
await f1().then(x => x * 2#);
await [1].map(x => Promise.resolve(x))[0];
f2 (test.js:11:4)
await f1().then(x => x * 2);
#await [1].map(x => Promise.resolve(x))[0];
await Promise.resolve().then(x => x * 2);
(anonymous) (test.js:11:31)
f2 (test.js:11:14)
await f1().then(x => x * 2);
await [1].map(x => Promise.#resolve(x))[0];
await Promise.resolve().then(x => x * 2);
(anonymous) (test.js:11:41)
f2 (test.js:11:14)
await f1().then(x => x * 2);
await [1].map(x => Promise.resolve(x)#)[0];
await Promise.resolve().then(x => x * 2);
f2 (test.js:12:4)
await [1].map(x => Promise.resolve(x))[0];
#await Promise.resolve().then(x => x * 2);
let p = Promise.resolve(42);
f2 (test.js:13:12)
await Promise.resolve().then(x => x * 2);
let p = #Promise.resolve(42);
await p;
f2 (test.js:14:4)
let p = Promise.resolve(42);
#await p;
return r;
f2 (test.js:15:4)
await p;
#return r;
}
f2 (test.js:15:13)
await p;
return r;#
}
Running test: testStepOver
f2 (test.js:8:12)
testFunction (test.js:18:9)
(anonymous) (expr.js:0:0)
async function f2() {
let r = #await f1() + await f1();
await f1();
f2 (test.js:8:31)
async function f2() {
let r = await f1() + await #f1();
await f1();
f2 (test.js:9:4)
let r = await f1() + await f1();
#await f1();
await f1().then(x => x * 2);
f2 (test.js:10:4)
await f1();
#await f1().then(x => x * 2);
await [1].map(x => Promise.resolve(x))[0];
f2 (test.js:11:4)
await f1().then(x => x * 2);
#await [1].map(x => Promise.resolve(x))[0];
await Promise.resolve().then(x => x * 2);
f2 (test.js:12:4)
await [1].map(x => Promise.resolve(x))[0];
#await Promise.resolve().then(x => x * 2);
let p = Promise.resolve(42);
f2 (test.js:13:12)
await Promise.resolve().then(x => x * 2);
let p = #Promise.resolve(42);
await p;
f2 (test.js:14:4)
let p = Promise.resolve(42);
#await p;
return r;
f2 (test.js:15:4)
await p;
#return r;
}
f2 (test.js:15:13)
await p;
return r;#
}
Running test: testStepIntoAfterBreakpoint
f2 (test.js:9:4)
let r = await f1() + await f1();
#await f1();
await f1().then(x => x * 2);
f1 (test.js:3:17)
f2 (test.js:9:10)
async function f1() {
for (let x = #0; x < 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
f2 (test.js:9:10)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:3:32)
f2 (test.js:9:10)
async function f1() {
for (let x = 0; x < 1; ++x) #await x;
return await Promise.resolve(2);
f1 (test.js:3:29)
async function f1() {
for (let x = 0; x < 1; ++#x) await x;
return await Promise.resolve(2);
f1 (test.js:3:22)
async function f1() {
for (let x = 0; x #< 1; ++x) await x;
return await Promise.resolve(2);
f1 (test.js:4:4)
for (let x = 0; x < 1; ++x) await x;
#return await Promise.resolve(2);
}

View File

@ -0,0 +1,126 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests breakable locations in await expression.');
let source = `
function testFunction() {
async function f1() {
for (let x = 0; x < 1; ++x) await x;
return await Promise.resolve(2);
}
async function f2() {
let r = await f1() + await f1();
await f1();
await f1().then(x => x * 2);
await [1].map(x => Promise.resolve(x))[0];
await Promise.resolve().then(x => x * 2);
let p = Promise.resolve(42);
await p;
return r;
}
return f2();
}
//# sourceURL=test.js`;
contextGroup.addScript(source);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testBreakLocations() {
Protocol.Debugger.enable();
let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
start: {lineNumber: 0, columnNumber : 0, scriptId}});
dumpAllLocations(locations);
},
async function testStepInto() {
Protocol.Debugger.pause();
let fin = Protocol.Runtime.evaluate({
expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
let result;
while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
let {params:{callFrames}} = result;
session.logCallFrames(callFrames);
session.logSourceLocation(callFrames[0].location);
Protocol.Debugger.stepInto();
}
Protocol.Runtime.evaluate({expression: '42'});
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
},
async function testStepOver() {
Protocol.Debugger.pause();
let fin = Protocol.Runtime.evaluate({
expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
Protocol.Debugger.stepInto();
await Protocol.Debugger.oncePaused();
Protocol.Debugger.stepInto();
await Protocol.Debugger.oncePaused();
let result;
while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
let {params:{callFrames}} = result;
session.logCallFrames(callFrames);
session.logSourceLocation(callFrames[0].location);
Protocol.Debugger.stepOver();
}
Protocol.Runtime.evaluate({expression: '42'});
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
},
async function testStepIntoAfterBreakpoint() {
Protocol.Debugger.setBreakpointByUrl({lineNumber: 9, url: 'test.js'});
Protocol.Runtime.evaluate({
expression: 'testFunction()//# sourceURL=expr.js'});
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
await Protocol.Debugger.resume();
async function awaitPausedAndDump() {
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
session.logSourceLocation(callFrames[0].location);
}
}
]);
function dumpAllLocations(locations) {
var lines = source.split('\n');
var locations = locations.sort((loc1, loc2) => {
if (loc2.lineNumber !== loc1.lineNumber) return loc2.lineNumber - loc1.lineNumber;
return loc2.columnNumber - loc1.columnNumber;
});
for (var location of locations) {
var line = lines[location.lineNumber];
line = line.slice(0, location.columnNumber) + locationMark(location.type) + line.slice(location.columnNumber);
lines[location.lineNumber] = line;
}
lines = lines.filter(line => line.indexOf('//# sourceURL=') === -1);
InspectorTest.log(lines.join('\n') + '\n');
}
function locationMark(type) {
if (type === 'return') return '|R|';
if (type === 'call') return '|C|';
if (type === 'debuggerStatement') return '|D|';
return '|_|';
}

View File

@ -0,0 +1,200 @@
Tests breakable locations in variable initializations.
Running test: testBreakLocations
Running test: testStepInto
function testFunction() {
var obj1 = |_|{a : 1};
var arr1 = |_|[1];
var promise = |_|Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
|_|Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
|_|promise = Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
var a = |_|1;
const x = |_|(a = 20);
var y = |_|(a = 100);
var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f();
function f() {
for (let { x, y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; }
|R|}
var b = obj1.|_|a;
|_|(async function asyncF() {
let r = |_|await Promise.|C|resolve(42);
|_|return r;|R|
})|C|();
|_|return promise;|R|
}
(anonymous) (expr.js:0:0)
testFunction (test.js:2:13)
(anonymous) (expr.js:0:0)
function testFunction() {
var obj1 = #{a : 1};
var arr1 = [1];
testFunction (test.js:3:13)
(anonymous) (expr.js:0:0)
var obj1 = {a : 1};
var arr1 = #[1];
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
testFunction (test.js:4:16)
(anonymous) (expr.js:0:0)
var arr1 = [1];
var promise = #Promise.resolve(1).then(x => x * 2).then(x => x / 2);
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
testFunction (test.js:5:2)
(anonymous) (expr.js:0:0)
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
#Promise.resolve(1).then(x => x * 2).then(x => x / 2);
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
testFunction (test.js:6:2)
(anonymous) (expr.js:0:0)
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
#promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
var a = 1;
testFunction (test.js:7:10)
(anonymous) (expr.js:0:0)
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
var a = #1;
const x = (a = 20);
testFunction (test.js:8:12)
(anonymous) (expr.js:0:0)
var a = 1;
const x = #(a = 20);
var y = (a = 100);
testFunction (test.js:9:10)
(anonymous) (expr.js:0:0)
const x = (a = 20);
var y = #(a = 100);
var z = x + (a = 1) + (a = 2) + (a = 3) + f();
testFunction (test.js:10:10)
(anonymous) (expr.js:0:0)
var y = (a = 100);
var z = #x + (a = 1) + (a = 2) + (a = 3) + f();
function f() {
f (test.js:12:24)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
f (test.js:12:42)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = { x: 0, y: 1 }; y #> 0; --y) { let z = x + y; }
}
f (test.js:12:62)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = #x + y; }
}
f (test.js:12:49)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = { x: 0, y: 1 }; y > 0; --#y) { let z = x + y; }
}
f (test.js:12:42)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = { x: 0, y: 1 }; y #> 0; --y) { let z = x + y; }
}
f (test.js:13:2)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
#}
var b = obj1.a;
testFunction (test.js:14:15)
(anonymous) (expr.js:0:0)
}
var b = obj1.#a;
(async function asyncF() {
testFunction (test.js:15:2)
(anonymous) (expr.js:0:0)
var b = obj1.a;
#(async function asyncF() {
let r = await Promise.resolve(42);
asyncF (test.js:16:12)
testFunction (test.js:18:4)
(anonymous) (expr.js:0:0)
(async function asyncF() {
let r = #await Promise.resolve(42);
return r;
asyncF (test.js:17:4)
let r = await Promise.resolve(42);
#return r;
})();
asyncF (test.js:17:13)
let r = await Promise.resolve(42);
return r;#
})();
(anonymous) (test.js:4:64)
var arr1 = [1];
var promise = Promise.resolve(1).then(x => x * 2).then(x => x #/ 2);
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
(anonymous) (test.js:4:67)
var arr1 = [1];
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2#);
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
(anonymous) (test.js:5:50)
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
Promise.resolve(1).then(x => x * 2).then(x => x #/ 2);
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
(anonymous) (test.js:5:53)
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
Promise.resolve(1).then(x => x * 2).then(x => x / 2#);
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
(anonymous) (test.js:6:60)
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
promise = Promise.resolve(1).then(x => x * 2).then(x => x #/ 2);
var a = 1;
(anonymous) (test.js:6:63)
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2#);
var a = 1;
Running test: testStepIntoAfterBreakpoint
testFunction (test.js:10:10)
(anonymous) (expr.js:0:0)
var y = (a = 100);
var z = #x + (a = 1) + (a = 2) + (a = 3) + f();
function f() {
f (test.js:12:24)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}

View File

@ -0,0 +1,74 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests breakable locations in variable initializations.');
let source = `
function testFunction() {
var obj1 = {a : 1};
var arr1 = [1];
var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
Promise.resolve(1).then(x => x * 2).then(x => x / 2);
promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
var a = 1;
const x = (a = 20);
var y = (a = 100);
var z = x + (a = 1) + (a = 2) + (a = 3) + f();
function f() {
for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
var b = obj1.a;
(async function asyncF() {
let r = await Promise.resolve(42);
return r;
})();
return promise;
}
//# sourceURL=test.js`;
contextGroup.addScript(source);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testBreakLocations() {
Protocol.Debugger.enable();
let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
start: {lineNumber: 0, columnNumber : 0, scriptId}});
session.logBreakLocations(locations);
},
async function testStepInto() {
Protocol.Debugger.pause();
let fin = Protocol.Runtime.evaluate({
expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
let result;
while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
let {params:{callFrames}} = result;
session.logCallFrames(callFrames);
session.logSourceLocation(callFrames[0].location);
Protocol.Debugger.stepInto();
}
Protocol.Runtime.evaluate({expression: '42'});
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
},
async function testStepIntoAfterBreakpoint() {
Protocol.Debugger.setBreakpointByUrl({lineNumber: 10, url: 'test.js'});
Protocol.Runtime.evaluate({
expression: 'testFunction()//# sourceURL=expr.js'});
await awaitPausedAndDump();
Protocol.Debugger.stepInto();
await awaitPausedAndDump();
await Protocol.Debugger.resume();
async function awaitPausedAndDump() {
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
session.logSourceLocation(callFrames[0].location);
}
}
]);

View File

@ -0,0 +1,200 @@
Tests for break on exception and stepping.
Running test: testStepThrougA
function a() { #n(); };
function b() { c(); };
Running test: testStepThrougB
paused on exception:
{
reasons : [
[0] : {
reason : step
}
[1] : {
reason : other
}
]
}
function a() { n(); };
function b() { #c(); };
function c() { n(); };
function b() { c(); };
function c() { #n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } };
Running test: testStepThrougD
paused on exception:
{
reasons : [
[0] : {
reason : step
}
[1] : {
reason : other
}
]
}
function c() { n(); };
function d() { #x = 1; try { e(); } catch(x) { x = 2; } };
function e() { n(); };
function c() { n(); };
function d() { x = 1; try { #e(); } catch(x) { x = 2; } };
function e() { n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } };
function e() { #n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
function c() { n(); };
function d() { x = 1; try { e(); } catch(x) { #x = 2; } };
function e() { n(); };
function c() { n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } #};
function e() { n(); };
Running test: testStepThrougDWithBreakOnAllExceptions
paused on exception:
{
reasons : [
[0] : {
reason : step
}
[1] : {
reason : other
}
]
}
function c() { n(); };
function d() { #x = 1; try { e(); } catch(x) { x = 2; } };
function e() { n(); };
function c() { n(); };
function d() { x = 1; try { #e(); } catch(x) { x = 2; } };
function e() { n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } };
function e() { #n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
paused on exception:
{
className : ReferenceError
description : ReferenceError: n is not defined at e (<anonymous>:6:16) at d (<anonymous>:5:29) at expr.js:1:1
objectId : <objectId>
subtype : error
type : object
uncaught : false
}
function d() { x = 1; try { e(); } catch(x) { x = 2; } };
function e() { #n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
function c() { n(); };
function d() { x = 1; try { e(); } catch(x) { #x = 2; } };
function e() { n(); };
function c() { n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } #};
function e() { n(); };
Running test: testStepThrougF
paused on exception:
{
reasons : [
[0] : {
reason : step
}
[1] : {
reason : other
}
]
}
function e() { n(); };
function f() { #x = 1; try { g(); } catch(x) { x = 2; } };
function g() { h(); };
function e() { n(); };
function f() { x = 1; try { #g(); } catch(x) { x = 2; } };
function g() { h(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
function g() { #h(); };
function h() { x = 1; throw 1; };
function g() { h(); };
function h() { #x = 1; throw 1; };
function g() { h(); };
function h() { x = 1; #throw 1; };
function e() { n(); };
function f() { x = 1; try { g(); } catch(x) { #x = 2; } };
function g() { h(); };
function e() { n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } #};
function g() { h(); };
Running test: testStepThrougFWithBreakOnAllExceptions
paused on exception:
{
reasons : [
[0] : {
reason : step
}
[1] : {
reason : other
}
]
}
function e() { n(); };
function f() { #x = 1; try { g(); } catch(x) { x = 2; } };
function g() { h(); };
function e() { n(); };
function f() { x = 1; try { #g(); } catch(x) { x = 2; } };
function g() { h(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
function g() { #h(); };
function h() { x = 1; throw 1; };
function g() { h(); };
function h() { #x = 1; throw 1; };
function g() { h(); };
function h() { x = 1; #throw 1; };
paused on exception:
{
description : 1
type : number
uncaught : false
value : 1
}
function g() { h(); };
function h() { x = 1; #throw 1; };
function e() { n(); };
function f() { x = 1; try { g(); } catch(x) { #x = 2; } };
function g() { h(); };
function e() { n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } #};
function g() { h(); };

View File

@ -0,0 +1,69 @@
// Copyright 2018 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Tests for break on exception and stepping.');
session.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Debugger.setBlackboxPatterns({patterns: ['expr\.js']});
Protocol.Debugger.onPaused(async ({params:{callFrames:[topFrame], data}}) => {
if (data) {
InspectorTest.log('paused on exception:');
InspectorTest.logMessage(data);
}
await session.logSourceLocation(topFrame.location);
Protocol.Debugger.stepInto();
});
contextGroup.addScript(`
function a() { n(); };
function b() { c(); };
function c() { n(); };
function d() { x = 1; try { e(); } catch(x) { x = 2; } };
function e() { n(); };
function f() { x = 1; try { g(); } catch(x) { x = 2; } };
function g() { h(); };
function h() { x = 1; throw 1; };
`);
InspectorTest.runAsyncTestSuite([
async function testStepThrougA() {
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'a()\n//# sourceURL=expr.js'});
},
async function testStepThrougB() {
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'b()\n//# sourceURL=expr.js'});
},
async function testStepThrougD() {
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'd()\n//# sourceURL=expr.js'});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testStepThrougDWithBreakOnAllExceptions() {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'd()\n//# sourceURL=expr.js'});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testStepThrougF() {
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'f()\n//# sourceURL=expr.js'});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testStepThrougFWithBreakOnAllExceptions() {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
Protocol.Debugger.pause();
await Protocol.Runtime.evaluate({expression: 'f()\n//# sourceURL=expr.js'});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
}
]);

View File

@ -0,0 +1,56 @@
Check that "break on exceptions" works for async generators.
Running test: testSimpleGeneratorThrowCaught
Paused for CAUGHT exception.
Running test: testSimpleGeneratorThrowUncaught
Paused for UNCAUGHT exception.
Running test: testYieldBeforeThrowCaught
Paused for CAUGHT exception.
Running test: testYieldBeforeThrowUncaught
Paused for UNCAUGHT exception.
Running test: testAwaitBeforeThrowCaught
Paused for CAUGHT exception.
Running test: testAwaitBeforeThrowUncaught
Paused for UNCAUGHT exception.
Running test: testYieldBeforeThrowWithAwaitCaught
Paused for CAUGHT exception.
Running test: testYieldBeforeThrowWithAwaitUncaught
Paused for UNCAUGHT exception.
Running test: testAwaitBeforeThrowWithYieldCaught
Paused for CAUGHT exception.
Running test: testAwaitBeforeThrowWithYieldUncaught
Paused for UNCAUGHT exception.
Running test: testYieldThrowsCaught
Paused for CAUGHT exception.
Running test: testYieldThrowsUncaught
Paused for UNCAUGHT exception.
Running test: testYieldThrowsCaughtInGenerator
Paused for CAUGHT exception.
Paused for UNCAUGHT exception.
Running test: testAwaitThrowsCaught
Paused for CAUGHT exception.
Running test: testAwaitThrowsUncaught
Paused for UNCAUGHT exception.
Running test: testYieldThrowMethodCaught
Paused for CAUGHT exception.
Running test: testYieldThrowMethodUncaught
Paused for UNCAUGHT exception.
Running test: testYieldThrowMethodCaughtInGenerator
Paused for UNCAUGHT exception.

View File

@ -0,0 +1,153 @@
// Copyright 2023 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Check that "break on exceptions" works for async generators.');
contextGroup.addScript(`
async function* simpleThrow() {
throw new Error();
}
async function* yieldBeforeThrow() {
yield 1;
throw new Error();
}
async function* awaitBeforeThrow() {
await 1;
throw new Error();
}
async function* yieldBeforeThrowWithAwait() {
await 1;
yield 2;
throw new Error();
}
async function* awaitBeforeThrowWithYield() {
yield 1;
await 2;
throw new Error();
}
async function* yieldThrows() {
yield 1;
yield thrower();
}
async function* yieldThrowsCaughtInGenerator() {
try {
yield 1;
yield thrower();
} catch {
throw new Error();
}
}
async function* awaitThrows() {
yield 1;
await thrower();
}
async function runGenWithCatch(gen) {
try {
for await (const val of gen());
} catch {}
}
async function runGenWithoutCatch(gen) {
for await (const val of gen());
}
async function injectExceptionIntoGen(gen) {
const g = gen();
await gen.next();
await gen.throw(new Error());
}
async function injectExceptionIntoGenWithCatch(gen) {
try {
const g = gen();
await gen.next();
await gen.throw(new Error());
} catch {}
}
async function thrower() {
await 1; // Suspend once.
throw new Error();
}`);
Protocol.Debugger.onPaused(async ({ params: { data }}) => {
const caughtOrUncaught = data.uncaught ? 'UNCAUGHT' : 'CAUGHT';
InspectorTest.log(`Paused for ${caughtOrUncaught} exception.`);
await Protocol.Debugger.resume();
});
async function runTest(expression) {
await Promise.all([
Protocol.Debugger.enable(),
Protocol.Debugger.setPauseOnExceptions({state: 'all'}),
]);
await Protocol.Runtime.evaluate({ expression, awaitPromise: true });
await Protocol.Debugger.disable();
}
InspectorTest.runAsyncTestSuite([
async function testSimpleGeneratorThrowCaught() {
await runTest('runGenWithCatch(simpleThrow)');
},
async function testSimpleGeneratorThrowUncaught() {
await runTest('runGenWithoutCatch(simpleThrow)');
},
async function testYieldBeforeThrowCaught() {
await runTest('runGenWithCatch(yieldBeforeThrow)');
},
async function testYieldBeforeThrowUncaught() {
await runTest('runGenWithoutCatch(yieldBeforeThrow)');
},
async function testAwaitBeforeThrowCaught() {
await runTest('runGenWithCatch(awaitBeforeThrow)');
},
async function testAwaitBeforeThrowUncaught() {
await runTest('runGenWithoutCatch(awaitBeforeThrow)');
},
async function testYieldBeforeThrowWithAwaitCaught() {
await runTest('runGenWithCatch(yieldBeforeThrowWithAwait)');
},
async function testYieldBeforeThrowWithAwaitUncaught() {
await runTest('runGenWithoutCatch(yieldBeforeThrowWithAwait)');
},
async function testAwaitBeforeThrowWithYieldCaught() {
await runTest('runGenWithCatch(awaitBeforeThrowWithYield)');
},
async function testAwaitBeforeThrowWithYieldUncaught() {
await runTest('runGenWithoutCatch(awaitBeforeThrowWithYield)');
},
async function testYieldThrowsCaught() {
await runTest('runGenWithCatch(yieldThrows)');
},
async function testYieldThrowsUncaught() {
await runTest('runGenWithoutCatch(yieldThrows)');
},
async function testYieldThrowsCaughtInGenerator() {
await runTest('runGenWithoutCatch(yieldThrowsCaughtInGenerator)');
},
async function testAwaitThrowsCaught() {
await runTest('runGenWithCatch(awaitThrows)');
},
async function testAwaitThrowsUncaught() {
await runTest('runGenWithoutCatch(awaitThrows)');
},
async function testYieldThrowMethodCaught() {
await runTest('injectExceptionIntoGenWithCatch(yieldThrows)');
},
async function testYieldThrowMethodUncaught() {
await runTest('injectExceptionIntoGen(yieldThrows)');
},
async function testYieldThrowMethodCaughtInGenerator() {
await runTest('injectExceptionIntoGen(yieldThrowsCaughtInGenerator)');
},
]);

View File

@ -0,0 +1,91 @@
Break on exceptions from compiler errors.
Running test: testUnexpectedEndOfInput
Runs '+++'
Runtime.evaluate exceptionDetails:
{
columnNumber : 3
exception : {
className : SyntaxError
description : SyntaxError: Unexpected end of input
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
Running test: testUnexpectedIdentifier
Runs 'x x'
Runtime.evaluate exceptionDetails:
{
columnNumber : 2
exception : {
className : SyntaxError
description : SyntaxError: Unexpected identifier 'x'
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
Running test: testEvalUnexpectedEndOfInput
Runs eval('+++')
paused on exception:
{
className : SyntaxError
description : SyntaxError: Unexpected end of input at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
uncaught : false
}
Runtime.evaluate exceptionDetails:
{
columnNumber : 3
exception : {
className : SyntaxError
description : SyntaxError: Unexpected end of input at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
Running test: testEvalUnexpectedIdentifier
Runs eval('x x')
paused on exception:
{
className : SyntaxError
description : SyntaxError: Unexpected identifier 'x' at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
uncaught : false
}
Runtime.evaluate exceptionDetails:
{
columnNumber : 2
exception : {
className : SyntaxError
description : SyntaxError: Unexpected identifier 'x' at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}

View File

@ -0,0 +1,52 @@
// Copyright 2018 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Break on exceptions from compiler errors.');
Protocol.Debugger.enable();
Protocol.Debugger.setPauseOnExceptions({state: 'all'});
Protocol.Debugger.onPaused(({params:{data}}) => {
InspectorTest.log('paused on exception:');
InspectorTest.logMessage(data);
Protocol.Debugger.resume();
});
InspectorTest.runAsyncTestSuite([
async function testUnexpectedEndOfInput() {
InspectorTest.log(`Runs '+++'`);
let {result:{exceptionDetails}} = await Protocol.Runtime.evaluate({
expression: '+++'
});
InspectorTest.log('Runtime.evaluate exceptionDetails:');
InspectorTest.logMessage(exceptionDetails);
},
async function testUnexpectedIdentifier() {
InspectorTest.log(`Runs 'x x'`);
let {result:{exceptionDetails}} = await Protocol.Runtime.evaluate({
expression: 'x x'
});
InspectorTest.log('Runtime.evaluate exceptionDetails:');
InspectorTest.logMessage(exceptionDetails);
},
async function testEvalUnexpectedEndOfInput() {
InspectorTest.log(`Runs eval('+++')`);
let {result:{exceptionDetails}} = await Protocol.Runtime.evaluate({
expression: `eval('+++')`
});
InspectorTest.log('Runtime.evaluate exceptionDetails:');
InspectorTest.logMessage(exceptionDetails);
},
async function testEvalUnexpectedIdentifier() {
InspectorTest.log(`Runs eval('x x')`);
let {result:{exceptionDetails}} = await Protocol.Runtime.evaluate({
expression: `eval('x x')`
});
InspectorTest.log('Runtime.evaluate exceptionDetails:');
InspectorTest.logMessage(exceptionDetails);
}
]);

View File

@ -0,0 +1,175 @@
Tests for break on exception.
Running test: testPauseOnInitialState
evaluate 'caught()'..
evaluate 'uncaught()'..
evaluate 'uncaughtFinally()'..
evaluate 'caughtFinally()'..
Running test: testPauseOnExceptionOff
evaluate 'caught()'..
evaluate 'uncaught()'..
evaluate 'uncaughtFinally()'..
evaluate 'caughtFinally()'..
Running test: testBreakOnCaughtException
evaluate 'caught()'..
paused on exception:
{
description : 1
type : number
uncaught : false
value : 1
}
evaluate 'uncaught()'..
evaluate 'uncaughtFinally()'..
evaluate 'caughtFinally()'..
Running test: testBreakOnUncaughtException
evaluate 'caught()'..
evaluate 'uncaught()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'uncaughtFinally()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'caughtFinally()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
Running test: testBreakOnAll
evaluate 'caught()'..
paused on exception:
{
description : 1
type : number
uncaught : false
value : 1
}
evaluate 'uncaught()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'uncaughtFinally()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'caughtFinally()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
Running test: testTryFinallyOriginalMessage
evaluate '
try {
throw 1;
} finally {
}
'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
Running test: testPromiseRejectedByCallback
evaluate '
function fun() { eval("throw 'rejection';") }
var p = new Promise(function(res, rej) { fun(); res(); });
var r;
p.then(() => { r = 'resolved'; }, (e) => { r = 'rejected' + e; });
'..
paused on exception:
{
type : string
uncaught : true
value : rejection
}
r =
{
type : string
value : rejectedrejection
}
Running test: testBreakOnExceptionAfterReconnect
evaluate 'f()'..
paused on exception:
{
className : Error
description : Error at f (<anonymous>:115:153) at <anonymous>:146:163
objectId : <objectId>
subtype : error
type : object
uncaught : true
}
reconnect..
evaluate 'f()'..
paused on exception:
{
className : Error
description : Error at f (<anonymous>:115:153) at <anonymous>:146:163
objectId : <objectId>
subtype : error
type : object
uncaught : true
}
Running test: testBreakOnExceptionInSilentMode
evaluate 'caught()'
evaluate 'uncaught()'
evaluate 'uncaughtFinally()'
evaluate 'caughtFinally()'

View File

@ -0,0 +1,191 @@
Checks if catch prediction works on new `using` and `await using` syntax.
Running test: testPauseOnInitialState
evaluate 'disposalUncaughtUsingSyntax()'..
evaluate 'disposalUncaughtAwaitUsingSyntax()'..
evaluate 'disposalUncaughtSuppressedError()'..
evaluate 'disposalCaughtUsingSyntax()'..
evaluate 'disposalCaughtAwaitUsingSyntax()'..
evaluate 'disposalCaughtSuppressedError()'..
Running test: testPauseOnExceptionOff
evaluate 'disposalUncaughtUsingSyntax()'..
evaluate 'disposalUncaughtAwaitUsingSyntax()'..
evaluate 'disposalUncaughtSuppressedError()'..
evaluate 'disposalCaughtUsingSyntax()'..
evaluate 'disposalCaughtAwaitUsingSyntax()'..
evaluate 'disposalCaughtSuppressedError()'..
Running test: testBreakOnCaughtException
evaluate 'disposalUncaughtUsingSyntax()'..
evaluate 'disposalUncaughtAwaitUsingSyntax()'..
evaluate 'disposalUncaughtSuppressedError()'..
evaluate 'disposalCaughtUsingSyntax()'..
paused on exception:
{
description : 5
type : number
uncaught : false
value : 5
}
evaluate 'disposalCaughtAwaitUsingSyntax()'..
paused on exception:
{
description : 6
type : number
uncaught : false
value : 6
}
evaluate 'disposalCaughtSuppressedError()'..
paused on exception:
{
description : 8
type : number
uncaught : false
value : 8
}
paused on exception:
{
description : 7
type : number
uncaught : false
value : 7
}
Running test: testBreakOnUncaughtException
evaluate 'disposalUncaughtUsingSyntax()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'disposalUncaughtAwaitUsingSyntax()'..
paused on exception:
{
description : 2
type : number
uncaught : true
value : 2
}
evaluate 'disposalUncaughtSuppressedError()'..
paused on exception:
{
description : 4
type : number
uncaught : true
value : 4
}
paused on exception:
{
description : 3
type : number
uncaught : true
value : 3
}
evaluate 'disposalCaughtUsingSyntax()'..
evaluate 'disposalCaughtAwaitUsingSyntax()'..
evaluate 'disposalCaughtSuppressedError()'..
Running test: testBreakOnAll
evaluate 'disposalUncaughtUsingSyntax()'..
paused on exception:
{
description : 1
type : number
uncaught : true
value : 1
}
evaluate 'disposalUncaughtAwaitUsingSyntax()'..
paused on exception:
{
description : 2
type : number
uncaught : true
value : 2
}
evaluate 'disposalUncaughtSuppressedError()'..
paused on exception:
{
description : 4
type : number
uncaught : true
value : 4
}
paused on exception:
{
description : 3
type : number
uncaught : true
value : 3
}
evaluate 'disposalCaughtUsingSyntax()'..
paused on exception:
{
description : 5
type : number
uncaught : false
value : 5
}
evaluate 'disposalCaughtAwaitUsingSyntax()'..
paused on exception:
{
description : 6
type : number
uncaught : false
value : 6
}
evaluate 'disposalCaughtSuppressedError()'..
paused on exception:
{
description : 8
type : number
uncaught : false
value : 8
}
paused on exception:
{
description : 7
type : number
uncaught : false
value : 7
}
Running test: testBreakOnExceptionInSilentMode
evaluate 'disposalUncaughtUsingSyntax()'
evaluate 'disposalUncaughtAwaitUsingSyntax()'
evaluate 'disposalUncaughtSuppressedError()'
evaluate 'disposalCaughtUsingSyntax()'
evaluate 'disposalCaughtAwaitUsingSyntax()'
evaluate 'disposalCaughtSuppressedError()'

View File

@ -0,0 +1,178 @@
// Copyright 2024 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.
// Flags: --js-staging
let {session, contextGroup, Protocol} = InspectorTest.start(
'Checks if catch prediction works on new `using` and `await using` syntax.');
Protocol.Debugger.enable();
Protocol.Debugger.onPaused(({params: {data}}) => {
InspectorTest.log('paused on exception:');
InspectorTest.logMessage(data);
Protocol.Debugger.resume();
});
contextGroup.addInlineScript(
`
function disposalUncaughtUsingSyntax() {
using x = {
value: 1,
[Symbol.dispose]() {
throw 1;
}
};
}
async function disposalUncaughtAwaitUsingSyntax() {
await using y = {
value: 2,
[Symbol.asyncDispose]() {
throw 2;
}
};
}
function disposalUncaughtSuppressedError() {
using x = {
value: 1,
[Symbol.dispose]() {
throw 3;
}
};
using y = {
value: 2,
[Symbol.dispose]() {
throw 4;
}
};
}
function disposalCaughtUsingSyntax() {
try {
using x = {
value: 1,
[Symbol.dispose]() {
throw 5;
}
};
} catch (e) {
}
}
async function disposalCaughtAwaitUsingSyntax() {
try {
await using y = {
value: 2,
[Symbol.asyncDispose]() {
throw 6;
}
};
} catch (e) {
}
}
function disposalCaughtSuppressedError() {
try {
using x = {
value: 1,
[Symbol.dispose]() {
throw 7;
}
};
using y = {
value: 2,
[Symbol.dispose]() {
throw 8;
}
};
} catch (e) {
}
}
`,
'test.js');
InspectorTest.runAsyncTestSuite([
async function testPauseOnInitialState() {
await evaluate('disposalUncaughtUsingSyntax()');
await evaluate('disposalUncaughtAwaitUsingSyntax()');
await evaluate('disposalUncaughtSuppressedError()');
await evaluate('disposalCaughtUsingSyntax()');
await evaluate('disposalCaughtAwaitUsingSyntax()');
await evaluate('disposalCaughtSuppressedError()');
},
async function testPauseOnExceptionOff() {
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
await evaluate('disposalUncaughtUsingSyntax()');
await evaluate('disposalUncaughtAwaitUsingSyntax()');
await evaluate('disposalUncaughtSuppressedError()');
await evaluate('disposalCaughtUsingSyntax()');
await evaluate('disposalCaughtAwaitUsingSyntax()');
await evaluate('disposalCaughtSuppressedError()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnCaughtException() {
await Protocol.Debugger.setPauseOnExceptions({state: 'caught'});
await evaluate('disposalUncaughtUsingSyntax()');
await evaluate('disposalUncaughtAwaitUsingSyntax()');
await evaluate('disposalUncaughtSuppressedError()');
await evaluate('disposalCaughtUsingSyntax()');
await evaluate('disposalCaughtAwaitUsingSyntax()');
await evaluate('disposalCaughtSuppressedError()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnUncaughtException() {
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
await evaluate('disposalUncaughtUsingSyntax()');
await evaluate('disposalUncaughtAwaitUsingSyntax()');
await evaluate('disposalUncaughtSuppressedError()');
await evaluate('disposalCaughtUsingSyntax()');
await evaluate('disposalCaughtAwaitUsingSyntax()');
await evaluate('disposalCaughtSuppressedError()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnAll() {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
await evaluate('disposalUncaughtUsingSyntax()');
await evaluate('disposalUncaughtAwaitUsingSyntax()');
await evaluate('disposalUncaughtSuppressedError()');
await evaluate('disposalCaughtUsingSyntax()');
await evaluate('disposalCaughtAwaitUsingSyntax()');
await evaluate('disposalCaughtSuppressedError()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnExceptionInSilentMode(next) {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
InspectorTest.log(`evaluate 'disposalUncaughtUsingSyntax()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalUncaughtUsingSyntax()', silent: true});
InspectorTest.log(`evaluate 'disposalUncaughtAwaitUsingSyntax()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalUncaughtAwaitUsingSyntax()', silent: true});
InspectorTest.log(`evaluate 'disposalUncaughtSuppressedError()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalUncaughtSuppressedError()', silent: true});
InspectorTest.log(`evaluate 'disposalCaughtUsingSyntax()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalCaughtUsingSyntax()', silent: true});
InspectorTest.log(`evaluate 'disposalCaughtAwaitUsingSyntax()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalCaughtAwaitUsingSyntax()', silent: true});
InspectorTest.log(`evaluate 'disposalCaughtSuppressedError()'`);
await Protocol.Runtime.evaluate(
{expression: 'disposalCaughtSuppressedError()', silent: true});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
}
]);
async function evaluate(expression) {
InspectorTest.log(`\nevaluate '${expression}'..`);
contextGroup.addInlineScript(expression);
await InspectorTest.waitForPendingTasks();
}

View File

@ -0,0 +1,481 @@
Checks that exceptions in framework code have correct stopping behavior.
Running test: testCase
> Running scenario throwUncaughtError, breaking on caught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario throwUncaughtError, breaking on uncaught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario throwCaughtError, breaking on caught exceptions:
console: Caught at Error
at throwCaughtError (framework.js:16:11)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario throwCaughtError, breaking on uncaught exceptions:
console: Caught at Error
at throwCaughtError (framework.js:16:11)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario catchErrorInFramework, breaking on caught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at wrapErrorHandler (framework.js:42:5)
at catchErrorInFramework (framework.js:23:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario catchErrorInFramework, breaking on uncaught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at wrapErrorHandler (framework.js:42:5)
at catchErrorInFramework (framework.js:23:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario frameworkFinallyMethod, breaking on caught exceptions:
console: finally in framework code
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
frameworkFinallyMethod (framework.js:26:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Exception revoked for reason: Handler added to rejected promise
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
frameworkFinallyMethod (framework.js:26:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario frameworkFinallyMethod, breaking on uncaught exceptions:
console: finally in framework code
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
frameworkFinallyMethod (framework.js:26:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Exception revoked for reason: Handler added to rejected promise
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
frameworkFinallyMethod (framework.js:26:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario catchErrorInUserCode, breaking on caught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
catchErrorInUserCode (user.js:70:4)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at catchErrorInUserCode (user.js:71:5)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario catchErrorInUserCode, breaking on uncaught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at catchErrorInUserCode (user.js:71:5)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario passErrorThroughUserCode, breaking on caught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
passErrorThroughUserCode (user.js:77:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario passErrorThroughUserCode, breaking on uncaught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
passErrorThroughUserCode (user.js:77:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
passErrorThroughUserCode (user.js:77:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario notAffectingUserCode, breaking on caught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at wrapErrorHandler (framework.js:42:5)
at catchErrorInFramework (framework.js:23:3)
at notAffectingUserCode (user.js:82:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario notAffectingUserCode, breaking on uncaught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at wrapErrorHandler (framework.js:42:5)
at catchErrorInFramework (framework.js:23:3)
at notAffectingUserCode (user.js:82:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario uncaughtWithAsyncUserCode, breaking on caught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
uncaughtWithAsyncUserCode (user.js:85:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario uncaughtWithAsyncUserCode, breaking on uncaught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
uncaughtAsync (framework.js:32:2)
-- await --
uncaughtWithAsyncUserCode (user.js:85:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
uncaughtWithAsyncUserCode (user.js:85:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario uncaughtWithAsyncUserCodeAndDelay, breaking on caught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario uncaughtWithAsyncUserCodeAndDelay, breaking on uncaught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario uncaughtWithAsyncUserCodeMissingAwait, breaking on caught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
uncaughtWithAsyncUserCodeMissingAwait (user.js:94:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
uncaughtWithAsyncUserCodeMissingAwait (user.js:94:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario uncaughtWithAsyncUserCodeMissingAwait, breaking on uncaught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtWithAsyncUserCodeAndDelay (user.js:90:2)
-- await --
uncaughtWithAsyncUserCodeMissingAwait (user.js:94:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario catchPassingThroughUserCode, breaking on caught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
passErrorThroughUserCode (user.js:77:2)
wrapErrorHandler (framework.js:41:4)
catchPassingThroughUserCode (user.js:98:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at passErrorThroughUserCode (user.js:78:3)
at wrapErrorHandler (framework.js:42:5)
at catchPassingThroughUserCode (user.js:99:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario catchPassingThroughUserCode, breaking on uncaught exceptions:
console: Caught at Error
at throwUncaughtError (framework.js:11:9)
at passErrorThroughUserCode (user.js:78:3)
at wrapErrorHandler (framework.js:42:5)
at catchPassingThroughUserCode (user.js:99:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario userException, breaking on caught exceptions:
Uncaught exception: Uncaught Error
-- <empty> --
userException (user.js:102:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario userException, breaking on uncaught exceptions:
Paused
userException (user.js:102:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Uncaught exception: Uncaught Error
-- <empty> --
userException (user.js:102:8)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario catchUserException, breaking on caught exceptions:
Paused
userException (user.js:102:2)
wrapErrorHandler (framework.js:41:4)
catchUserException (user.js:106:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
console: Caught at Error
at userException (user.js:103:9)
at wrapErrorHandler (framework.js:42:5)
at catchUserException (user.js:107:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario catchUserException, breaking on uncaught exceptions:
console: Caught at Error
at userException (user.js:103:9)
at wrapErrorHandler (framework.js:42:5)
at catchUserException (user.js:107:3)
at runWithResolution (framework.js:54:13)
console: finished without error
Running test: testCase
> Running scenario nowhereToStop, breaking on caught exceptions:
console: finished without error
Uncaught exception: Uncaught SyntaxError: Unexpected token 'p', "ping" is not valid JSON
-- <empty> --
-- setTimeout --
nowhereToStop (user.js:110:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario nowhereToStop, breaking on uncaught exceptions:
console: finished without error
Uncaught exception: Uncaught SyntaxError: Unexpected token 'p', "ping" is not valid JSON
-- <empty> --
-- setTimeout --
nowhereToStop (user.js:110:2)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario userFinallyMethod, breaking on caught exceptions:
console: finally in user code
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
userFinallyMethod (user.js:114:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Exception revoked for reason: Handler added to rejected promise
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
userFinallyMethod (user.js:114:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Running test: testCase
> Running scenario userFinallyMethod, breaking on uncaught exceptions:
Paused
throwUncaughtError (framework.js:10:2)
uncaughtAsync (framework.js:32:2)
-- await --
userFinallyMethod (user.js:114:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
console: finally in user code
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
userFinallyMethod (user.js:114:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)
Exception revoked for reason: Handler added to rejected promise
Uncaught exception: Uncaught Error
-- <empty> --
throwUncaughtError (framework.js:10:8)
uncaughtAsync (framework.js:32:2)
-- await --
userFinallyMethod (user.js:114:9)
runWithResolution (framework.js:53:12)
-- setTimeout --
(anonymous) (framework.js:62:31)
testWrapper (framework.js:62:8)
(anonymous) (test_framework.js:0:0)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,156 @@
// Copyright 2023 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that exceptions in framework code have correct stopping behavior.');
// framework.js
async function frameworkUncaught() {
await complicatedThrow(false);
}
async function frameworkCaught() {
await complicatedThrow(true);
}
async function uncaughtAsync() {
await delay();
throw new Error('Failed');
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function branchPromise(func, branchCatches) {
const newPromise = func().then(()=>console.log('Will not print'));
if (branchCatches) {
newPromise.catch((e)=>console.error('Caught at ' + e.stack));
} else {
newPromise.then(()=>console.log('Also will not print'));
}
return newPromise;
}
async function frameworkAsync(func) {
await func();
}
function complicatedThrow(catches) {
return frameworkAsync(branchPromise.bind(null, frameworkAsync.bind(null, branchPromise.bind(null, uncaughtAsync, false)), catches));
}
async function testWrapper(testFunc) {
// testWrapper runs testFunc and completes successfully when testFunc
// completes, but does so in a setTimeout so that it doesn't catch any
// exceptions thrown by testFunc.
async function runWithResolution(resolve) {
try {
await testFunc();
console.log('finished without error');
} finally {
// Leave exceptions uncaught, but the testWrapper continues normally
// anyway. Needs to be in a setTimeout so that uncaught exceptions
// are handled before the test is complete.
setTimeout(resolve, 0);
}
}
await new Promise(resolve => setTimeout(runWithResolution.bind(null, resolve), 0));
}
// user.js
async function caughtInUser() {
try {
await complicatedThrow(false);
} catch (e) {
console.log('Caught in user code at ' + e.stack);
}
}
async function caughtInUserAndFramework() {
try {
await complicatedThrow(true);
} catch (e) {
console.log('Caught in user code at ' + e.stack);
}
}
async function uncaughtInUser() {
await complicatedThrow(false);
}
async function uncaughtInUserCaughtInFramework() {
await complicatedThrow(true);
}
function branchInUser() {
const p = complicatedThrow(false);
p.catch((e)=>console.error('Caught in user code at ' + e.stack));
return p;
}
// -------------------------------------
// Order of functions should match above so that line numbers match
const files = [
{
name: 'framework.js',
scenarios: [frameworkUncaught, frameworkCaught],
helpers: [uncaughtAsync, delay, branchPromise, frameworkAsync, complicatedThrow, testWrapper],
startLine: 9,
}, {
name: 'user.js',
scenarios: [caughtInUser, caughtInUserAndFramework, uncaughtInUser, uncaughtInUserCaughtInFramework, branchInUser],
helpers: [],
startLine: 64,
}
];
const allScenarios = [];
for (const {name, scenarios, helpers, startLine} of files) {
allScenarios.push(...scenarios);
const file = [...scenarios, ...helpers].join('\n\n');
contextGroup.addScript(file, startLine, 0, name);
}
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
InspectorTest.log('Paused');
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Console.onMessageAdded(event => InspectorTest.log('console: ' + event.params.message.text));
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 6});
Protocol.Console.enable();
Protocol.Runtime.onExceptionRevoked(event => InspectorTest.log('Exception revoked for reason: ' + event.params.reason));
Protocol.Runtime.onExceptionThrown(event => {
InspectorTest.log(`Uncaught exception: ${event.params.exceptionDetails.text}`);
session.logAsyncStackTrace(event.params.exceptionDetails.stackTrace);
});
Protocol.Runtime.enable();
const testFunctions = [];
for (const scenario of allScenarios) {
for (const state of ['caught', 'uncaught']) {
for (const ignoreList of [true, false]) {
const patterns = ignoreList ? ['framework\.js'] : [];
testFunctions.push(async function testCase() {
InspectorTest.log(`> Running scenario ${scenario.name}, breaking on ${state} exceptions, ignore listing ${ignoreList ? 'on' : 'off'}:`);
await Protocol.Debugger.setPauseOnExceptions({state});
await Protocol.Debugger.setBlackboxPatterns({patterns});
await Protocol.Runtime.evaluate({expression: `testWrapper(${scenario.name})//# sourceURL=test_framework.js`, awaitPromise: true});
});
}
}
}
InspectorTest.runAsyncTestSuite(testFunctions);

View File

@ -0,0 +1,199 @@
// Copyright 2023 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that exceptions in framework code have correct stopping behavior.');
// framework.js
function throwUncaughtError() {
throw new Error();
}
function throwCaughtError() {
try {
throw new Error();
} catch (e) {
console.log('Caught at ' + e.stack);
}
}
function catchErrorInFramework() {
wrapErrorHandler(throwUncaughtError);
}
function frameworkFinallyMethod() {
return uncaughtAsync().finally(
() => console.log('finally in framework code'));
}
async function uncaughtAsync() {
await delay();
throwUncaughtError();
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 0));
}
function wrapErrorHandler(errorFunc) {
try {
errorFunc();
} catch (e) {
console.log('Caught at ' + e.stack);
}
}
async function testWrapper(testFunc) {
// testWrapper runs testFunc and completes successfully when testFunc
// completes, but does so in a setTimeout so that it doesn't catch any
// exceptions thrown by testFunc.
async function runWithResolution(resolve) {
try {
await testFunc();
console.log('finished without error');
} finally {
// Leave exceptions uncaught, but the testWrapper continues normally
// anyway. Needs to be in a setTimeout so that uncaught exceptions
// are handled before the test is complete.
setTimeout(resolve, 0);
}
}
await new Promise(resolve => setTimeout(runWithResolution.bind(null, resolve),
0));
}
// user.js
function catchErrorInUserCode() {
try {
throwUncaughtError();
} catch (e) {
console.log('Caught at ' + e.stack);
}
}
function passErrorThroughUserCode() {
throwUncaughtError();
}
function notAffectingUserCode() {
catchErrorInFramework();
}
async function uncaughtWithAsyncUserCode() {
await uncaughtAsync();
}
async function uncaughtWithAsyncUserCodeAndDelay() {
await delay();
throwUncaughtError();
}
async function uncaughtWithAsyncUserCodeMissingAwait() {
return uncaughtWithAsyncUserCodeAndDelay();
}
function catchPassingThroughUserCode() {
wrapErrorHandler(passErrorThroughUserCode);
}
function userException() {
throw new Error();
}
function catchUserException() {
wrapErrorHandler(userException);
}
function nowhereToStop() {
setTimeout(JSON.parse.bind(null, 'ping'), 0);
}
function userFinallyMethod() {
return uncaughtAsync().finally(() => console.log('finally in user code'));
}
// -------------------------------------
// Order of functions should match above so that line numbers match
const files = [
{
name: 'framework.js',
scenarios: [
throwUncaughtError,
throwCaughtError,
catchErrorInFramework,
frameworkFinallyMethod
],
helpers: [uncaughtAsync, delay, wrapErrorHandler, testWrapper],
startLine: 9,
}, {
name: 'user.js',
scenarios: [
catchErrorInUserCode,
passErrorThroughUserCode,
notAffectingUserCode,
uncaughtWithAsyncUserCode,
uncaughtWithAsyncUserCodeAndDelay,
uncaughtWithAsyncUserCodeMissingAwait,
catchPassingThroughUserCode,
userException,
catchUserException,
nowhereToStop,
userFinallyMethod
],
helpers: [],
startLine: 68,
}
];
const allScenarios = [];
for (const {name, scenarios, helpers, startLine} of files) {
allScenarios.push(...scenarios);
const file = [...scenarios, ...helpers].join('\n\n');
contextGroup.addScript(file, startLine, 0, name);
}
session.setupScriptMap();
Protocol.Debugger.onPaused(message => {
InspectorTest.log('Paused');
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
Protocol.Debugger.resume();
});
Protocol.Console.onMessageAdded(
event => InspectorTest.log('console: ' + event.params.message.text));
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 6});
Protocol.Console.enable();
Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
Protocol.Runtime.onExceptionRevoked(event => InspectorTest.log(
'Exception revoked for reason: ' + event.params.reason));
Protocol.Runtime.onExceptionThrown(event => {
InspectorTest.log(
`Uncaught exception: ${event.params.exceptionDetails.text}`);
session.logAsyncStackTrace(event.params.exceptionDetails.stackTrace);
});
Protocol.Runtime.enable();
const testFunctions = [];
for (const scenario of allScenarios) {
for (const state of ['caught', 'uncaught']) {
testFunctions.push(async function testCase() {
InspectorTest.log(`> Running scenario ${scenario.name}, breaking on ${state} exceptions:`);
await Protocol.Debugger.setPauseOnExceptions({state});
await Protocol.Runtime.evaluate({
expression: `testWrapper(${scenario.name})//# sourceURL=test_framework.js`,
awaitPromise: true
});
});
}
}
InspectorTest.runAsyncTestSuite(testFunctions);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,633 @@
// Copyright 2023 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.
// Flags: --js-staging
let {session, contextGroup, Protocol} = InspectorTest.start('Checks when promise rejections are predicted to be caught.');
// catch-prediction.js
function rejectAfterDelayInPromiseConstructor() {
return new Promise((pass, reject) => setTimeout(() => reject(new Error('fail')), 0));
}
function promiseReject() {
return Promise.reject(new Error('fail'));
}
function throwInPromiseConstructor() {
return new Promise(() => {throw new Error('fail');});
}
function rejectInPromiseConstructor() {
return new Promise((pass, reject) => {
reject(new Error('fail'));
console.log('after reject');
});
}
function rejectAfterDelayInTryInPromiseConstructor() {
return new Promise((pass, reject) => setTimeout(() => {
try {
reject(new Error('fail'));
} catch(e) {
console.log('fake'); // Won't be hit
}
}, 0));
}
function rejectBindAfterDelay() {
// Unbreakable location because there will be nothing on the callstack
return new Promise((pass, reject) => setTimeout(reject.bind(null, new Error('fail')), 0));
}
function throwInPromiseTryCallback() {
return Promise.try(() => { throw new Error('fail'); });
}
async function throwFromAsync() {
throw new Error('fail');
}
async function throwFromAsyncAfterDelay() {
await delay();
throw new Error('fail');
}
function customRejectingThenable() {
// JS supports awaiting on user defined promise-like objects
return {
then(onFulfilled, onRejected) {
onRejected(new Error('fail'));
}
}
}
function customRejectingThenableAfterDelay() {
// JS supports awaiting on user defined promise-like objects
return {
then(onFulfilled, onRejected) {
setTimeout(() => onRejected(new Error('fail')), 0);
}
}
}
function exceptionInThen() {
return Promise.resolve().then(() => {throw new Error('fail');});
}
function exceptionInCatch() {
return Promise.reject(new Error('will catch')).catch(() => {
console.log('throwing again');
throw new Error('fail');
});
}
async function exceptionInAsyncGenerator() {
async function* gen() {
yield 1;
throw new Error('fail');
}
for await(const x of gen()) {}
}
async function rejectInGenerator() {
function* gen() {
yield promiseReject();
}
for await(const x of gen()) {}
}
async function rejectAfterDelayInGenerator() {
function* gen() {
yield rejectAfterDelayInPromiseConstructor();
}
for await(const x of gen()) {}
}
async function rejectInAsyncGenerator() {
async function* gen() {
yield promiseReject();
}
for await(const x of gen()) {}
}
async function rejectAfterDelayInAsyncGenerator() {
async function* gen() {
yield rejectAfterDelayInPromiseConstructor();
}
for await(const x of gen()) {}
}
async function asyncGeneratorThrowMethod() {
async function* gen() {
yield 1;
}
const g = gen();
await g.next();
await g.throw(new Error('fail'));
}
async function asyncCatchingGeneratorThrowMethod() {
async function* gen() {
try {
yield 1;
} catch (e) {
console.log('caught by generator');
}
}
const g = gen();
await g.next();
await g.throw(new Error('fail'));
}
async function throwInAsyncGenerator() {
async function* gen() {
yield 1;
throw new Error('fail');
}
for await(const x of gen()) {}
}
function promiseRejectInTry() {
// A synchronous try can't catch a promise rejection.
try {
return Promise.reject(new Error('fail'));
} catch (e) {
console.log('fake'); // Will not catch
}
}
function rejectAfterFulfillInPromiseConstructor() {
return new Promise((pass, reject) => {
pass('ok');
console.log('after pass');
reject(new Error('fail'));
console.log('after reject');
});
}
function rejectAfterDelayAfterFulfillInPromiseConstructor() {
return new Promise((pass, reject) => {
pass('ok');
setTimeout(() => reject(new Error('fail')), 0);
});
}
function throwAfterFulfillInPromiseConstructor() {
return new Promise((pass, reject) => {
pass('ok');
console.log('after pass');
throw new Error('fail');
});
}
async function throwInAsyncDisposeFormSync() {
await using x = {
value: 1,
[Symbol.dispose]() {
throw new Error('fail');
}
};
}
async function dontHandleAsync(fn) {
// Unhandled exception that is trivial to predict,
// for comparison.
await fn();
}
async function awaitAndCreateInTry(fn) {
try {
// The easy case to get right, for comparison.
await fn();
} catch(e) {
console.log('caught');
}
}
function catchMethod(fn) {
// Catch handler may not be attached at the time promise is rejected
fn().catch((e) => console.log('caught'));
}
function finallyMethod(fn) {
// Is a finally handler considered caught?
fn().finally(() => console.log('finally handler'));
}
function catchMethodInTry(fn) {
try {
fn().catch((e) => console.log('caught'));
} catch(e) {
console.log('fake'); // Won't be hit
}
}
async function awaitInTry(fn) {
// No handler when promise is created, but there is when it is awaited
const promise = fn();
try {
await promise;
} catch(e) {
console.log('caught');
}
}
async function awaitAndCreateInTryFinally(fn) {
try {
await fn();
} finally {
// Is finally handler treated as a catch?
console.log('finally handler');
}
}
async function createInTry(fn) {
let promise = null;
// In this test case we don't handle the exception,
// but first we try to convince JS we will.
try {
promise = fn();
} catch(e) {
console.log('fake'); // Won't be hit
}
if(promise) {
await promise;
}
}
function fireAndForgetInTry(fn) {
try {
// Unhandled exception, but will we mispredict as caught?
fn();
} catch(e) {
console.log('fake'); // Won't be hit
}
}
function finallyAndCatchMethod(fn) {
// Will we account for the catch method after the finally?
fn().finally(() => console.log('finally handler'))
.catch(() => console.log('caught'));
}
function thenMethod(fn) {
fn().then(() => console.log('not hit'));
}
function thenMethodWithTwoArgs(fn) {
fn().then(() => console.log('not hit'), () => console.log('caught'));
}
async function caughtPromiseRace(fn) {
try {
await Promise.race([fn()]);
} catch(e) {
console.log('caught');
}
}
async function caughtInTryPromiseRace(fn) {
const promise = fn();
try {
await Promise.race([promise]);
} catch(e) {
console.log('caught');
}
}
async function uncaughtPromiseRace(fn) {
await Promise.race([fn()]);
}
async function ignoredPromiseRace(fn) {
// Race will resolve to first promise, preventing exception from second
// from propagating. Is this caught or uncaught?
await Promise.race([Promise.resolve(), fn()]);
}
async function ignoredPromiseRaceInTry(fn) {
try {
// Race will resolve to first promise, preventing exception from second
// from propagating. Is this caught or uncaught?
await Promise.race([Promise.resolve(), fn()]);
} catch(e) {
console.log('caught');
}
}
async function caughtPromiseAll(fn) {
try {
await Promise.all([fn()]);
} catch(e) {
console.log('caught');
}
}
async function uncaughtPromiseAll(fn) {
await Promise.all([fn()]);
}
async function caughtPromiseAny(fn) {
try {
await Promise.any([fn()]);
} catch(e) {
console.log('caught');
}
}
async function uncaughtPromiseAny(fn) {
await Promise.any([fn()]);
}
async function ignoredPromiseAny(fn) {
// Any will resolve to first promise, preventing exception from second
// from propagating. Is this caught or uncaught?
await Promise.any([Promise.resolve(), fn()]);
}
async function ignoredPromiseAnyInTry(fn) {
try {
// Any will resolve to first promise, preventing exception from second
// from propagating. Is this caught or uncaught?
await Promise.any([Promise.resolve(), fn()]);
} catch(e) {
console.log('caught');
}
}
async function ignoredPromiseAnyWithIndirection(fn) {
// Similar to other ignored cases but we have to walk the promise tree to
// find the already fulfilled promise.
async function indirectThrow() {
await fn();
}
async function indirectAny() {
await Promise.any([Promise.resolve(), indirectThrow()]);
}
await indirectAny();
}
async function ignoredPromiseAnyWithIndirectionInTry(fn) {
async function indirectThrow() {
await fn();
}
try {
// Similar to other ignored cases but we have to walk the promise tree to
// find the already fulfilled promise.
await Promise.any([Promise.resolve(), indirectThrow()]);
} catch(e) {
console.log('caught');
}
}
async function awaitAfterDelayInTry(fn) {
try {
// Predicts correctly if thrown immediately but if not no handler will
// be attached when it throws.
const promise = fn();
console.log('sleeping');
await delay();
await delay();
console.log('awaiting');
await promise;
} catch(e) {
console.log('caught');
}
}
async function catchInAsyncGenerator(fn) {
async function* gen() {
try {
yield fn();
} catch (e) {
console.log('caught');
}
}
for await(const x of gen()) {}
}
async function catchInGenerator(fn) {
function* gen() {
try {
yield fn();
} catch (e) {
console.log('fake'); // Will not catch
}
}
for await(const x of gen()) {}
}
async function catchAndAlsoDont(fn) {
const uncaughtPromise = fn();
const caughtPromise = uncaughtPromise.catch(() => console.log('caught'));
await uncaughtPromise;
console.log('never reached');
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 0));
}
async function testWrapper(throwFunc, handleFunc) {
// testWrapper runs testFunc and completes successfully when testFunc
// completes, but does so in a setTimeout so that it doesn't catch any
// exceptions thrown by testFunc.
async function runWithResolution(resolve) {
try {
const promise = handleFunc(throwFunc);
console.log('awaiting promise');
await promise;
console.log('finished without error');
} finally {
// Leave exceptions uncaught, but the testWrapper continues normally
// anyway. Needs to be in a setTimeout so that uncaught exceptions
// are handled before the test is complete.
setTimeout(resolve, 0);
}
}
await new Promise(resolve => setTimeout(runWithResolution.bind(null, resolve), 0));
}
// -------------------------------------
// Order of functions should match above so that line numbers match
const basicThrowFunctions = [rejectAfterDelayInPromiseConstructor, promiseReject];
const advancedThrowFunctions = [
throwInPromiseConstructor,
rejectInPromiseConstructor,
rejectAfterDelayInTryInPromiseConstructor,
rejectBindAfterDelay,
throwFromAsync,
throwFromAsyncAfterDelay,
customRejectingThenable,
customRejectingThenableAfterDelay,
exceptionInThen,
exceptionInCatch,
exceptionInAsyncGenerator,
rejectInGenerator,
rejectAfterDelayInGenerator,
rejectInAsyncGenerator,
rejectAfterDelayInAsyncGenerator,
asyncGeneratorThrowMethod,
asyncCatchingGeneratorThrowMethod,
throwInAsyncGenerator,
promiseRejectInTry,
rejectAfterFulfillInPromiseConstructor,
rejectAfterDelayAfterFulfillInPromiseConstructor,
throwAfterFulfillInPromiseConstructor,
throwInPromiseTryCallback,
throwInAsyncDisposeFormSync
];
const basicCatchFunctions = [dontHandleAsync, awaitAndCreateInTry];
const advancedCatchFunctions = [
catchMethod,
finallyMethod,
catchMethodInTry,
awaitInTry,
awaitAndCreateInTryFinally,
createInTry,
fireAndForgetInTry,
finallyAndCatchMethod,
thenMethod,
thenMethodWithTwoArgs,
caughtPromiseRace,
caughtInTryPromiseRace,
uncaughtPromiseRace,
ignoredPromiseRace,
ignoredPromiseRaceInTry,
caughtPromiseAll,
uncaughtPromiseAll,
caughtPromiseAny,
uncaughtPromiseAny,
ignoredPromiseAny,
ignoredPromiseAnyInTry,
ignoredPromiseAnyWithIndirection,
ignoredPromiseAnyWithIndirectionInTry,
awaitAfterDelayInTry,
catchInAsyncGenerator,
catchInGenerator,
catchAndAlsoDont,
];
const helpers = [delay, testWrapper];
const file = [...basicThrowFunctions, ...advancedThrowFunctions, ...basicCatchFunctions, ...advancedCatchFunctions, ...helpers].join('\n\n');
const startLine = 9; // Should match first line of first function
contextGroup.addScript(file, startLine, 0, 'catch-prediction.js');
session.setupScriptMap();
let pauseCount = 0
let uncaught = false;
let predictedUncaught = null;
let exceptionDetails = null;
let exceptionStackTrace = null;
let exceptionId = null;
function lazyLogException() {
if (exceptionDetails || exceptionStackTrace) {
InspectorTest.log(`Uncaught exception: ${exceptionDetails}`);
session.logAsyncStackTrace(exceptionStackTrace);
}
exceptionDetails = null;
exceptionStackTrace = null;
}
function uncaughtString(uncaught) {
return ((uncaught && 'uncaught') ?? '(undefined)') || 'caught';
}
Protocol.Debugger.onPaused(message => {
lazyLogException();
predictedUncaught = message.params.data?.uncaught;
InspectorTest.log(`Paused on ${uncaughtString(predictedUncaught)} ${message.params.reason}`);
session.logCallFrames(message.params.callFrames);
session.logAsyncStackTrace(message.params.asyncStackTrace);
InspectorTest.log('');
pauseCount++;
Protocol.Debugger.resume();
});
Protocol.Console.onMessageAdded(event => {
lazyLogException();
InspectorTest.log('console: ' + event.params.message.text);
});
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 6});
Protocol.Console.enable();
Protocol.Runtime.onExceptionRevoked(event => {
if (!uncaught) {
InspectorTest.log('ERROR: Revoked exception when none thrown');
} else if (!exceptionId) {
InspectorTest.log('ERROR: No exception id');
} else if (exceptionId !== event.params.exceptionId) {
InspectorTest.log('ERROR: exception id does not match');
}
exceptionId = null;
uncaught = false;
let message = 'Previously printed uncaught exception revoked';
if (exceptionDetails || exceptionStackTrace) {
message = 'Uncaught message immediately revoked';
exceptionDetails = null;
exceptionStackTrace = null;
}
InspectorTest.log(message + ' for reason: ' + event.params.reason)
});
Protocol.Runtime.onExceptionThrown(event => {
lazyLogException();
if (uncaught) {
InspectorTest.log('ERROR: Uncaught exception thrown twice');
}
uncaught = true;
// Save this info and lazily log it so we can not log it when it is
// immediately revoked.
exceptionDetails = event.params.exceptionDetails.text;
exceptionStackTrace = event.params.exceptionDetails.stackTrace;
exceptionId = event.params.exceptionDetails.exceptionId;
});
Protocol.Runtime.enable();
const testFunctions = [];
function addTestFunctionsFor(throwFunc, catchFunc) {
async function testCase(next) {
InspectorTest.log(`> Throwing from ${throwFunc.name}, handling with ${catchFunc.name}`);
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
uncaught = false;
pauseCount = 0;
predictedUncaught = null;
exceptionId = null;
await Protocol.Runtime.evaluate({expression: `testWrapper(${throwFunc.name}, ${catchFunc.name})//# sourceURL=test_framework.js`, awaitPromise: true});
lazyLogException();
InspectorTest.log('');
if (pauseCount !== 1) {
InspectorTest.log(`WARNING: Test paused ${pauseCount} times`);
}
if (pauseCount > 0) {
if (uncaught === predictedUncaught) {
InspectorTest.log('Correctly predicted as ' + uncaughtString(uncaught));
} else {
InspectorTest.log(`PREDICTION MISMATCH: Exception was ${uncaughtString(uncaught)} but was predicted to be ${uncaughtString(predictedUncaught)}`);
}
}
InspectorTest.log('------------------------------------------------------');
}
testFunctions.push(testCase);
}
for (const throwFunc of [...basicThrowFunctions, ...advancedThrowFunctions]) {
for (const catchFunc of basicCatchFunctions) {
addTestFunctionsFor(throwFunc, catchFunc);
}
}
for (const catchFunc of advancedCatchFunctions) {
for (const throwFunc of basicThrowFunctions) {
addTestFunctionsFor(throwFunc, catchFunc);
}
}
InspectorTest.runAsyncTestSuite(testFunctions);

View File

@ -0,0 +1,147 @@
// Copyright 2018 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Tests for break on exception.');
Protocol.Debugger.enable();
Protocol.Debugger.onPaused(({params:{data}}) => {
InspectorTest.log('paused on exception:');
InspectorTest.logMessage(data);
Protocol.Debugger.resume();
});
contextGroup.addInlineScript(`
function throws() {
throw 1;
}
function caught() {
try {
throws();
} catch (e) {
}
}
function uncaught() {
throws();
}
function uncaughtFinally() {
try {
throws();
} finally {
}
}
function caughtFinally() {
L: try {
throws();
} finally {
break L;
}
}
`, 'test.js');
InspectorTest.runAsyncTestSuite([
async function testPauseOnInitialState() {
await evaluate('caught()');
await evaluate('uncaught()');
await evaluate('uncaughtFinally()');
await evaluate('caughtFinally()');
},
async function testPauseOnExceptionOff() {
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
await evaluate('caught()');
await evaluate('uncaught()');
await evaluate('uncaughtFinally()');
await evaluate('caughtFinally()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnCaughtException() {
await Protocol.Debugger.setPauseOnExceptions({state: 'caught'});
await evaluate('caught()');
await evaluate('uncaught()');
await evaluate('uncaughtFinally()');
await evaluate('caughtFinally()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnUncaughtException() {
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
await evaluate('caught()');
await evaluate('uncaught()');
await evaluate('uncaughtFinally()');
await evaluate('caughtFinally()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnAll() {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
await evaluate('caught()');
await evaluate('uncaught()');
await evaluate('uncaughtFinally()');
await evaluate('caughtFinally()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testTryFinallyOriginalMessage() {
await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
await evaluate(`
try {
throw 1;
} finally {
}
`);
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testPromiseRejectedByCallback() {
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
await evaluate(`
function fun() { eval("throw 'rejection';") }
var p = new Promise(function(res, rej) { fun(); res(); });
var r;
p.then(() => { r = 'resolved'; }, (e) => { r = 'rejected' + e; });
`);
InspectorTest.log('r = ');
InspectorTest.logMessage((await Protocol.Runtime.evaluate({
expression: 'r'
})).result.result);
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnExceptionAfterReconnect() {
contextGroup.addInlineScript('function f() { throw new Error(); }');
await Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
await evaluate('f()');
InspectorTest.log('\nreconnect..');
session.reconnect();
await evaluate('f()');
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
},
async function testBreakOnExceptionInSilentMode(next) {
await Protocol.Debugger.setPauseOnExceptions({ state: "all" });
InspectorTest.log(`evaluate 'caught()'`);
await Protocol.Runtime.evaluate({expression: 'caught()', silent: true});
InspectorTest.log(`evaluate 'uncaught()'`);
await Protocol.Runtime.evaluate({expression: 'uncaught()', silent: true});
InspectorTest.log(`evaluate 'uncaughtFinally()'`);
await Protocol.Runtime.evaluate({
expression: 'uncaughtFinally()',
silent: true
});
InspectorTest.log(`evaluate 'caughtFinally()'`);
await Protocol.Runtime.evaluate({
xpression: 'caughtFinally()',
silent: true
});
await Protocol.Debugger.setPauseOnExceptions({state: 'none'});
}
]);
async function evaluate(expression) {
InspectorTest.log(`\nevaluate '${expression}'..`);
contextGroup.addInlineScript(expression);
await InspectorTest.waitForPendingTasks();
}

View File

@ -0,0 +1,26 @@
Tests how breakpoints and side effects live together.
Test breakpoint, should pause inside foo:
foo (test.js:3:2)
(anonymous) (:0:0)
Run foo with no side effects:
{
className : EvalError
description : EvalError: Possible side-effect in debug-evaluate
objectId : <objectId>
subtype : error
type : object
}
Test breakpoint after run with side effect check:
foo (test.js:3:2)
(anonymous) (:0:0)
Run foo with no side effects after debugger disabled:
{
className : EvalError
description : EvalError: Possible side-effect in debug-evaluate
objectId : <objectId>
subtype : error
type : object
}

View File

@ -0,0 +1,58 @@
// Copyright 2018 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests how breakpoints and side effects live together.');
(async function main() {
session.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: `
var a = 1;
function foo() {
a = 2;
}
//# sourceURL=test.js`});
Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 3});
InspectorTest.log('Test breakpoint, should pause inside foo:');
{
const evaluatePromise = Protocol.Runtime.evaluate({expression: 'foo()'});
const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
Protocol.Debugger.resume();
await evaluatePromise;
}
InspectorTest.log('\nRun foo with no side effects:');
{
const {result:{result}} = await Protocol.Runtime.evaluate({
expression: 'foo()',
throwOnSideEffect: true
});
InspectorTest.logMessage(result);
}
InspectorTest.log('\nTest breakpoint after run with side effect check:');
{
const evaluatePromise = Protocol.Runtime.evaluate({expression: 'foo()'});
const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
Protocol.Debugger.resume();
await evaluatePromise;
}
await Protocol.Debugger.disable();
InspectorTest.log('\nRun foo with no side effects after debugger disabled:');
{
const {result:{result}} = await Protocol.Runtime.evaluate({
expression: 'foo()',
throwOnSideEffect: true
});
InspectorTest.logMessage(result);
}
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,66 @@
Checks breakpoints.
Running test: testRemoveBreakpoint
Debugger.removeBreakpoint when agent is disabled:
{
error : {
code : -32000
message : Debugger agent is not enabled
}
id : <messageId>
}
Remove breakpoint with invalid breakpoint id:
{
id : <messageId>
result : {
}
}
{
id : <messageId>
result : {
}
}
Running test: testSetBreakpointByUrl
Adding conditional (arg === 1) breakpoint
evaluating foo1(0):
not paused
evaluating foo1(1):
hit expected breakpoint
Evaluating another script with the same url
evaluating foo2(0):
not paused
evaluating foo2(1):
hit expected breakpoint
Removing breakpoint
evaluating foo1(1):
not paused
evaluating foo2(1):
not paused
Adding breakpoint back
evaluating foo1(0):
not paused
evaluating foo1(1):
hit expected breakpoint
Disabling debugger agent
evaluating foo1(1):
not paused
evaluating foo2(1):
not paused
Enabling debugger agent
evaluating foo1(1):
not paused
evaluating foo2(1):
not paused
Running test: testSetBreakpointInScriptsWithDifferentOffsets
Adding breakpoint
evaluating foo1(0):
hit expected breakpoint
evaluating foo2(0):
hit expected breakpoint

View File

@ -0,0 +1,117 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks breakpoints.');
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testRemoveBreakpoint() {
InspectorTest.log('Debugger.removeBreakpoint when agent is disabled:');
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: '1:test.js:0:0'
}));
Protocol.Debugger.enable();
InspectorTest.log('Remove breakpoint with invalid breakpoint id:')
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: ''
}));
InspectorTest.logMessage(await Protocol.Debugger.removeBreakpoint({
breakpointId: ':::'
}));
await Protocol.Debugger.disable();
},
async function testSetBreakpointByUrl() {
await Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: `
function foo1(arg) {
return arg;
}
//# sourceURL=testSetBreakpointByUrl.js`});
InspectorTest.log('Adding conditional (arg === 1) breakpoint');
let {result:{breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 2,
url: 'testSetBreakpointByUrl.js',
columnNumber: 2,
condition: 'arg === 1'
});
await evaluate('foo1(0)');
await evaluate('foo1(1)', breakpointId);
InspectorTest.log('\nEvaluating another script with the same url')
Protocol.Runtime.evaluate({expression: `
function foo2(arg) {
return arg;
}
//# sourceURL=testSetBreakpointByUrl.js`});
await evaluate('foo2(0)');
await evaluate('foo2(1)', breakpointId);
InspectorTest.log('\nRemoving breakpoint');
await Protocol.Debugger.removeBreakpoint({breakpointId});
await evaluate('foo1(1)');
await evaluate('foo2(1)');
InspectorTest.log('\nAdding breakpoint back');
({result:{breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 2,
url: 'testSetBreakpointByUrl.js',
columnNumber: 2,
condition: 'arg === 1'
}));
await evaluate('foo1(0)');
await evaluate('foo1(1)', breakpointId);
InspectorTest.log('\nDisabling debugger agent');
await Protocol.Debugger.disable();
await evaluate('foo1(1)');
await evaluate('foo2(1)');
InspectorTest.log('\nEnabling debugger agent');
await Protocol.Debugger.enable();
await evaluate('foo1(1)');
await evaluate('foo2(1)');
},
async function testSetBreakpointInScriptsWithDifferentOffsets() {
await Protocol.Debugger.enable();
InspectorTest.log('Adding breakpoint');
let {result:{breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 2,
url: 'test2.js',
columnNumber: 2,
});
contextGroup.addScript(`
function foo1(arg) {
return arg;
}
//# sourceURL=test2.js`);
contextGroup.addScript(`
function foo2(arg) {
return arg;
}
//# sourceURL=test2.js`, 5);
await evaluate('foo1(0)', breakpointId);
await evaluate('foo2(0)', breakpointId);
}
]);
async function evaluate(expression, expectedBreakpoint) {
InspectorTest.log('evaluating ' + expression + ':');
let paused = Protocol.Debugger.oncePaused();
let evaluate = Protocol.Runtime.evaluate({expression});
let result = await Promise.race([paused, evaluate]);
if (result.method === 'Debugger.paused') {
if (result.params.hitBreakpoints) {
if (result.params.hitBreakpoints.find(b => b === expectedBreakpoint)) {
InspectorTest.log(' hit expected breakpoint')
} else {
InspectorTest.log(' hit unexpected breakpoint');
}
}
await Protocol.Debugger.resume();
} else {
InspectorTest.log(' not paused');
}
}

View File

@ -0,0 +1,4 @@
Tests that function location in call frames is correct
Paused on 'debugger;'
Top frame location: {"scriptId":"42","lineNumber":3,"columnNumber":4}
Top frame functionLocation: {"scriptId":"42","lineNumber":0,"columnNumber":21}

View File

@ -0,0 +1,27 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that function location in call frames is correct');
contextGroup.addScript(
`function testFunction()
{
var a = 2;
debugger;
}`);
Protocol.Debugger.enable();
Protocol.Debugger.oncePaused().then(handleDebuggerPaused);
Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0)" });
function handleDebuggerPaused(messageObject)
{
InspectorTest.log("Paused on 'debugger;'");
var topFrame = messageObject.params.callFrames[0];
topFrame.location.scriptId = "42";
topFrame.functionLocation.scriptId = "42";
InspectorTest.log("Top frame location: " + JSON.stringify(topFrame.location));
InspectorTest.log("Top frame functionLocation: " + JSON.stringify(topFrame.functionLocation));
InspectorTest.completeTest();
}

View File

@ -0,0 +1,15 @@
Tests url in Debugger.CallFrame.
[
[0] : {
url :
}
[1] : {
url :
}
[2] : {
url :
}
[3] : {
url :
}
]

View File

@ -0,0 +1,20 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests url in Debugger.CallFrame.');
contextGroup.addScript(`
eval('function foo1() { debugger; }');
eval('function foo2() { foo1() } //# sourceURL=source-url.js');
function foo3() { foo2(); }
`, 0, 0, 'test.js');
(async function test() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: 'foo3()//# sourceURL=expr.js'});
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
InspectorTest.logMessage(callFrames.map(frame => ({url: frame.url})));
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,4 @@
Async caught exception prediction and blackboxing.
paused at:
#debugger;

View File

@ -0,0 +1,38 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Async caught exception prediction and blackboxing.');
contextGroup.addScript(`
function constructorThrow() {
return new Promise((resolve, reject) =>
Promise.resolve().then(() =>
reject("f") // Exception f
)
);
}
function dotCatch(producer) {
Promise.resolve(producer()).catch(() => {});
}
//# sourceURL=framework.js`);
session.setupScriptMap();
(async function test() {
Protocol.Debugger.enable();
Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
Protocol.Debugger.setPauseOnExceptions({state: 'all'});
Protocol.Runtime.evaluate({expression: 'dotCatch(constructorThrow);'});
// Should break at this debugger statement, not at reject.
Protocol.Runtime.evaluate({expression: 'setTimeout(\'debugger;\', 0);'});
await waitPauseAndDumpLocation();
InspectorTest.completeTest();
})();
async function waitPauseAndDumpLocation() {
var message = await Protocol.Debugger.oncePaused();
InspectorTest.log('paused at:');
session.logSourceLocation(message.params.callFrames[0].location);
return message;
}

View File

@ -0,0 +1,13 @@
Check that inspector correctly passes caught/uncaught information.
paused in throwCaught
uncaught: false
paused in throwUncaught
uncaught: true
paused in throwInPromiseCaught
uncaught: false
paused in promiseUncaught
uncaught: true
paused in throwInMapConstructor
uncaught: true
paused in throwInAsyncIterator
uncaught: true

View File

@ -0,0 +1,46 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start("Check that inspector correctly passes caught/uncaught information.");
contextGroup.addScript(
`function throwCaught() { try { throw new Error(); } catch (_) {} }
function throwUncaught() { throw new Error(); }
function throwInPromiseCaught() {
var reject;
new Promise(function(res, rej) { reject = rej; }).catch(() => {});
reject();
}
function throwInPromiseUncaught() {
new Promise(function promiseUncaught() { throw new Error(); });
}
function throwInMapConstructor() { new Map('a'); }
function throwInAsyncIterator() {
let it = (async function*() {})();
it.next.call({});
}
function schedule(f) { setTimeout(f, 0); }
`);
Protocol.Debugger.enable();
Protocol.Debugger.setPauseOnExceptions({ "state": "all" });
Protocol.Debugger.onPaused(message => {
InspectorTest.log("paused in " + message.params.callFrames[0].functionName);
InspectorTest.log("uncaught: " + message.params.data.uncaught);
Protocol.Debugger.resume();
});
Protocol.Runtime.evaluate({ "expression": "schedule(throwCaught);" })
.then(() => Protocol.Runtime.evaluate(
{ "expression": "schedule(throwUncaught);" }))
.then(() => Protocol.Runtime.evaluate(
{ "expression": "schedule(throwInPromiseCaught);"}))
.then(() => Protocol.Runtime.evaluate(
{ "expression": "schedule(throwInPromiseUncaught);"}))
.then(() => Protocol.Runtime.evaluate(
{ "expression": "schedule(throwInMapConstructor);"}))
.then(() => Protocol.Runtime.evaluate(
{ "expression": "schedule(throwInAsyncIterator);"}))
.then(() => InspectorTest.completeTest());

View File

@ -0,0 +1,35 @@
Checks that we can update return value on pause
Running test: testError
Set return value not at return position
{
error : {
code : -32000
message : Could not update return value at non-return position
}
id : <messageId>
}
Running test: testUndefined
Break at return position..
Update return value to 42..
Dump actual return value
{
result : {
description : 42
type : number
value : 42
}
}
Running test: testArrow
Break at return position..
Update return value to 239..
Dump actual return value
{
result : {
description : 239
type : number
value : 239
}
}

View File

@ -0,0 +1,68 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Checks that we can update return value on pause');
InspectorTest.runAsyncTestSuite([
async function testError() {
Protocol.Debugger.enable();
let evaluation = Protocol.Runtime.evaluate({
expression: 'function foo() { debugger; } foo()',
returnByValue: true
});
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
InspectorTest.log('Set return value not at return position');
let result = await Protocol.Debugger.setReturnValue({
newValue: { value: 42 },
});
InspectorTest.logMessage(result);
await Protocol.Debugger.disable();
},
async function testUndefined() {
Protocol.Debugger.enable();
let evaluation = Protocol.Runtime.evaluate({
expression: 'function foo() { debugger; } foo()',
returnByValue: true
});
InspectorTest.log('Break at return position..');
await Protocol.Debugger.oncePaused();
Protocol.Debugger.stepInto();
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
InspectorTest.log('Update return value to 42..');
Protocol.Debugger.setReturnValue({
newValue: { value: 42 },
});
Protocol.Debugger.resume();
let {result} = await evaluation;
InspectorTest.log('Dump actual return value');
InspectorTest.logMessage(result);
await Protocol.Debugger.disable();
},
async function testArrow() {
Protocol.Debugger.enable();
Protocol.Debugger.pause();
let evaluation = Protocol.Runtime.evaluate({
expression: '(() => 42)()',
returnByValue: true
});
InspectorTest.log('Break at return position..');
await Protocol.Debugger.oncePaused();
Protocol.Debugger.stepInto();
await Protocol.Debugger.oncePaused();
Protocol.Debugger.stepInto();
let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
InspectorTest.log('Update return value to 239..');
Protocol.Debugger.setReturnValue({
newValue: { value: 239 },
});
Protocol.Debugger.resume();
let {result} = await evaluation;
InspectorTest.log('Dump actual return value');
InspectorTest.logMessage(result);
await Protocol.Debugger.disable();
}
]);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
// Copyright 2016 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.
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test class fields scopes"
);
contextGroup.addScript(`
function run() {
function foo() {
debugger;
return "foo";
}
function bar() {
return 3;
}
class X {
x = 1;
[foo()] = 2;
p = bar();
}
debugger;
new X;
}`);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: "run()" });
let {
params: { callFrames: callFrames0 }
} = await Protocol.Debugger.oncePaused(); // inside foo()
InspectorTest.logMessage(callFrames0);
Protocol.Debugger.resume();
await Protocol.Debugger.oncePaused(); // at debugger;
Protocol.Debugger.stepOver(); // at debugger;
await Protocol.Debugger.oncePaused(); // at new X;
Protocol.Debugger.stepInto(); // step into initializer_function;
// at x = 1;
let {
params: { callFrames: callFrames1 }
} = await Protocol.Debugger.oncePaused();
InspectorTest.logMessage(callFrames1);
Protocol.Debugger.stepOver();
// at [foo()] = 2;
let {
params: { callFrames: callFrames2 }
} = await Protocol.Debugger.oncePaused();
InspectorTest.logMessage(callFrames2);
Protocol.Debugger.stepOver();
// at p = bar();
let {
params: { callFrames: callFrames3 }
} = await Protocol.Debugger.oncePaused();
InspectorTest.logMessage(callFrames3);
Protocol.Debugger.stepInto();
// inside bar();
let {
params: { callFrames: callFrames4 }
} = await Protocol.Debugger.oncePaused();
InspectorTest.logMessage(callFrames4);
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,65 @@
Test static private class accessors
Running test: testScopesPaused
private members on the base class
privateProperties from Runtime.getProperties()
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[3] : {
name : #field
value : {
description : 2
type : number
value : 2
}
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
undefined
private members on the subclass
privateProperties from Runtime.getProperties()
[
[0] : {
get : {
className : Function
description : get #accessor() { return 'subclassAccessor'; }
objectId : <objectId>
type : function
}
name : #accessor
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
undefined

View File

@ -0,0 +1,64 @@
// Copyright 2024 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let {session, contextGroup, Protocol} =
InspectorTest.start('Test static private class accessors');
const script = `
function run() {
class A {
static test() {
debugger;
}
static #field = 2;
get #instanceAccessor() { return this.#field; } // should not show up
set #instanceAccessor(val) { this.#field = val; } // should not show up
static set #writeOnly(val) { this.#field = val; }
static get #readOnly() { return this.#field; }
static get #accessor() { return this.#field; }
static set #accessor(val) { this.#field = val; }
};
A.test();
class B extends A {
static get #accessor() { return 'subclassAccessor'; }
static test() {
debugger;
}
}
B.test();
}`;
contextGroup.addScript(script);
InspectorTest.runAsyncTestSuite([async function testScopesPaused() {
Protocol.Debugger.enable();
// Do not await here, instead oncePaused should be awaited.
Protocol.Runtime.evaluate({expression: 'run()'});
InspectorTest.log('private members on the base class');
let {params: {callFrames}} =
await Protocol.Debugger.oncePaused(); // inside A.test()
let frame = callFrames[0];
await printPrivateMembers(
Protocol, InspectorTest, {objectId: frame.this.objectId});
Protocol.Debugger.resume();
({params: {callFrames}} = await Protocol.Debugger.oncePaused()); // B.test();
frame = callFrames[0];
InspectorTest.log('private members on the subclass');
await printPrivateMembers(
Protocol, InspectorTest, {objectId: frame.this.objectId});
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}]);

View File

@ -0,0 +1,144 @@
Test private class fields in scopes
Running test: testScopesPaused
[
[0] : {
callFrameId : <callFrameId>
canBeRestarted : true
functionLocation : {
columnNumber : 16
lineNumber : 4
scriptId : <scriptId>
}
functionName : A
location : {
columnNumber : 6
lineNumber : 5
scriptId : <scriptId>
}
scopeChain : [
[0] : {
endLocation : {
columnNumber : 5
lineNumber : 6
scriptId : <scriptId>
}
name : A
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
startLocation : {
columnNumber : 16
lineNumber : 4
scriptId : <scriptId>
}
type : local
}
[1] : {
object : {
className : global
description : global
objectId : <objectId>
type : object
}
type : global
}
]
this : {
className : A
description : A
objectId : <objectId>
type : object
}
url :
}
[1] : {
callFrameId : <callFrameId>
canBeRestarted : true
functionLocation : {
columnNumber : 12
lineNumber : 1
scriptId : <scriptId>
}
functionName : run
location : {
columnNumber : 2
lineNumber : 8
scriptId : <scriptId>
}
scopeChain : [
[0] : {
endLocation : {
columnNumber : 1
lineNumber : 9
scriptId : <scriptId>
}
name : run
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
startLocation : {
columnNumber : 12
lineNumber : 1
scriptId : <scriptId>
}
type : local
}
[1] : {
object : {
className : global
description : global
objectId : <objectId>
type : object
}
type : global
}
]
this : {
className : global
description : global
objectId : <objectId>
type : object
}
url :
}
[2] : {
callFrameId : <callFrameId>
canBeRestarted : true
functionLocation : {
columnNumber : 0
lineNumber : 0
scriptId : <scriptId>
}
functionName :
location : {
columnNumber : 0
lineNumber : 0
scriptId : <scriptId>
}
scopeChain : [
[0] : {
object : {
className : global
description : global
objectId : <objectId>
type : object
}
type : global
}
]
this : {
className : global
description : global
objectId : <objectId>
type : object
}
url :
}
]

View File

@ -0,0 +1,32 @@
// Copyright 2019 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.
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test private class fields in scopes"
);
contextGroup.addScript(`
function run() {
class A {
#foo = "hello"
constructor () {
debugger;
}
};
new A();
}`);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: "run()" });
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside A()
InspectorTest.logMessage(callFrames);
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,7 @@
Test empty inner classes with private instance methods in the outer class
Running test: testScopesPaused
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
undefined

View File

@ -0,0 +1,41 @@
// Copyright 2020 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let {session, contextGroup, Protocol} = InspectorTest.start(
'Test empty inner classes with private instance methods in the outer class');
contextGroup.addScript(`
function run() {
class Outer {
#method() {}
factory() {
return class Inner {
fn() {
debugger;
}
};
}
};
const a = new Outer();
const Inner = a.factory();
(new Inner).fn();
}`);
InspectorTest.runAsyncTestSuite([async function testScopesPaused() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: 'run()'});
let {params: {callFrames}} =
await Protocol.Debugger.oncePaused(); // inside fn()
let frame = callFrames[0];
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}]);

View File

@ -0,0 +1,293 @@
Test private class methods
Running test: testScopesPaused
privateProperties from Runtime.getProperties()
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[3] : {
name : #field
value : {
description : 2
type : number
value : 2
}
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #inc() { this.#field++; return this.#field; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
private accessors properties on the base class instance
privateProperties from Runtime.getProperties()
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
]
Evaluating private methods
{
result : {
description : 3
type : number
value : 3
}
}
Evaluating private methods
{
result : {
description : 4
type : number
value : 4
}
}
Evaluating private accessors
{
result : {
description : 5
type : number
value : 5
}
}
Evaluating read-only accessor
{
result : {
description : 5
type : number
value : 5
}
}
Evaluating write-only accessor
{
result : {
description : 0
type : number
value : 0
}
}
private members on the subclass instance
privateProperties from Runtime.getProperties()
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[3] : {
name : #field
value : {
description : 2
type : number
value : 2
}
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[3]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #inc() { this.#field++; return this.#field; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
[1] : {
configurable : true
enumerable : true
isOwn : true
name : 1
value : {
className : Object
description : #subclassMethod() { return 'subclassMethod'; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
[2] : {
configurable : true
enumerable : true
isOwn : true
name : 2
value : {
className : Object
description : #inc() { return 'subclass #inc'; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
Evaluating private methods in the base class from the subclass
{
exceptionDetails : {
columnNumber : 4
exception : {
className : SyntaxError
description : SyntaxError: Private field '#subclassMethod' must be declared in an enclosing class at B.fn (<anonymous>:20:7) at run (<anonymous>:34:5) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
result : {
className : SyntaxError
description : SyntaxError: Private field '#subclassMethod' must be declared in an enclosing class at B.fn (<anonymous>:20:7) at run (<anonymous>:34:5) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
}
Evaluating private method in the subclass from the subclass
{
result : {
type : string
value : subclassMethod
}
}
Evaluating private method shadowing the base class method
{
result : {
type : string
value : subclass #inc
}
}

View File

@ -0,0 +1,128 @@
Test getting private class methods from an instance that calls nested super()
Running test: testScopesPaused
private members after super() is called in IIFE
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #b() {}
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
private members after super() is called in arrow function
privateProperties from Runtime.getProperties()
[
[0] : {
get : {
className : Function
description : get #c() {}
objectId : <objectId>
type : function
}
name : #c
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #b() {}
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
private members after super() is called in eval()
privateProperties from Runtime.getProperties()
[
[0] : {
get : {
className : Function
description : get #c() {}
objectId : <objectId>
type : function
}
name : #c
}
[1] : {
name : #d
set : {
className : Function
description : set #d(val) {}
objectId : <objectId>
type : function
}
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #b() {}
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}

View File

@ -0,0 +1,75 @@
// 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test getting private class methods from an instance that calls nested super()"
);
contextGroup.addScript(`
function run() {
class A {}
class B extends A {
#b() {}
constructor() {
(() => super())();
}
test() { debugger; }
};
(new B()).test();
class C extends B {
get #c() {}
constructor() {
const callSuper = () => super();
callSuper();
}
test() { debugger; }
};
(new C()).test();
class D extends C {
set #d(val) {}
constructor(str) {
eval(str);
}
test() { debugger; }
};
(new D('super();')).test();
}`);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: "run()" });
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside B constructor
let frame = callFrames[0];
InspectorTest.log('private members after super() is called in IIFE');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
({ params: { callFrames } }
= await Protocol.Debugger.oncePaused()); // inside C constructor
frame = callFrames[0];
InspectorTest.log('private members after super() is called in arrow function');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
({ params: { callFrames } }
= await Protocol.Debugger.oncePaused()); // inside D constructor
frame = callFrames[0];
InspectorTest.log('private members after super() is called in eval()');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,20 @@
Check private methods in object preview.
Running test: testPrivateMethods
expression: new class extends class { constructor() { return new Proxy({}, {}); } } { #method() { return 1; } }
[
]
expression: new class { #method() { return 1; } get #accessor() { } set #accessor(val) { } }
[
[0] : {
name : #accessor
type : accessor
}
]
expression: new class extends class { #method() { return 1; } } { get #accessor() { } set #accessor(val) { } }
[
[0] : {
name : #accessor
type : accessor
}
]

View File

@ -0,0 +1,36 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start("Check private methods in object preview.");
Protocol.Debugger.enable();
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(dumpInternalProperties);
contextGroup.setupInjectedScriptEnvironment();
InspectorTest.runAsyncTestSuite([
async function testPrivateMethods() {
const expressions = [
"new class extends class { constructor() { return new Proxy({}, {}); } } { #method() { return 1; } }",
"new class { #method() { return 1; } get #accessor() { } set #accessor(val) { } }",
"new class extends class { #method() { return 1; } } { get #accessor() { } set #accessor(val) { } }",
];
for (const expression of expressions) {
InspectorTest.log(`expression: ${expression}`);
await Protocol.Runtime.evaluate({
expression: `console.table(${expression})`,
generatePreview: true
});
}
}
]);
function dumpInternalProperties(message) {
try {
InspectorTest.logMessage(message.params.args[0].preview.properties);
} catch {
InspectorTest.logMessage(message);
}
}

View File

@ -0,0 +1,190 @@
Test static private class methods
Running test: testScopesPaused
private members on the base class
privateProperties from Runtime.getProperties()
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[3] : {
name : #field
value : {
description : 2
type : number
value : 2
}
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #inc() { return ++A.#accessor; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
Evaluating A.#inc();
{
result : {
description : 3
type : number
value : 3
}
}
Evaluating this.#inc();
{
result : {
description : 4
type : number
value : 4
}
}
Evaluating ++this.#accessor;
{
result : {
description : 5
type : number
value : 5
}
}
Evaluating this.#readOnly;
{
result : {
description : 5
type : number
value : 5
}
}
Evaluating this.#writeOnly = 0; this.#field;
{
result : {
description : 0
type : number
value : 0
}
}
private members on the subclass
privateProperties from Runtime.getProperties()
[
[0] : {
get : {
className : Function
description : get #accessor() { return 'subclassAccessor'; }
objectId : <objectId>
type : function
}
name : #accessor
}
]
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #subclassMethod() { return B.#accessor; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
Evaluating this.#inc(); from the base class
{
exceptionDetails : {
columnNumber : 4
exception : {
className : SyntaxError
description : SyntaxError: Private field '#inc' must be declared in an enclosing class at B.test (<anonymous>:24:7) at run (<anonymous>:28:5) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
result : {
className : SyntaxError
description : SyntaxError: Private field '#inc' must be declared in an enclosing class at B.test (<anonymous>:24:7) at run (<anonymous>:28:5) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
}
Evaluating this.#subclassMethod();
{
result : {
type : string
value : subclassAccessor
}
}

View File

@ -0,0 +1,40 @@
Test static private class methods
Running test: testScopesPaused
private members on class A
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #method() { debugger; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
private members on class B
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
undefined

View File

@ -0,0 +1,55 @@
// Copyright 2020 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test static private class methods"
);
const script = `
function run() {
class A {
static #method() {
debugger;
}
static test() {
class B {
static test() { debugger; }
}
A.#method(); // reference #method so it shows up
B.test();
}
}
A.test();
}`;
contextGroup.addScript(script);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
// Do not await here, instead oncePaused should be awaited.
Protocol.Runtime.evaluate({ expression: 'run()' });
InspectorTest.log('private members on class A');
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside A.#method()
let frame = callFrames[0];
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
({ params: { callFrames } } = await Protocol.Debugger.oncePaused()); // B.test();
frame = callFrames[0];
InspectorTest.log('private members on class B');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,28 @@
Check static private methods in object preview.
Running test: testPrivateMethods
expression: class { static get #readOnly() { return 1; } }
{
type : string
value : class { static get #readOnly() { return 1; } }
}
expression: class { static set #writeOnly(val) { } }
{
type : string
value : class { static set #writeOnly(val) { } }
}
expression: class { static #method() { return 1; } static get #accessor() { } static set #accessor(val) { } }
{
type : string
value : class { static #method() { return 1; } static get #accessor() { } static set #accessor(val) { } }
}
expression: class extends class { } { static #method() { return 1; } }
{
type : string
value : class extends class { } { static #method() { return 1; } }
}
expression: class extends class { static #method() { return 1; } } { get #accessor() { } set #accessor(val) { } }
{
type : string
value : class extends class { static #method() { return 1; } } { get #accessor() { } set #accessor(val) { } }
}

View File

@ -0,0 +1,39 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start("Check static private methods in object preview.");
Protocol.Debugger.enable();
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(dumpInternalProperties);
contextGroup.setupInjectedScriptEnvironment();
InspectorTest.runAsyncTestSuite([
async function testPrivateMethods() {
const expressions = [
"class { static get #readOnly() { return 1; } }",
"class { static set #writeOnly(val) { } }",
"class { static #method() { return 1; } static get #accessor() { } static set #accessor(val) { } }",
"class extends class { } { static #method() { return 1; } }",
"class extends class { static #method() { return 1; } } { get #accessor() { } set #accessor(val) { } }",
];
for (const expression of expressions) {
InspectorTest.log(`expression: ${expression}`);
// Currently the previews are strings of the source code of the classes
await Protocol.Runtime.evaluate({
expression: `console.table(${expression})`,
generatePreview: true
});
}
}
]);
function dumpInternalProperties(message) {
try {
InspectorTest.logMessage(message.params.args[0]);
} catch {
InspectorTest.logMessage(message);
}
}

View File

@ -0,0 +1,117 @@
// Copyright 2019 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test static private class methods"
);
const script = `
function run() {
class A {
static test() {
debugger;
}
static #field = 2;
#instanceMethod() { } // should not show up
get #instanceAccessor() { return this.#field; } // should not show up
set #instanceAccessor(val) { this.#field = val; } // should not show up
static set #writeOnly(val) { this.#field = val; }
static get #readOnly() { return this.#field; }
static get #accessor() { return this.#field; }
static set #accessor(val) { this.#field = val; }
static #inc() { return ++A.#accessor; }
};
A.test();
class B extends A {
static get #accessor() { return 'subclassAccessor'; }
static #subclassMethod() { return B.#accessor; }
static test() {
debugger;
}
}
B.test();
}`;
contextGroup.addScript(script);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
// Do not await here, instead oncePaused should be awaited.
Protocol.Runtime.evaluate({ expression: 'run()' });
InspectorTest.log('private members on the base class');
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside A.test()
let frame = callFrames[0];
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
InspectorTest.log('Evaluating A.#inc();');
let { result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'A.#inc();',
callFrameId: callFrames[0].callFrameId
});
InspectorTest.logObject(result);
InspectorTest.log('Evaluating this.#inc();');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#inc();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logObject(result);
InspectorTest.log('Evaluating ++this.#accessor;');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: '++this.#accessor;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logObject(result);
InspectorTest.log('Evaluating this.#readOnly;');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#readOnly;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logObject(result);
InspectorTest.log('Evaluating this.#writeOnly = 0; this.#field;');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#writeOnly = 0; this.#field;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logObject(result);
Protocol.Debugger.resume();
({ params: { callFrames } } = await Protocol.Debugger.oncePaused()); // B.test();
frame = callFrames[0];
InspectorTest.log('private members on the subclass');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
InspectorTest.log('Evaluating this.#inc(); from the base class');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#inc();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logMessage(result);
InspectorTest.log('Evaluating this.#subclassMethod();');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#subclassMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logMessage(result);
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,123 @@
Test accessing unused private methods at runtime
Running test: testScopesPaused
private members of A in testStatic()
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #staticMethod() { return 1; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
Access A.#staticMethod() in testStatic()
{
exceptionDetails : {
columnNumber : 0
exception : {
className : ReferenceError
description : ReferenceError: A is not defined at eval (eval at testStatic (:1:1), <anonymous>:1:1) at A.testStatic (<anonymous>:6:29) at run (<anonymous>:9:7) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
result : {
className : ReferenceError
description : ReferenceError: A is not defined at eval (eval at testStatic (:1:1), <anonymous>:1:1) at A.testStatic (<anonymous>:6:29) at run (<anonymous>:9:7) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
}
Access this.#staticMethod() in testStatic()
{
exceptionDetails : {
columnNumber : 5
exception : {
className : Error
description : Error: Unused static private method '#staticMethod' cannot be accessed at debug time at eval (eval at testStatic (:1:1), <anonymous>:1:6) at A.testStatic (<anonymous>:6:29) at run (<anonymous>:9:7) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
result : {
className : Error
description : Error: Unused static private method '#staticMethod' cannot be accessed at debug time at eval (eval at testStatic (:1:1), <anonymous>:1:6) at A.testStatic (<anonymous>:6:29) at run (<anonymous>:9:7) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
}
private members of a in testInstance()
privateProperties from Runtime.getProperties()
undefined
[[PrivateMethods]] in internalProperties from Runtime.getProperties()
{
name : [[PrivateMethods]]
value : {
className : Array
description : PrivateMethods[1]
objectId : <objectId>
subtype : internal#privateMethodList
type : object
}
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : 0
value : {
className : Object
description : #instanceMethod() { return 2; }
objectId : <objectId>
subtype : internal#privateMethod
type : object
}
writable : true
}
]
}
Evaluating this.#instanceMethod() in testInstance()
{
result : {
description : 2
type : number
value : 2
}
}

View File

@ -0,0 +1,73 @@
// Copyright 2020 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test accessing unused private methods at runtime"
);
const script = `
function run() {
class A {
#instanceMethod() { return 2; }
static #staticMethod() { return 1; }
static testStatic() { debugger; }
testInstance() { debugger; }
};
A.testStatic();
const a = new A;
a.testInstance();
}`;
contextGroup.addScript(script);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
// Do not await here, instead oncePaused should be awaited.
Protocol.Runtime.evaluate({ expression: 'run()' });
InspectorTest.log('private members of A in testStatic()');
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside A.testStatic()
let frame = callFrames[0];
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
// Variables not referenced in the source code are currently
// considered "optimized away".
InspectorTest.log('Access A.#staticMethod() in testStatic()');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'A.#staticMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logMessage(result);
InspectorTest.log('Access this.#staticMethod() in testStatic()');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#staticMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logMessage(result);
Protocol.Debugger.resume();
({ params: { callFrames } } = await Protocol.Debugger.oncePaused()); // a.testInstatnce();
frame = callFrames[0];
InspectorTest.log('private members of a in testInstance()');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
InspectorTest.log('Evaluating this.#instanceMethod() in testInstance()');
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#instanceMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.logMessage(result);
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,141 @@
// Copyright 2019 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.
utils.load('test/inspector/private-class-member-inspector-test.js');
let { session, contextGroup, Protocol } = InspectorTest.start(
"Test private class methods"
);
contextGroup.addScript(`
function run() {
class A {
#field = 2;
static #staticMethod() {} // should not show up
static get #staticAccessor() { } // should not show up
static set #staticAccessor(val) { } // should not show up
#inc() { this.#field++; return this.#field; }
set #writeOnly(val) { this.#field = val; }
get #readOnly() { return this.#field; }
get #accessor() { return this.#field; }
set #accessor(val) { this.#field = val; }
fn() {
debugger;
}
};
const a = new A();
a.fn();
class B extends A {
#subclassMethod() { return 'subclassMethod'; }
#inc() { return 'subclass #inc'; }
test() { debugger; }
}
const b = new B();
b.fn();
b.test();
}`);
InspectorTest.runAsyncTestSuite([
async function testScopesPaused() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: "run()" });
let {
params: { callFrames }
} = await Protocol.Debugger.oncePaused(); // inside a.fn()
let frame = callFrames[0];
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
InspectorTest.log('private accessors properties on the base class instance');
await printPrivateMembers(Protocol, InspectorTest, {
objectId: frame.this.objectId,
accessorPropertiesOnly: true,
});
let { result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#inc();',
callFrameId: callFrames[0].callFrameId
});
InspectorTest.log('Evaluating private methods');
InspectorTest.logObject(result);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#inc();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating private methods');
InspectorTest.logObject(result);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: '++this.#accessor;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating private accessors');
InspectorTest.logObject(result);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#readOnly;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating read-only accessor');
InspectorTest.logObject(result);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#writeOnly = 0; this.#field;',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating write-only accessor');
InspectorTest.logObject(result);
Protocol.Debugger.resume();
({ params: { callFrames } } = await Protocol.Debugger.oncePaused()); // b.fn();
frame = callFrames[0];
InspectorTest.log('private members on the subclass instance');
await printPrivateMembers(Protocol, InspectorTest, { objectId: frame.this.objectId });
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#subclassMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating private methods in the base class from the subclass');
InspectorTest.logMessage(result);
Protocol.Debugger.resume();
({ params: { callFrames } } = await Protocol.Debugger.oncePaused()); // b.test();
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#subclassMethod();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating private method in the subclass from the subclass');
InspectorTest.logObject(result);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({
expression: 'this.#inc();',
callFrameId: callFrames[0].callFrameId
}));
InspectorTest.log('Evaluating private method shadowing the base class method');
InspectorTest.logObject(result);
Protocol.Debugger.resume();
Protocol.Debugger.disable();
}
]);

View File

@ -0,0 +1,5 @@
Tests that we clear breakpoints on agent disabled
function foo() {#}
foo();#debugger;

View File

@ -0,0 +1,28 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests that we clear breakpoints on agent disabled');
(async function test() {
session.setupScriptMap();
Protocol.Runtime.evaluate({expression: 'function foo() {}'});
Protocol.Debugger.enable();
let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
await Protocol.Debugger.setBreakpoint({
location: {
lineNumber: 0, columnNumber: 16, scriptId
}
});
Protocol.Runtime.evaluate({expression: 'foo()'});
var {params:{callFrames}} = await Protocol.Debugger.oncePaused();
await session.logSourceLocation(callFrames[0].location);
await Protocol.Debugger.disable();
await Protocol.Debugger.enable();
Protocol.Debugger.onPaused(InspectorTest.logMessage);
Protocol.Runtime.evaluate({expression: 'foo();debugger;'});
var {params:{callFrames}} = await Protocol.Debugger.oncePaused();
await session.logSourceLocation(callFrames[0].location);
InspectorTest.completeTest();
})()

View File

@ -0,0 +1,25 @@
Checks that we collect obsolete async tasks with async stacks.
Async stacks count: 1
Scheduled async tasks: 1
Recurring async tasks: 0
Async stacks count: 0
Scheduled async tasks: 0
Recurring async tasks: 0
Async stacks count: 2
Scheduled async tasks: 2
Recurring async tasks: 0
Async stacks count: 0
Scheduled async tasks: 0
Recurring async tasks: 0
Async stacks count: 1
Scheduled async tasks: 1
Recurring async tasks: 0
Async stacks count: 0
Scheduled async tasks: 0
Recurring async tasks: 0

View File

@ -0,0 +1,35 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we collect obsolete async tasks with async stacks.');
contextGroup.addScript(`
function test() {
inspector.setMaxAsyncTaskStacks(128);
var p = Promise.resolve().then(() => 42);
inspector.dumpAsyncTaskStacksStateForTest();
inspector.setMaxAsyncTaskStacks(128);
inspector.dumpAsyncTaskStacksStateForTest();
p.then(() => 42).then(() => 239);
inspector.dumpAsyncTaskStacksStateForTest();
inspector.setMaxAsyncTaskStacks(128);
inspector.dumpAsyncTaskStacksStateForTest();
setTimeout(() => 42, 0);
inspector.dumpAsyncTaskStacksStateForTest();
inspector.setMaxAsyncTaskStacks(128);
inspector.dumpAsyncTaskStacksStateForTest();
}
`);
(async function test() {
Protocol.Debugger.enable();
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await Protocol.Runtime.evaluate({expression: 'test()'});
InspectorTest.completeTest();
})()

View File

@ -0,0 +1,211 @@
Checks that we drop old async call chains.
Running test: testInfrastructure
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 5
actual async chain len: 5
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(1024)
Run expression 'console.trace(42)' with async chain len: 5
actual async chain len: 5
Running test: testZeroLimit
inspector.setMaxAsyncTaskStacks(0)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 0
inspector.setMaxAsyncTaskStacks(0)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 0
inspector.setMaxAsyncTaskStacks(0)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 0
inspector.setMaxAsyncTaskStacks(0)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 0
Running test: testOneLimit
inspector.setMaxAsyncTaskStacks(1)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(1)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(1)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(1)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 1
Running test: testTwoLimit
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(2)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 1
Running test: testMoreThanTwoLimit
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(3)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(4)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(5)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(6)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 1
actual async chain len: 1
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 2
actual async chain len: 2
inspector.setMaxAsyncTaskStacks(7)
Run expression 'console.trace(42)' with async chain len: 3
actual async chain len: 3

View File

@ -0,0 +1,174 @@
// Copyright 2017 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.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we drop old async call chains.');
Protocol.Debugger.enable();
Protocol.Runtime.enable();
InspectorTest.runAsyncTestSuite([
async function testInfrastructure() {
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainPromise(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainPromise(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainPromise(5, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainSetTimeout(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainSetTimeout(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(1024);
runWithAsyncChainSetTimeout(5, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
},
async function testZeroLimit() {
const limit = 0;
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
},
async function testOneLimit() {
const limit = 1;
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
},
async function testTwoLimit() {
const limit = 2;
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(3, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(3, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
},
async function testMoreThanTwoLimit() {
for (let limit = 3; limit <= 7; ++limit) {
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainPromise(3, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(1, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(2, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
await setMaxAsyncTaskStacks(limit);
runWithAsyncChainSetTimeout(3, 'console.trace(42)');
dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
}
},
]);
function runWithAsyncChainPromise(len, source) {
InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
let asyncCall = `(function asyncCall(num) {
if (num === 0) {
${source};
return;
}
Promise.resolve().then(() => asyncCall(num - 1));
})(${len})`;
Protocol.Runtime.evaluate({expression: asyncCall});
}
function runWithAsyncChainSetTimeout(len, source) {
InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
let setTimeoutPrefix = '() => setTimeout(';
let setTimeoutSuffix = ', 0)';
Protocol.Runtime.evaluate({
expression: `setTimeout(${setTimeoutPrefix.repeat(len - 1)}'${source}'${setTimeoutSuffix.repeat(len - 1)}, 0)`
});
}
function dumpAsyncChainLength(message) {
let stackTrace = message.params.asyncStackTrace || message.params.stackTrace.parent;
let asyncChainCount = 0;
while (stackTrace) {
++asyncChainCount;
stackTrace = stackTrace.parent;
}
InspectorTest.log(`actual async chain len: ${asyncChainCount}\n`);
}
async function setMaxAsyncTaskStacks(max) {
let expression = `inspector.setMaxAsyncTaskStacks(${max})`;
InspectorTest.log(expression);
await Protocol.Runtime.evaluate({expression});
}

View File

@ -0,0 +1,225 @@
Tests breakable locations in comma expressions.
Running test: testBreakLocations
function testFunction() {
|C|foo(), |C|foo(), |C|foo();
|_|return |C|bar(), |C|bar();|R|
}
function foo() {
|_|return |C|baz(), |C|baz();|R|
}
function bar() {
|_|return |C|foo(),
1 |_|+ |C|foo(),
2 |_|+ |C|foo();|R|
}
const baz = |_|() => |_|0|R|;
|R|
Running test: testStepping
Execution paused in testFunction:
function testFunction() {
#foo(), foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
#return baz(), baz();
}
Called from testFunction:
function testFunction() {
#foo(), foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), #baz();
}
Called from testFunction:
function testFunction() {
#foo(), foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), baz();#
}
Called from testFunction:
function testFunction() {
#foo(), foo(), foo();
return bar(), bar();
Execution paused in testFunction:
function testFunction() {
foo(), #foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
#return baz(), baz();
}
Called from testFunction:
function testFunction() {
foo(), #foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), #baz();
}
Called from testFunction:
function testFunction() {
foo(), #foo(), foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), baz();#
}
Called from testFunction:
function testFunction() {
foo(), #foo(), foo();
return bar(), bar();
Execution paused in testFunction:
function testFunction() {
foo(), foo(), #foo();
return bar(), bar();
Execution paused in foo:
function foo() {
#return baz(), baz();
}
Called from testFunction:
function testFunction() {
foo(), foo(), #foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), #baz();
}
Called from testFunction:
function testFunction() {
foo(), foo(), #foo();
return bar(), bar();
Execution paused in foo:
function foo() {
return baz(), baz();#
}
Called from testFunction:
function testFunction() {
foo(), foo(), #foo();
return bar(), bar();
Execution paused in testFunction:
foo(), foo(), foo();
#return bar(), bar();
}
Execution paused in bar:
function bar() {
#return foo(),
1 + foo(),
Called from testFunction:
foo(), foo(), foo();
return #bar(), bar();
}
Execution paused in bar:
return foo(),
1 #+ foo(),
2 + foo();
Called from testFunction:
foo(), foo(), foo();
return #bar(), bar();
}
Execution paused in bar:
1 + foo(),
2 #+ foo();
}
Called from testFunction:
foo(), foo(), foo();
return #bar(), bar();
}
Execution paused in bar:
1 + foo(),
2 + foo();#
}
Called from testFunction:
foo(), foo(), foo();
return #bar(), bar();
}
Execution paused in testFunction:
foo(), foo(), foo();
return bar(), #bar();
}
Execution paused in bar:
function bar() {
#return foo(),
1 + foo(),
Called from testFunction:
foo(), foo(), foo();
return bar(), #bar();
}
Execution paused in bar:
return foo(),
1 #+ foo(),
2 + foo();
Called from testFunction:
foo(), foo(), foo();
return bar(), #bar();
}
Execution paused in bar:
1 + foo(),
2 #+ foo();
}
Called from testFunction:
foo(), foo(), foo();
return bar(), #bar();
}
Execution paused in bar:
1 + foo(),
2 + foo();#
}
Called from testFunction:
foo(), foo(), foo();
return bar(), #bar();
}
Execution paused in testFunction:
foo(), foo(), foo();
return bar(), bar();#
}
Resuming and finishing...

View File

@ -0,0 +1,96 @@
// Copyright 2022 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.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests breakable locations in comma expressions.');
const source = `
function testFunction() {
foo(), foo(), foo();
return bar(), bar();
}
function foo() {
return baz(), baz();
}
function bar() {
return foo(),
1 + foo(),
2 + foo();
}
const baz = () => 0;
`;
const url = 'test.js';
contextGroup.addScript(source, 0, 0, url);
session.setupScriptMap();
InspectorTest.runAsyncTestSuite([
async function testBreakLocations() {
const [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
const {result: {locations}} =
await Protocol.Debugger.getPossibleBreakpoints(
{start: {lineNumber: 0, columnNumber: 0, scriptId}});
await session.logBreakLocations(locations);
await Promise.all([
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
},
async function testStepping() {
const [, , {params: {scriptId}}] = await Promise.all([
Protocol.Runtime.enable(),
Protocol.Debugger.enable(),
Protocol.Debugger.onceScriptParsed(),
]);
const {breakpointId} = await Protocol.Debugger.setBreakpoint({
location: {
scriptId,
lineNumber: 2,
}
});
const evalPromise =
Protocol.Runtime.evaluate({expression: 'testFunction()'});
for (;;) {
const {method, params} = await Promise.race([
evalPromise,
Protocol.Debugger.oncePaused(),
]);
if (method !== 'Debugger.paused') {
break;
}
const callFrames = params.callFrames.filter(
callFrame => callFrame.location.scriptId === scriptId);
if (callFrames.length === 0) {
InspectorTest.log('Resuming and finishing...');
await Protocol.Debugger.resume();
} else {
const [{functionName, location}, ...callerFrames] = callFrames;
InspectorTest.log(`Execution paused in ${functionName}:`);
await session.logSourceLocation(location);
for (const {location, functionName} of callerFrames) {
InspectorTest.log(`Called from ${functionName}:`);
await session.logSourceLocation(location);
}
if (functionName === 'testFunction') {
await Protocol.Debugger.stepInto();
} else {
await Protocol.Debugger.stepOver();
}
}
}
await Promise.all([
Protocol.Debugger.removeBreakpoint({breakpointId}),
Protocol.Debugger.disable(),
Protocol.Runtime.disable(),
]);
}
]);

View File

@ -0,0 +1,23 @@
Check that debug and monitor methods from Command Line API works with bound function.
> debug foo and bar
> call foo and bar
paused in foo
paused in bar
> undebug foo and bar
> call foo and bar
> monitor foo and bar
> call foo and bar
function foo called
function bar called
> unmonitor foo and bar
> call foo and bar
> monitor and debug bar
> call bar
function bar called
paused in bar
> undebug bar
> call bar
function bar called
> debug and unmonitor bar
> call bar
paused in bar

View File

@ -0,0 +1,67 @@
// Copyright 2016 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Check that debug and monitor methods from Command Line API works with bound function.');
contextGroup.addScript(`
function foo() {}
function boo() {}
var bar = () => boo();
function testFunction() {
console.log("> debug foo and bar");
debug(foo);
debug(bar);
console.log("> call foo and bar");
foo();
bar();
console.log("> undebug foo and bar");
undebug(foo);
undebug(bar);
console.log("> call foo and bar");
foo();
bar();
console.log("> monitor foo and bar");
monitor(foo);
monitor(bar);
console.log("> call foo and bar");
foo();
bar();
console.log("> unmonitor foo and bar");
unmonitor(foo);
unmonitor(bar);
console.log("> call foo and bar");
foo();
bar();
console.log("> monitor and debug bar");
monitor(bar);
debug(bar);
console.log("> call bar");
bar();
console.log("> undebug bar");
undebug(bar);
console.log("> call bar");
bar();
console.log("> debug and unmonitor bar");
debug(bar);
unmonitor(bar);
console.log("> call bar");
bar();
}`);
Protocol.Runtime.enable();
Protocol.Debugger.enable();
Protocol.Debugger.onPaused(message => {
var functionName = message.params.callFrames[0].functionName;
InspectorTest.log(`paused in ${functionName}`);
Protocol.Debugger.resume();
});
Protocol.Runtime.onConsoleAPICalled(
message => InspectorTest.log(message.params.args[0].value));
Protocol.Runtime
.evaluate({expression: 'testFunction()', includeCommandLineAPI: true})
.then(InspectorTest.completeTest);

Some files were not shown because too many files have changed in this diff Show More