mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:59:47 +00:00
Reland "[ VM / Service ] Add setIsolatePauseMode RPC"
This reverts commitd21897b88d
. Reason for revert: Reland before fixing failures in google3 (requires copybara update of package:vm_service which requires this change to have already been landed in the SDK). Original change's description: > Revert "[ VM / Service ] Add setIsolatePauseMode RPC" > > This reverts commitcad8a34d83
. > > Reason for revert: broke the g3 cbuild, see cbuild logs > (Error: The method 'setIsolatePauseMode' isn't defined for the class 'VmServiceInterface') > > Original change's description: > > [ VM / Service ] Add setIsolatePauseMode RPC > > > > Allows for service clients to set pause behaviors on a per-isolate > > basis at runtime. setIsolatePauseMode is a more general version of > > setExceptionPauseMode and setExceptionPauseMode has been marked as deprecated. > > > > TEST=pause_on_exceptions_*_test.dart,should_pause_on_exit_test.dart > > > > Change-Id: I09d80aa2123791dd74d02441c162c19cc0486955 > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219580 > > Commit-Queue: Ben Konyi <bkonyi@google.com> > > Reviewed-by: Siva Annamalai <asiva@google.com> > > TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com > > Change-Id: Ic326c54e0fd682e382bd70e36d87467d4148c990 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220067 > Reviewed-by: Siva Annamalai <asiva@google.com> > Commit-Queue: Siva Annamalai <asiva@google.com> # Not skipping CQ checks because this is a reland. Change-Id: I0e25654e1991b7246cd413454ef45594d36f4bde Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220127 Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
39d930305c
commit
5de4830a4e
|
@ -581,7 +581,10 @@ class IsolateManager {
|
|||
return;
|
||||
}
|
||||
|
||||
await service.setExceptionPauseMode(isolate.id!, _exceptionPauseMode);
|
||||
await service.setIsolatePauseMode(
|
||||
isolate.id!,
|
||||
exceptionPauseMode: _exceptionPauseMode,
|
||||
);
|
||||
}
|
||||
|
||||
/// Calls setLibraryDebuggable for all libraries in the given isolate based
|
||||
|
|
|
@ -25,7 +25,7 @@ dependencies:
|
|||
shelf_web_socket: ^1.0.0
|
||||
sse: ^4.0.0
|
||||
stream_channel: ^2.0.0
|
||||
vm_service: ^7.2.0
|
||||
vm_service: ^7.5.0
|
||||
web_socket_channel: ^2.0.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Changelog
|
||||
|
||||
## 7.5.0
|
||||
- Update to version `3.53` of the spec.
|
||||
- Added `setIsolatePauseMode` RPC.
|
||||
- Deprecated `setExceptionPauseMode` in favor of `setIsolatePauseMode`.
|
||||
|
||||
## 7.4.0
|
||||
- Update to version `3.52` of the spec.
|
||||
- Added `lookupResolvedPackageUris` and `lookupPackageUris` RPCs and `UriList`
|
||||
|
|
1
pkg/vm_service/java/.gitignore
vendored
1
pkg/vm_service/java/.gitignore
vendored
|
@ -36,6 +36,7 @@ src/org/dartlang/vm/service/consumer/RequestHeapSnapshotConsumer.java
|
|||
src/org/dartlang/vm/service/consumer/ResumeConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetExceptionPauseModeConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetFlagConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetIsolatePauseModeConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetLibraryDebuggableConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetNameConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/SetTraceClassAllocationConsumer.java
|
||||
|
|
|
@ -1 +1 @@
|
|||
version=3.52
|
||||
version=3.53
|
||||
|
|
|
@ -26,7 +26,7 @@ export 'snapshot_graph.dart'
|
|||
HeapSnapshotObjectNoData,
|
||||
HeapSnapshotObjectNullData;
|
||||
|
||||
const String vmServiceVersion = '3.52.0';
|
||||
const String vmServiceVersion = '3.53.0';
|
||||
|
||||
/// @optional
|
||||
const String optional = 'optional';
|
||||
|
@ -236,6 +236,7 @@ Map<String, List<String>> _methodReturnTypes = {
|
|||
'resume': const ['Success'],
|
||||
'setBreakpointState': const ['Breakpoint'],
|
||||
'setExceptionPauseMode': const ['Success'],
|
||||
'setIsolatePauseMode': const ['Success'],
|
||||
'setFlag': const ['Success', 'Error'],
|
||||
'setLibraryDebuggable': const ['Success'],
|
||||
'setName': const ['Success'],
|
||||
|
@ -1078,9 +1079,34 @@ abstract class VmServiceInterface {
|
|||
///
|
||||
/// This method will throw a [SentinelException] in the case a [Sentinel] is
|
||||
/// returned.
|
||||
@Deprecated('Use setIsolatePauseMode instead')
|
||||
Future<Success> setExceptionPauseMode(
|
||||
String isolateId, /*ExceptionPauseMode*/ String mode);
|
||||
|
||||
/// The `setIsolatePauseMode` RPC is used to control if or when an isolate
|
||||
/// will pause due to a change in execution state.
|
||||
///
|
||||
/// The `shouldPauseOnExit` parameter specify whether the target isolate
|
||||
/// should pause on exit.
|
||||
///
|
||||
/// The `setExceptionPauseMode` RPC is used to control if an isolate pauses
|
||||
/// when an exception is thrown.
|
||||
///
|
||||
/// mode | meaning
|
||||
/// ---- | -------
|
||||
/// None | Do not pause isolate on thrown exceptions
|
||||
/// Unhandled | Pause isolate on unhandled exceptions
|
||||
/// All | Pause isolate on all thrown exceptions
|
||||
///
|
||||
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
|
||||
/// [Sentinel] is returned.
|
||||
///
|
||||
/// This method will throw a [SentinelException] in the case a [Sentinel] is
|
||||
/// returned.
|
||||
Future<Success> setIsolatePauseMode(String isolateId,
|
||||
{/*ExceptionPauseMode*/ String? exceptionPauseMode,
|
||||
bool? shouldPauseOnExit});
|
||||
|
||||
/// The `setFlag` RPC is used to set a VM flag at runtime. Returns an error if
|
||||
/// the named flag does not exist, the flag may not be set at runtime, or the
|
||||
/// value is of the wrong type for the flag.
|
||||
|
@ -1101,6 +1127,7 @@ abstract class VmServiceInterface {
|
|||
/// provided value. If set to false when the profiler is already running, the
|
||||
/// profiler will be stopped but may not free its sample buffer depending on
|
||||
/// platform limitations.
|
||||
/// - Isolate pause settings will only be applied to newly spawned isolates.
|
||||
///
|
||||
/// See [Success].
|
||||
///
|
||||
|
@ -1549,11 +1576,19 @@ class VmServerConnection {
|
|||
);
|
||||
break;
|
||||
case 'setExceptionPauseMode':
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
response = await _serviceImplementation.setExceptionPauseMode(
|
||||
params!['isolateId'],
|
||||
params['mode'],
|
||||
);
|
||||
break;
|
||||
case 'setIsolatePauseMode':
|
||||
response = await _serviceImplementation.setIsolatePauseMode(
|
||||
params!['isolateId'],
|
||||
exceptionPauseMode: params['exceptionPauseMode'],
|
||||
shouldPauseOnExit: params['shouldPauseOnExit'],
|
||||
);
|
||||
break;
|
||||
case 'setFlag':
|
||||
response = await _serviceImplementation.setFlag(
|
||||
params!['name'],
|
||||
|
@ -2081,11 +2116,23 @@ class VmService implements VmServiceInterface {
|
|||
'enable': enable
|
||||
});
|
||||
|
||||
@Deprecated('Use setIsolatePauseMode instead')
|
||||
@override
|
||||
Future<Success> setExceptionPauseMode(
|
||||
String isolateId, /*ExceptionPauseMode*/ String mode) =>
|
||||
_call('setExceptionPauseMode', {'isolateId': isolateId, 'mode': mode});
|
||||
|
||||
@override
|
||||
Future<Success> setIsolatePauseMode(String isolateId,
|
||||
{/*ExceptionPauseMode*/ String? exceptionPauseMode,
|
||||
bool? shouldPauseOnExit}) =>
|
||||
_call('setIsolatePauseMode', {
|
||||
'isolateId': isolateId,
|
||||
if (exceptionPauseMode != null)
|
||||
'exceptionPauseMode': exceptionPauseMode,
|
||||
if (shouldPauseOnExit != null) 'shouldPauseOnExit': shouldPauseOnExit,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Response> setFlag(String name, String value) =>
|
||||
_call('setFlag', {'name': name, 'value': value});
|
||||
|
|
|
@ -3,7 +3,7 @@ description: >-
|
|||
A library to communicate with a service implementing the Dart VM
|
||||
service protocol.
|
||||
|
||||
version: 7.4.0
|
||||
version: 7.5.0
|
||||
|
||||
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
|
||||
|
||||
|
|
|
@ -277,7 +277,6 @@ class _ServiceTesterRunner {
|
|||
vm = await vmServiceConnectUri(serviceWebsocketAddress);
|
||||
print('Done loading VM');
|
||||
isolate = await getFirstIsolate(vm);
|
||||
print('Got first isolate');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -335,14 +334,12 @@ class _ServiceTesterRunner {
|
|||
if (event.kind == EventKind.kIsolateRunnable) {
|
||||
print(event.isolate!.name);
|
||||
vm = await service.getVM();
|
||||
//assert(vmIsolates.isNotEmpty);
|
||||
await subscription.cancel();
|
||||
await service.streamCancel(EventStreams.kIsolate);
|
||||
completer!.complete(event.isolate!);
|
||||
completer = null;
|
||||
}
|
||||
});
|
||||
|
||||
await service.streamListen(EventStreams.kIsolate);
|
||||
|
||||
// The isolate may have started before we subscribed.
|
||||
|
|
112
pkg/vm_service/test/pause_on_exceptions_legacy_test.dart
Normal file
112
pkg/vm_service/test/pause_on_exceptions_legacy_test.dart
Normal file
|
@ -0,0 +1,112 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
doThrow() {
|
||||
throw "TheException"; // Line 13.
|
||||
}
|
||||
|
||||
doCaught() {
|
||||
try {
|
||||
doThrow();
|
||||
} catch (e) {
|
||||
return "end of doCaught";
|
||||
}
|
||||
}
|
||||
|
||||
doUncaught() {
|
||||
doThrow();
|
||||
return "end of doUncaught";
|
||||
}
|
||||
|
||||
final tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolate = await service.getIsolate(isolateRef.id!);
|
||||
final lib = await service.getObject(isolateRef.id!, isolate.rootLib!.id!);
|
||||
|
||||
Completer? onPaused;
|
||||
Completer? onResume;
|
||||
|
||||
final stream = service.onDebugEvent;
|
||||
final subscription = stream.listen((Event event) {
|
||||
print("Event $event");
|
||||
if (event.kind == EventKind.kPauseException) {
|
||||
if (onPaused == null) throw "Unexpected pause event $event";
|
||||
final t = onPaused;
|
||||
onPaused = null;
|
||||
t!.complete(event);
|
||||
}
|
||||
if (event.kind == EventKind.kResume) {
|
||||
if (onResume == null) throw "Unexpected resume event $event";
|
||||
final t = onResume;
|
||||
onResume = null;
|
||||
t!.complete(event);
|
||||
}
|
||||
});
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
|
||||
test(String pauseMode, String expression, bool shouldPause,
|
||||
bool shouldBeCaught) async {
|
||||
print("Evaluating $expression with pause on $pauseMode exception");
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
await service.setExceptionPauseMode(isolate.id!, pauseMode);
|
||||
|
||||
late Completer t;
|
||||
if (shouldPause) {
|
||||
t = Completer();
|
||||
onPaused = t;
|
||||
}
|
||||
final fres = service.evaluate(isolate.id!, lib.id!, expression);
|
||||
if (shouldPause) {
|
||||
await t.future;
|
||||
|
||||
final stack = await service.getStack(isolate.id!);
|
||||
expect(stack.frames![0].function!.name, 'doThrow');
|
||||
|
||||
t = Completer();
|
||||
onResume = t;
|
||||
await service.resume(isolate.id!);
|
||||
await t.future;
|
||||
}
|
||||
|
||||
dynamic res = await fres;
|
||||
if (shouldBeCaught) {
|
||||
expect(res is InstanceRef, true);
|
||||
expect(res.kind, 'String');
|
||||
expect(res.valueAsString, equals("end of doCaught"));
|
||||
} else {
|
||||
print(res.json);
|
||||
expect(res is ErrorRef, true);
|
||||
res = await service.getObject(isolate.id!, res.id!);
|
||||
expect(res is Error, true);
|
||||
expect(res.exception.kind, 'String');
|
||||
expect(res.exception.valueAsString, equals("TheException"));
|
||||
}
|
||||
}
|
||||
|
||||
await test("All", "doCaught()", true, true);
|
||||
await test("All", "doUncaught()", true, false);
|
||||
|
||||
await test("Unhandled", "doCaught()", false, true);
|
||||
await test("Unhandled", "doUncaught()", true, false);
|
||||
|
||||
await test("None", "doCaught()", false, true);
|
||||
await test("None", "doUncaught()", false, false);
|
||||
|
||||
await subscription.cancel();
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'pause_on_exceptions_test.dart',
|
||||
);
|
112
pkg/vm_service/test/pause_on_exceptions_test.dart
Normal file
112
pkg/vm_service/test/pause_on_exceptions_test.dart
Normal file
|
@ -0,0 +1,112 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
doThrow() {
|
||||
throw "TheException"; // Line 13.
|
||||
}
|
||||
|
||||
doCaught() {
|
||||
try {
|
||||
doThrow();
|
||||
} catch (e) {
|
||||
return "end of doCaught";
|
||||
}
|
||||
}
|
||||
|
||||
doUncaught() {
|
||||
doThrow();
|
||||
return "end of doUncaught";
|
||||
}
|
||||
|
||||
final tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolate = await service.getIsolate(isolateRef.id!);
|
||||
final lib = await service.getObject(isolateRef.id!, isolate.rootLib!.id!);
|
||||
|
||||
Completer? onPaused;
|
||||
Completer? onResume;
|
||||
|
||||
final stream = service.onDebugEvent;
|
||||
final subscription = stream.listen((Event event) {
|
||||
print("Event $event");
|
||||
if (event.kind == EventKind.kPauseException) {
|
||||
if (onPaused == null) throw "Unexpected pause event $event";
|
||||
final t = onPaused;
|
||||
onPaused = null;
|
||||
t!.complete(event);
|
||||
}
|
||||
if (event.kind == EventKind.kResume) {
|
||||
if (onResume == null) throw "Unexpected resume event $event";
|
||||
final t = onResume;
|
||||
onResume = null;
|
||||
t!.complete(event);
|
||||
}
|
||||
});
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
|
||||
test(String pauseMode, String expression, bool shouldPause,
|
||||
bool shouldBeCaught) async {
|
||||
print("Evaluating $expression with pause on $pauseMode exception");
|
||||
|
||||
await service.setIsolatePauseMode(isolate.id!,
|
||||
exceptionPauseMode: pauseMode);
|
||||
|
||||
late Completer t;
|
||||
if (shouldPause) {
|
||||
t = Completer();
|
||||
onPaused = t;
|
||||
}
|
||||
final fres = service.evaluate(isolate.id!, lib.id!, expression);
|
||||
if (shouldPause) {
|
||||
await t.future;
|
||||
|
||||
final stack = await service.getStack(isolate.id!);
|
||||
expect(stack.frames![0].function!.name, 'doThrow');
|
||||
|
||||
t = Completer();
|
||||
onResume = t;
|
||||
await service.resume(isolate.id!);
|
||||
await t.future;
|
||||
}
|
||||
|
||||
dynamic res = await fres;
|
||||
if (shouldBeCaught) {
|
||||
expect(res is InstanceRef, true);
|
||||
expect(res.kind, 'String');
|
||||
expect(res.valueAsString, equals("end of doCaught"));
|
||||
} else {
|
||||
print(res.json);
|
||||
expect(res is ErrorRef, true);
|
||||
res = await service.getObject(isolate.id!, res.id!);
|
||||
expect(res is Error, true);
|
||||
expect(res.exception.kind, 'String');
|
||||
expect(res.exception.valueAsString, equals("TheException"));
|
||||
}
|
||||
}
|
||||
|
||||
await test("All", "doCaught()", true, true);
|
||||
await test("All", "doUncaught()", true, false);
|
||||
|
||||
await test("Unhandled", "doCaught()", false, true);
|
||||
await test("Unhandled", "doUncaught()", true, false);
|
||||
|
||||
await test("None", "doCaught()", false, true);
|
||||
await test("None", "doUncaught()", false, false);
|
||||
|
||||
await subscription.cancel();
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'pause_on_exceptions_test.dart',
|
||||
);
|
51
pkg/vm_service/test/should_pause_on_exit_test.dart
Normal file
51
pkg/vm_service/test/should_pause_on_exit_test.dart
Normal file
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
void testMain() {
|
||||
print('Hello world!');
|
||||
}
|
||||
|
||||
Future<bool> shouldPauseOnExit(VmService service, IsolateRef isolateRef) async {
|
||||
final isolate = await service.getIsolate(isolateRef.id!);
|
||||
return isolate.pauseOnExit!;
|
||||
}
|
||||
|
||||
final tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
await service.setIsolatePauseMode(isolateRef.id!, shouldPauseOnExit: false);
|
||||
expect(await shouldPauseOnExit(service, isolateRef), false);
|
||||
final completer = Completer<void>();
|
||||
|
||||
final stream = service.onDebugEvent;
|
||||
final subscription = stream.listen((Event event) {
|
||||
if (event.kind == EventKind.kPauseExit) {
|
||||
completer.complete();
|
||||
}
|
||||
});
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
|
||||
await service.setIsolatePauseMode(isolateRef.id!, shouldPauseOnExit: true);
|
||||
expect(await shouldPauseOnExit(service, isolateRef), true);
|
||||
await service.resume(isolateRef.id!);
|
||||
await completer.future;
|
||||
await service.resume(isolateRef.id!);
|
||||
await subscription.cancel();
|
||||
},
|
||||
];
|
||||
|
||||
void main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'should_pause_on_exit_test.dart',
|
||||
pause_on_start: true,
|
||||
pause_on_exit: true,
|
||||
testeeConcurrent: testMain,
|
||||
);
|
|
@ -167,6 +167,23 @@ abstract class Parser {
|
|||
.trim();
|
||||
}
|
||||
|
||||
String? consumeString() {
|
||||
StringBuffer buf = StringBuffer();
|
||||
String startQuotation = advance()!.text!;
|
||||
if (startQuotation != '"' && startQuotation != "'") {
|
||||
return null;
|
||||
}
|
||||
while (peek()!.text != startQuotation) {
|
||||
Token t = advance()!;
|
||||
if (t.text == null) {
|
||||
throw FormatException('Reached EOF');
|
||||
}
|
||||
buf.write('${t.text} ');
|
||||
}
|
||||
advance();
|
||||
return buf.toString().trim();
|
||||
}
|
||||
|
||||
void validate(bool result, String message) {
|
||||
if (!result) throw 'expected ${message}';
|
||||
}
|
||||
|
|
|
@ -725,6 +725,9 @@ abstract class VmServiceInterface {
|
|||
}
|
||||
return result;
|
||||
};
|
||||
if (m.deprecated) {
|
||||
gen.writeln("// ignore: deprecated_member_use_from_same_package");
|
||||
}
|
||||
gen.write("response = await _serviceImplementation.${m.name}(");
|
||||
// Positional args
|
||||
m.args.where((arg) => !arg.optional).forEach((MethodArg arg) {
|
||||
|
@ -1130,6 +1133,8 @@ class Method extends Member {
|
|||
final String? docs;
|
||||
|
||||
MemberType returnType = MemberType();
|
||||
bool get deprecated => deprecationMessage != null;
|
||||
String? deprecationMessage;
|
||||
List<MethodArg> args = [];
|
||||
|
||||
Method(this.name, String definition, [this.docs]) {
|
||||
|
@ -1196,6 +1201,9 @@ class Method extends Member {
|
|||
}
|
||||
if (_docs.isNotEmpty) gen.writeDocs(_docs);
|
||||
}
|
||||
if (deprecated) {
|
||||
gen.writeln("@Deprecated('$deprecationMessage')");
|
||||
}
|
||||
if (withOverrides) gen.writeln('@override');
|
||||
gen.write('Future<${returnType.name}> ${name}(');
|
||||
bool startedOptional = false;
|
||||
|
@ -2128,7 +2136,12 @@ class MethodParser extends Parser {
|
|||
void parseInto(Method method) {
|
||||
// method is return type, name, (, args )
|
||||
// args is type name, [optional], comma
|
||||
|
||||
if (peek()?.text?.startsWith('@deprecated') ?? false) {
|
||||
advance();
|
||||
expect('(');
|
||||
method.deprecationMessage = consumeString()!;
|
||||
expect(')');
|
||||
}
|
||||
method.returnType.parse(this, isReturnType: true);
|
||||
|
||||
Token t = expectName();
|
||||
|
|
|
@ -496,6 +496,7 @@ class Method extends Member {
|
|||
final String? docs;
|
||||
|
||||
MemberType returnType = MemberType();
|
||||
bool deprecated = false;
|
||||
List<MethodArg> args = [];
|
||||
|
||||
Method(this.name, String definition, [this.docs]) {
|
||||
|
@ -606,7 +607,7 @@ class Method extends Member {
|
|||
}
|
||||
}
|
||||
writer.addLine('request("$name", params, consumer);');
|
||||
}, javadoc: javadoc.toString());
|
||||
}, javadoc: javadoc.toString(), isDeprecated: deprecated);
|
||||
}
|
||||
|
||||
void _parse(Token? token) {
|
||||
|
@ -647,6 +648,13 @@ class MethodParser extends Parser {
|
|||
// method is return type, name, (, args )
|
||||
// args is type name, [optional], comma
|
||||
|
||||
if (peek()?.text?.startsWith('@deprecated') ?? false) {
|
||||
advance();
|
||||
expect('(');
|
||||
consumeString();
|
||||
expect(')');
|
||||
method.deprecated = true;
|
||||
}
|
||||
method.returnType.parse(this);
|
||||
|
||||
Token t = expectName();
|
||||
|
|
|
@ -214,6 +214,7 @@ class TypeWriter {
|
|||
String? modifiers = 'public',
|
||||
String? returnType = 'void',
|
||||
bool isOverride = false,
|
||||
bool isDeprecated = false,
|
||||
}) {
|
||||
var methodDecl = StringBuffer();
|
||||
if (javadoc != null && javadoc.isNotEmpty) {
|
||||
|
@ -223,6 +224,9 @@ class TypeWriter {
|
|||
.forEach((line) => methodDecl.writeln(' * $line'.trimRight()));
|
||||
methodDecl.writeln(' */');
|
||||
}
|
||||
if (isDeprecated) {
|
||||
methodDecl.writeln(' @Deprecated');
|
||||
}
|
||||
if (isOverride) {
|
||||
methodDecl.writeln(' @Override');
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ var tests = <VMTest>[
|
|||
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
|
||||
expect(result['type'], 'Version');
|
||||
expect(result['major'], 3);
|
||||
expect(result['minor'], 52);
|
||||
expect(result['minor'], 53);
|
||||
expect(result['_privateMajor'], 0);
|
||||
expect(result['_privateMinor'], 0);
|
||||
},
|
||||
|
|
|
@ -12,7 +12,7 @@ var tests = <VMTest>[
|
|||
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
|
||||
expect(result['type'], equals('Version'));
|
||||
expect(result['major'], equals(3));
|
||||
expect(result['minor'], equals(52));
|
||||
expect(result['minor'], equals(53));
|
||||
expect(result['_privateMajor'], equals(0));
|
||||
expect(result['_privateMinor'], equals(0));
|
||||
},
|
||||
|
|
|
@ -5164,6 +5164,44 @@ static void SetExceptionPauseMode(Thread* thread, JSONStream* js) {
|
|||
PrintSuccess(js);
|
||||
}
|
||||
|
||||
static const MethodParameter* const set_isolate_pause_mode_params[] = {
|
||||
ISOLATE_PARAMETER,
|
||||
new EnumParameter("exceptionPauseMode", false, exception_pause_mode_names),
|
||||
new BoolParameter("shouldPauseOnExit", false),
|
||||
nullptr,
|
||||
};
|
||||
|
||||
static void SetIsolatePauseMode(Thread* thread, JSONStream* js) {
|
||||
bool state_changed = false;
|
||||
const char* exception_pause_mode = js->LookupParam("exceptionPauseMode");
|
||||
if (exception_pause_mode != nullptr) {
|
||||
Dart_ExceptionPauseInfo info =
|
||||
EnumMapper(exception_pause_mode, exception_pause_mode_names,
|
||||
exception_pause_mode_values);
|
||||
if (info == kInvalidExceptionPauseInfo) {
|
||||
PrintInvalidParamError(js, "exceptionPauseMode");
|
||||
return;
|
||||
}
|
||||
Isolate* isolate = thread->isolate();
|
||||
isolate->debugger()->SetExceptionPauseInfo(info);
|
||||
state_changed = true;
|
||||
}
|
||||
|
||||
const char* pause_isolate_on_exit = js->LookupParam("shouldPauseOnExit");
|
||||
if (pause_isolate_on_exit != nullptr) {
|
||||
bool enable = BoolParameter::Parse(pause_isolate_on_exit, false);
|
||||
thread->isolate()->message_handler()->set_should_pause_on_exit(enable);
|
||||
state_changed = true;
|
||||
}
|
||||
|
||||
if (state_changed && Service::debug_stream.enabled()) {
|
||||
ServiceEvent event(thread->isolate(),
|
||||
ServiceEvent::kDebuggerSettingsUpdate);
|
||||
Service::HandleEvent(&event);
|
||||
}
|
||||
PrintSuccess(js);
|
||||
}
|
||||
|
||||
static const MethodParameter* const set_breakpoint_state_params[] = {
|
||||
ISOLATE_PARAMETER,
|
||||
new IdParameter("breakpointId", true),
|
||||
|
@ -5580,6 +5618,8 @@ static const ServiceMethodDescriptor service_methods_[] = {
|
|||
set_breakpoint_state_params },
|
||||
{ "setExceptionPauseMode", SetExceptionPauseMode,
|
||||
set_exception_pause_mode_params },
|
||||
{ "setIsolatePauseMode", SetIsolatePauseMode,
|
||||
set_isolate_pause_mode_params },
|
||||
{ "setFlag", SetFlag,
|
||||
set_flags_params },
|
||||
{ "setLibraryDebuggable", SetLibraryDebuggable,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace dart {
|
||||
|
||||
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
|
||||
#define SERVICE_PROTOCOL_MINOR_VERSION 52
|
||||
#define SERVICE_PROTOCOL_MINOR_VERSION 53
|
||||
|
||||
class Array;
|
||||
class EmbedderServiceHandler;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Dart VM Service Protocol 3.52
|
||||
# Dart VM Service Protocol 3.53
|
||||
|
||||
> Please post feedback to the [observatory-discuss group][discuss-list]
|
||||
|
||||
This document describes of _version 3.52_ of the Dart VM Service Protocol. This
|
||||
This document describes of _version 3.53_ of the Dart VM Service Protocol. This
|
||||
protocol is used to communicate with a running Dart Virtual Machine.
|
||||
|
||||
To use the Service Protocol, start the VM with the *--observe* flag.
|
||||
|
@ -1378,6 +1378,7 @@ See [Breakpoint](#breakpoint).
|
|||
### setExceptionPauseMode
|
||||
|
||||
```
|
||||
@deprecated('Use setIsolatePauseMode instead')
|
||||
Success|Sentinel setExceptionPauseMode(string isolateId,
|
||||
ExceptionPauseMode mode)
|
||||
```
|
||||
|
@ -1394,6 +1395,31 @@ All | Pause isolate on all thrown exceptions
|
|||
If _isolateId_ refers to an isolate which has exited, then the
|
||||
_Collected_ [Sentinel](#sentinel) is returned.
|
||||
|
||||
### setIsolatePauseMode
|
||||
|
||||
```
|
||||
Success|Sentinel setIsolatePauseMode(string isolateId,
|
||||
ExceptionPauseMode exceptionPauseMode [optional],
|
||||
bool shouldPauseOnExit [optional])
|
||||
```
|
||||
|
||||
The _setIsolatePauseMode_ RPC is used to control if or when an isolate will
|
||||
pause due to a change in execution state.
|
||||
|
||||
The _shouldPauseOnExit_ parameter specify whether the target isolate should pause on exit.
|
||||
|
||||
The _setExceptionPauseMode_ RPC is used to control if an isolate pauses when
|
||||
an exception is thrown.
|
||||
|
||||
mode | meaning
|
||||
---- | -------
|
||||
None | Do not pause isolate on thrown exceptions
|
||||
Unhandled | Pause isolate on unhandled exceptions
|
||||
All | Pause isolate on all thrown exceptions
|
||||
|
||||
If _isolateId_ refers to an isolate which has exited, then the
|
||||
_Collected_ [Sentinel](#sentinel) is returned.
|
||||
|
||||
### setFlag
|
||||
|
||||
```
|
||||
|
@ -1420,6 +1446,7 @@ Notes:
|
|||
provided value. If set to false when the profiler is already running, the
|
||||
profiler will be stopped but may not free its sample buffer depending on
|
||||
platform limitations.
|
||||
* Isolate pause settings will only be applied to newly spawned isolates.
|
||||
|
||||
See [Success](#success).
|
||||
|
||||
|
@ -4235,4 +4262,5 @@ version | comments
|
|||
3.50 | Added `returnType`, `parameters`, and `typeParameters` to `@Instance`, and `implicit` to `@Function`. Added `Parameter` type.
|
||||
3.51 | Added optional `reportLines` parameter to `getSourceReport` RPC.
|
||||
3.52 | Added `lookupResolvedPackageUris` and `lookupPackageUris` RPCs and `UriList` type.
|
||||
3.53 | Added `setIsolatePauseMode` RPC.
|
||||
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
|
||||
|
|
Loading…
Reference in a new issue