v8/test/inspector/debugger/wasm-instrumentation-breakpoint.js
Kim-Anh Tran 0c3fdff2d2 [debug] Capture more cases for instrumentation breakpoints
The previous implementation would not explicitly send
`Debugger.paused` events for instrumentation breakpoints
if they were to overlap with breaks due to:
* regular breakpoints
* OOM
* exceptions
* asserts

This CL is a step towards making sure that a separate
`Debugger.paused` event is always sent for an instrumentation
breakpoint. In some cases where we have overlapping reasons
but only know of one, the 'instrumentation' reason,
we still just send out one paused event with the reason
being `instrumentation`.

Drive-by: send instrumentation notification to all sessions,
remember which breakpoints are instrumentation breakpoints

Bug: chromium:1229541, chromium:1133307
Change-Id: Ie15438f78b8b81a89c64fa291ce7ecc36ebb2182
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3211892
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Kim-Anh Tran <kimanh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77333}
2021-10-12 08:53:39 +00:00

133 lines
5.5 KiB
JavaScript

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/wasm-inspector-test.js');
const {session, contextGroup, Protocol} =
InspectorTest.start('Test instrumentation breakpoints in wasm.');
session.setupScriptMap();
Protocol.Debugger.onPaused(async msg => {
let top_frame = msg.params.callFrames[0];
let reason = msg.params.reason;
let hitBreakpoints = msg.params.hitBreakpoints;
InspectorTest.log(`Paused at ${top_frame.url} with reason "${reason}".`);
if (!top_frame.url.startsWith('v8://test/')) {
await session.logSourceLocation(top_frame.location);
}
// Report the hit breakpoints to make sure that it is empty, as
// instrumentation breakpoints should not be reported as normal
// breakpoints.
InspectorTest.log(`Hit breakpoints: ${JSON.stringify(hitBreakpoints)}`)
Protocol.Debugger.resume();
});
InspectorTest.runAsyncTestSuite([
async function testBreakInStartFunction() {
const builder = new WasmModuleBuilder();
const start_fn = builder.addFunction('start', kSig_v_v).addBody([kExprNop]);
builder.addStart(start_fn.index);
await Protocol.Runtime.enable();
await Protocol.Debugger.enable();
InspectorTest.log('Setting instrumentation breakpoint');
InspectorTest.logMessage(
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'}));
InspectorTest.log('Compiling wasm module.');
await WasmInspectorTest.compile(builder.toArray());
InspectorTest.log('Instantiating module.');
await WasmInspectorTest.evalWithUrl(
'new WebAssembly.Instance(module)', 'instantiate');
InspectorTest.log(
'Instantiating a second time (should trigger no breakpoint).');
await WasmInspectorTest.evalWithUrl(
'new WebAssembly.Instance(module)', 'instantiate2');
InspectorTest.log('Done.');
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
// If we compile twice, we get two instrumentation breakpoints (which might or
// might not be expected, but it's the current behaviour).
async function testBreakInStartFunctionCompileTwice() {
const builder = new WasmModuleBuilder();
const start_fn = builder.addFunction('start', kSig_v_v).addBody([kExprNop]);
builder.addStart(start_fn.index);
await Protocol.Runtime.enable();
await Protocol.Debugger.enable();
InspectorTest.log('Setting instrumentation breakpoint');
InspectorTest.logMessage(
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'}));
InspectorTest.log('Instantiating module.');
await WasmInspectorTest.instantiate(builder.toArray());
InspectorTest.log(
'Instantiating a second time (should trigger another breakpoint).');
await WasmInspectorTest.instantiate(builder.toArray());
InspectorTest.log('Done.');
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
async function testBreakInExportedFunction() {
const builder = new WasmModuleBuilder();
const func =
builder.addFunction('func', kSig_v_v).addBody([kExprNop]).exportFunc();
await Protocol.Runtime.enable();
await Protocol.Debugger.enable();
InspectorTest.log('Setting instrumentation breakpoint');
InspectorTest.logMessage(
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'}));
InspectorTest.log('Instantiating wasm module.');
await WasmInspectorTest.instantiate(builder.toArray());
InspectorTest.log(
'Calling exported function \'func\' (should trigger a breakpoint).');
await WasmInspectorTest.evalWithUrl('instance.exports.func()', 'call_func');
InspectorTest.log(
'Calling exported function \'func\' a second time ' +
'(should trigger no breakpoint).');
await WasmInspectorTest.evalWithUrl('instance.exports.func()', 'call_func');
InspectorTest.log('Done.');
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
async function testBreakOnlyWithSourceMap() {
const builder = new WasmModuleBuilder();
const func =
builder.addFunction('func', kSig_v_v).addBody([kExprNop]).exportFunc();
const bytes_no_source_map = builder.toArray();
builder.addCustomSection('sourceMappingURL', [3, 97, 98, 99]);
const bytes_with_source_map = builder.toArray();
await Protocol.Runtime.enable();
await Protocol.Debugger.enable();
InspectorTest.log(
'Setting instrumentation breakpoint for source maps only');
InspectorTest.logMessage(
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptWithSourceMapExecution'}));
InspectorTest.log('Instantiating wasm module without source map.');
await WasmInspectorTest.instantiate(bytes_no_source_map);
InspectorTest.log(
'Calling exported function \'func\' (should trigger no breakpoint).');
await WasmInspectorTest.evalWithUrl('instance.exports.func()', 'call_func');
InspectorTest.log('Instantiating wasm module with source map.');
await WasmInspectorTest.instantiate(bytes_with_source_map);
InspectorTest.log(
'Calling exported function \'func\' (should trigger a breakpoint).');
await WasmInspectorTest.evalWithUrl('instance.exports.func()', 'call_func');
InspectorTest.log('Done.');
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
]);