v8/test/debugger/debug/wasm/breakpoints.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

79 lines
3.0 KiB
JavaScript
Raw Normal View History

[wasm][debug] Support multi-threaded breakpoints This adds support for multiple isolates sharing the same module but setting different breakpoints. This is simulated by having a debugger test that runs in the "--isolates" variant, i.e. two isolates running the same test at the same time. Both isolates will set and remove breakpoints. The DebugInfo will keep a separate list of breakpoints per isolate, and when recompiling a function for debugging it will respect all breakpoints in all isolates. In order to ensure consistency if multiple isolates are setting or removing breakpoints simultaneously, we go back to a more coarse-grained locking scheme, where the DebugInfo lock is held while re-compiling Liftoff functions. While recompilation will install the code in the module-global code table and jump table (and hence all isolates will use it for future calls), only the stack of the requesting isolate is rewritten to immediately use new code. This is OK, because other isolates are not interested in the new breakpoint(s) anyway. On {SetBreakpoint}, we always need to rewrite the stack of the requesting isolate though, even if the breakpoint was set before by another isolate. Drive-by: Some fixes in SharedFunctionInfo in order to support setting breakpoints via the Debug mirror. R=thibaudm@chromium.org Bug: v8:10359 Change-Id: If659afb273260fc5e8124b4b617fb4322de473c7 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218059 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68096}
2020-05-29 09:32:08 +00:00
// 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.
// Test setting and removing breakpoints in Wasm.
// Similar tests exist as inspector tests already, but inspector tests are not
// run concurrently in multiple isolates (see `run-tests.py --isolates`).
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
[wasm][debug] Support multi-threaded breakpoints This adds support for multiple isolates sharing the same module but setting different breakpoints. This is simulated by having a debugger test that runs in the "--isolates" variant, i.e. two isolates running the same test at the same time. Both isolates will set and remove breakpoints. The DebugInfo will keep a separate list of breakpoints per isolate, and when recompiling a function for debugging it will respect all breakpoints in all isolates. In order to ensure consistency if multiple isolates are setting or removing breakpoints simultaneously, we go back to a more coarse-grained locking scheme, where the DebugInfo lock is held while re-compiling Liftoff functions. While recompilation will install the code in the module-global code table and jump table (and hence all isolates will use it for future calls), only the stack of the requesting isolate is rewritten to immediately use new code. This is OK, because other isolates are not interested in the new breakpoint(s) anyway. On {SetBreakpoint}, we always need to rewrite the stack of the requesting isolate though, even if the breakpoint was set before by another isolate. Drive-by: Some fixes in SharedFunctionInfo in order to support setting breakpoints via the Debug mirror. R=thibaudm@chromium.org Bug: v8:10359 Change-Id: If659afb273260fc5e8124b4b617fb4322de473c7 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218059 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68096}
2020-05-29 09:32:08 +00:00
const builder = new WasmModuleBuilder();
const body_a = [
kExprLocalGet, 0, // local.get i0
kExprI32Const, 1, // i32.const 1
kExprI32Add // i32.add i0 1
];
const fun_a = builder.addFunction('a', kSig_i_i).addBody(body_a).exportFunc();
const body_b = [
kExprLocalGet, 0, // local.get i0
kExprCallFunction, fun_a.index, // call a
kExprLocalGet, 1, // local.get i1
kExprI32Sub, // i32.sub a(i0) i1
kExprCallFunction, fun_a.index, // call a
];
const fun_b = builder.addFunction('b', kSig_i_ii).addBody(body_b).exportFunc();
const instance = builder.instantiate();
Debug = debug.Debug;
const a_localget_offset = body_a.indexOf(kExprLocalGet);
const a_const_offset = body_a.indexOf(kExprI32Const);
const a_add_offset = body_a.indexOf(kExprI32Add);
const b_sub_offset = body_b.indexOf(kExprI32Sub);
const expected_breaks = [
`$a:1:${fun_a.body_offset + a_add_offset}`, // break in a at i32.add
`$b:1:${fun_b.body_offset + b_sub_offset}`, // break in b at i32.sub
`$a:1:${fun_a.body_offset + a_localget_offset}`, // break in a at local.get i0
`$a:1:${fun_a.body_offset + a_const_offset}` // break in a at i32.const 1
[wasm][debug] Support multi-threaded breakpoints This adds support for multiple isolates sharing the same module but setting different breakpoints. This is simulated by having a debugger test that runs in the "--isolates" variant, i.e. two isolates running the same test at the same time. Both isolates will set and remove breakpoints. The DebugInfo will keep a separate list of breakpoints per isolate, and when recompiling a function for debugging it will respect all breakpoints in all isolates. In order to ensure consistency if multiple isolates are setting or removing breakpoints simultaneously, we go back to a more coarse-grained locking scheme, where the DebugInfo lock is held while re-compiling Liftoff functions. While recompilation will install the code in the module-global code table and jump table (and hence all isolates will use it for future calls), only the stack of the requesting isolate is rewritten to immediately use new code. This is OK, because other isolates are not interested in the new breakpoint(s) anyway. On {SetBreakpoint}, we always need to rewrite the stack of the requesting isolate though, even if the breakpoint was set before by another isolate. Drive-by: Some fixes in SharedFunctionInfo in order to support setting breakpoints via the Debug mirror. R=thibaudm@chromium.org Bug: v8:10359 Change-Id: If659afb273260fc5e8124b4b617fb4322de473c7 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218059 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68096}
2020-05-29 09:32:08 +00:00
];
let error;
function onBreak(event, exec_state, data) {
try {
if (event != Debug.DebugEvent.Break) return;
if (error) return;
const pos =
[data.functionName(), data.sourceLine(), data.sourceColumn()].join(':');
const loc = [pos, data.sourceLineText()].join(':');
print(`Break at ${loc}`);
assertTrue(expected_breaks.length > 0, 'expecting more breaks');
const expected_pos = expected_breaks.shift();
assertEquals(expected_pos, pos);
// When we stop in b, we add another breakpoint in a at offset 0 and remove
// the existing breakpoint.
if (data.functionName() === '$b') {
[wasm][debug] Support multi-threaded breakpoints This adds support for multiple isolates sharing the same module but setting different breakpoints. This is simulated by having a debugger test that runs in the "--isolates" variant, i.e. two isolates running the same test at the same time. Both isolates will set and remove breakpoints. The DebugInfo will keep a separate list of breakpoints per isolate, and when recompiling a function for debugging it will respect all breakpoints in all isolates. In order to ensure consistency if multiple isolates are setting or removing breakpoints simultaneously, we go back to a more coarse-grained locking scheme, where the DebugInfo lock is held while re-compiling Liftoff functions. While recompilation will install the code in the module-global code table and jump table (and hence all isolates will use it for future calls), only the stack of the requesting isolate is rewritten to immediately use new code. This is OK, because other isolates are not interested in the new breakpoint(s) anyway. On {SetBreakpoint}, we always need to rewrite the stack of the requesting isolate though, even if the breakpoint was set before by another isolate. Drive-by: Some fixes in SharedFunctionInfo in order to support setting breakpoints via the Debug mirror. R=thibaudm@chromium.org Bug: v8:10359 Change-Id: If659afb273260fc5e8124b4b617fb4322de473c7 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218059 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68096}
2020-05-29 09:32:08 +00:00
Debug.setBreakPoint(instance.exports.a, 0, a_localget_offset);
Debug.clearBreakPoint(breakpoint_a);
}
// When we stop at a at local.get, we set another breakpoint *in the same
// function*, one instruction later (at i32.const).
if (data.functionName() === '$a' &&
[wasm][debug] Support multi-threaded breakpoints This adds support for multiple isolates sharing the same module but setting different breakpoints. This is simulated by having a debugger test that runs in the "--isolates" variant, i.e. two isolates running the same test at the same time. Both isolates will set and remove breakpoints. The DebugInfo will keep a separate list of breakpoints per isolate, and when recompiling a function for debugging it will respect all breakpoints in all isolates. In order to ensure consistency if multiple isolates are setting or removing breakpoints simultaneously, we go back to a more coarse-grained locking scheme, where the DebugInfo lock is held while re-compiling Liftoff functions. While recompilation will install the code in the module-global code table and jump table (and hence all isolates will use it for future calls), only the stack of the requesting isolate is rewritten to immediately use new code. This is OK, because other isolates are not interested in the new breakpoint(s) anyway. On {SetBreakpoint}, we always need to rewrite the stack of the requesting isolate though, even if the breakpoint was set before by another isolate. Drive-by: Some fixes in SharedFunctionInfo in order to support setting breakpoints via the Debug mirror. R=thibaudm@chromium.org Bug: v8:10359 Change-Id: If659afb273260fc5e8124b4b617fb4322de473c7 Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218059 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68096}
2020-05-29 09:32:08 +00:00
data.sourceColumn() == fun_a.body_offset) {
Debug.setBreakPoint(instance.exports.a, 0, a_const_offset);
}
} catch (e) {
if (!error) error = e;
}
}
Debug.setListener(onBreak);
const breakpoint_a = Debug.setBreakPoint(instance.exports.a, 0, a_add_offset);
const breakpoint_b = Debug.setBreakPoint(instance.exports.b, 0, b_sub_offset);
print('Running b(11).');
const result = instance.exports.b(11);
print('Returned from wasm.');
if (error) throw error;
assertEquals(0, expected_breaks.length, 'all breaks were hit');