Skip to content

Commit

Permalink
[vm/concurrency] Introduce GroupDebugger that takes CodeBreakpoints m…
Browse files Browse the repository at this point in the history
…anagement away from isolate Debugger.

CodeBreakpoint class tracks patching of the call targets for the purpose of routing the call to the debugger runtime.
With this CL CodeBreakpoint instance is managed by GroupDebugger, debugger class owned by IsolateGroup, and can be associated with multiple BreakpointLocation, one location per isolate that set a breakpoint at particular code location.

TEST=observatory/tests/service/break_on_function_child_isolate_test

Issue #36097

Change-Id: I3b3d0974a0fb9668742e5c1e2a2ce13b84b1d630
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190732
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
  • Loading branch information
aam authored and commit-bot@chromium.org committed Mar 17, 2021
1 parent c5c8064 commit 4baf7e5
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// VMOptions=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
import 'dart:async';
import 'dart:isolate' as dart_isolate;

import 'package:observatory/service_io.dart';
import 'package:test/test.dart';
import 'service_test_common.dart';
import 'test_helper.dart';
import 'dart:developer';

const int LINE_A = 18;
const int LINE_B = 25;
const int LINE_C = 29;

foo(args) { // LINE_A
final dart_isolate.SendPort sendPort = args[0] as dart_isolate.SendPort;
sendPort.send('reply from foo');
}

testMain() async {
final rpResponse = dart_isolate.ReceivePort();
debugger(); // LINE_B
await dart_isolate.Isolate.spawn(foo, [rpResponse.sendPort]);
await rpResponse.first;
rpResponse.close();
debugger(); // LINE_C
}

final completerAtFoo = Completer();

final tests = <IsolateTest>[
hasPausedAtStart,
resumeIsolate,
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_B + 1),
(Isolate isolate) async {
// Set up a listener to wait for child isolate launch and breakpoint events.
final stream = await isolate.vm.getEventStream(VM.kDebugStream);
var childIsolate;
var subscription;
subscription = stream.listen((ServiceEvent event) async {
switch (event.kind) {
case ServiceEvent.kPauseStart:
childIsolate = event.isolate!;
await childIsolate.reload();

Library rootLib = await childIsolate.rootLibrary.load() as Library;
final foo = rootLib.functions.singleWhere((f) => f.name == 'foo');
final bpt = await childIsolate.addBreakpointAtEntry(foo);

expect(bpt is Breakpoint, isTrue);
childIsolate.resume();
break;
case ServiceEvent.kPauseBreakpoint:
if (childIsolate == event.isolate) {
ServiceMap stack = await childIsolate.getStack();
Frame top = stack['frames'][0];
Script script = await top.location!.script.load() as Script;
expect(script.tokenToLine(top.location!.tokenPos), equals(LINE_A));

childIsolate.resume();
subscription.cancel();
completerAtFoo.complete();
}
break;
}
});
},
resumeIsolate,
(Isolate isolate) async {
await completerAtFoo.future;
},
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_C + 1),
resumeIsolate,
];

main(args) async {
runIsolateTests(args, tests,
testeeConcurrent: testMain, pause_on_start: true);
}
1 change: 1 addition & 0 deletions runtime/observatory/tests/service/service_kernel.status
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_function_child_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode.
break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_function_child_isolate_test: SkipByDesign # Debugger is disabled in AOT mode.
break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode.
breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode.
Expand Down
Loading

0 comments on commit 4baf7e5

Please sign in to comment.