-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vm/concurrency] Introduce GroupDebugger that takes CodeBreakpoints m…
…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
Showing
9 changed files
with
370 additions
and
119 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
runtime/observatory/tests/service/break_on_function_child_isolate_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.