7eb95ad901
Change-Id: I6e02b29fedcb92a6670665c70f6a9b34a06c5d9d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/335242 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Derek Xu <derekx@google.com>
153 lines
4.5 KiB
Dart
153 lines
4.5 KiB
Dart
// Copyright (c) 2023, 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.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:test/test.dart';
|
|
import 'package:vm_service/vm_service.dart';
|
|
|
|
import 'common/service_test_common.dart';
|
|
import 'common/test_helper.dart';
|
|
|
|
int counter = 0;
|
|
const LINE_A = 20;
|
|
const LINE_B = LINE_A + 1;
|
|
const LINE_C = LINE_A - 2;
|
|
|
|
void periodicTask(_) {
|
|
counter++;
|
|
counter++; // Line 19. We set our breakpoint here.
|
|
counter++;
|
|
if (counter % 300 == 0) {
|
|
print('counter = $counter');
|
|
}
|
|
}
|
|
|
|
void startTimer() {
|
|
Timer.periodic(const Duration(milliseconds: 10), periodicTask);
|
|
}
|
|
|
|
Future<void> waitForEvent(VmService service, String eventKind) {
|
|
final completer = Completer<void>();
|
|
late final StreamSubscription<Event> subscription;
|
|
subscription = service.onDebugEvent.listen((Event event) {
|
|
if (event.kind == eventKind) {
|
|
subscription.cancel();
|
|
completer.complete();
|
|
}
|
|
});
|
|
return completer.future;
|
|
}
|
|
|
|
final tests = <IsolateTest>[
|
|
// Initialize stream.
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
await service.streamListen(EventStreams.kDebug);
|
|
},
|
|
// Pause
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
final isolateId = isolateRef.id!;
|
|
final event = waitForEvent(service, EventKind.kPauseInterrupted);
|
|
await service.pause(isolateId);
|
|
await event;
|
|
},
|
|
|
|
// Resume
|
|
resumeIsolate,
|
|
|
|
// Add breakpoint
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
final isolateId = isolateRef.id!;
|
|
var isolate = await service.getIsolate(isolateId);
|
|
final rootLib =
|
|
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
|
final scriptId = rootLib.scripts![0].id!;
|
|
final script = await service.getObject(isolateId, scriptId) as Script;
|
|
|
|
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
|
|
|
|
// Add the breakpoint.
|
|
final bpt = await service.addBreakpoint(isolateId, scriptId, LINE_A);
|
|
expect(bpt.location!.script!.id, scriptId);
|
|
expect(script.getLineNumberFromTokenPos(bpt.location!.tokenPos), LINE_A);
|
|
|
|
isolate = await service.getIsolate(isolateId);
|
|
expect(isolate.breakpoints!.length, 1);
|
|
|
|
await event; // Wait for breakpoint events.
|
|
},
|
|
|
|
// We are at the breakpoint on LINE_A.
|
|
stoppedAtLine(LINE_A),
|
|
|
|
// Stepping
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
|
|
await service.resume(isolateRef.id!, step: StepOption.kOver);
|
|
await event; // Wait for breakpoint events.
|
|
},
|
|
|
|
// We are now at line LINE_B.
|
|
stoppedAtLine(LINE_B),
|
|
|
|
// Remove breakpoint
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
final isolateId = isolateRef.id!;
|
|
var isolate = await service.getIsolate(isolateId);
|
|
|
|
// Set up a listener to wait for breakpoint events.
|
|
final event = waitForEvent(service, EventKind.kBreakpointRemoved);
|
|
|
|
expect(isolate.breakpoints!.length, 1);
|
|
final bpt = isolate.breakpoints!.first;
|
|
await service.removeBreakpoint(isolateId, bpt.id!);
|
|
await event;
|
|
|
|
isolate = await service.getIsolate(isolateId);
|
|
expect(isolate.breakpoints!.length, 0);
|
|
},
|
|
|
|
// Resume
|
|
resumeIsolate,
|
|
|
|
// Add breakpoint at function entry
|
|
(VmService service, IsolateRef isolateRef) async {
|
|
// Set up a listener to wait for breakpoint events.
|
|
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
|
|
|
|
final isolateId = isolateRef.id!;
|
|
var isolate = await service.getIsolate(isolateId);
|
|
final rootLib =
|
|
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
|
|
|
// Find a specific function.
|
|
final function = rootLib.functions!.firstWhere(
|
|
(f) => f.name == 'periodicTask',
|
|
);
|
|
|
|
// Add the breakpoint at function entry
|
|
final bpt = await service.addBreakpointAtEntry(isolateId, function.id!);
|
|
|
|
final script =
|
|
await service.getObject(isolateId, bpt.location!.script!.id!) as Script;
|
|
expect(script.uri, endsWith('debugging_test.dart'));
|
|
expect(script.getLineNumberFromTokenPos(bpt.location!.tokenPos), LINE_C);
|
|
|
|
isolate = await service.getIsolate(isolateId);
|
|
expect(isolate.breakpoints!.length, 1);
|
|
|
|
await event; // Wait for breakpoint events.
|
|
},
|
|
|
|
// We are now at line LINE_C, the entrypoint for periodicTask.
|
|
stoppedAtLine(LINE_C),
|
|
];
|
|
|
|
void main(List<String> args) => runIsolateTests(
|
|
args,
|
|
tests,
|
|
'debugging_test.dart',
|
|
testeeBefore: startTimer,
|
|
);
|