Revert "[3.0 alpha][VM/Service] Update VM Service spec to v4.0"

This reverts commit c21f7c847c.

Reason for revert: Appears to cause issues when flutter app is launched with VSCode or Android Studio, please see https://github.com/flutter/flutter/issues/117526

Original change's description:
> [3.0 alpha][VM/Service] Update VM Service spec to v4.0
>
> This CL updates the VM Service spec to version 4.0 in order to add
> support for records. Some deprecated procedures and properties will also
> be removed in v4.0.
>
> As described in service.md's changelog, this CL:
> Adds `Record` and `RecordType` `InstanceKind`s, adds a deprecation
> notice to the `decl` property of `BoundField`, adds `name` property to
> `BoundField`, adds a deprecation notice to the `parentListIndex`
> property of `InboundReference`, changes the type of the `parentField`
> property of `InboundReference` from `@Field` to `@Field|string|int`,
> adds a deprecation notice to the `parentListIndex` property of
> `RetainingObject`, changes the type of the `parentField` property of
> `RetainingObject` from `string` to `string|int`, removes the deprecated
> `setExceptionPauseMode` procedure, removes the deprecated `timeSpan`
> property from `CpuSamples`, and removes the deprecated `timeSpan`
> property from `CpuSamplesEvent.
>
> TEST=CI
>
> Issue: https://github.com/dart-lang/sdk/issues/49725
> Change-Id: I7bf61c1ba11a0c7fd95a10c9c02c14282062b802
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268521
> Commit-Queue: Derek Xu <derekx@google.com>
> Reviewed-by: Ben Konyi <bkonyi@google.com>

# Not skipping CQ checks because original CL landed > 1 day ago.

Issue: https://github.com/dart-lang/sdk/issues/49725
Change-Id: Ieb2a09653192e165ea8cf68965647e346e3a318b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/277181
Reviewed-by: Derek Xu <derekx@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Auto-Submit: Siva Annamalai <asiva@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
Siva Annamalai 2022-12-22 20:19:00 +00:00 committed by Commit Queue
parent 59ec6a3d46
commit dcaf392d34
20 changed files with 295 additions and 133 deletions

View file

@ -200,6 +200,7 @@ class CachedCpuSamples extends CpuSamples {
required int? samplePeriod,
required int? maxStackDepth,
required int? sampleCount,
required int? timeSpan,
required int? timeOriginMicros,
required int? timeExtentMicros,
required int? pid,
@ -209,6 +210,7 @@ class CachedCpuSamples extends CpuSamples {
samplePeriod: samplePeriod,
maxStackDepth: maxStackDepth,
sampleCount: sampleCount,
timeSpan: timeSpan,
timeOriginMicros: timeOriginMicros,
timeExtentMicros: timeExtentMicros,
pid: pid,
@ -223,6 +225,7 @@ class CachedCpuSamples extends CpuSamples {
samplePeriod: json['samplePeriod'] ?? -1,
maxStackDepth: json['maxStackDepth'] ?? -1,
sampleCount: json['sampleCount'] ?? -1,
timeSpan: json['timeSpan'] ?? -1,
timeOriginMicros: json['timeOriginMicros'] ?? -1,
timeExtentMicros: json['timeExtentMicros'] ?? -1,
pid: json['pid'] ?? -1,

View file

@ -34,6 +34,7 @@ src/org/dartlang/vm/service/consumer/ReloadSourcesConsumer.java
src/org/dartlang/vm/service/consumer/RemoveBreakpointConsumer.java
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

View file

@ -587,17 +587,17 @@ public class VmServiceTest {
private static void vmPauseOnException(IsolateRef isolate, ExceptionPauseMode mode) {
System.out.println("Request pause on exception: " + mode);
final OpLatch latch = new OpLatch();
vmService.setIsolatePauseMode(isolate.getId(), mode, new SuccessConsumer() {
@Override
public void onError(RPCError error) {
showRPCError(error);
}
vmService.setExceptionPauseMode(isolate.getId(), mode, new SuccessConsumer() {
@Override
public void onError(RPCError error) {
showRPCError(error);
}
@Override
public void received(Success response) {
System.out.println("Successfully set pause on exception");
latch.opComplete();
}
@Override
public void received(Success response) {
System.out.println("Successfully set pause on exception");
latch.opComplete();
}
});
latch.waitAndAssertOpComplete();
}

View file

@ -1 +1 @@
version=4.0
version=3.62

View file

@ -26,7 +26,7 @@ export 'snapshot_graph.dart'
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
const String vmServiceVersion = '4.0.0';
const String vmServiceVersion = '3.62.0';
/// @optional
const String optional = 'optional';
@ -236,6 +236,7 @@ Map<String, List<String>> _methodReturnTypes = {
'requestHeapSnapshot': const ['Success'],
'resume': const ['Success'],
'setBreakpointState': const ['Breakpoint'],
'setExceptionPauseMode': const ['Success'],
'setIsolatePauseMode': const ['Success'],
'setFlag': const ['Success', 'Error'],
'setLibraryDebuggable': const ['Success'],
@ -1076,12 +1077,33 @@ abstract class VmServiceInterface {
Future<Breakpoint> setBreakpointState(
String isolateId, String breakpointId, bool enable);
/// 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.
@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
@ -1576,6 +1598,13 @@ class VmServerConnection {
params['enable'],
);
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'],
@ -2120,6 +2149,12 @@ 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,
@ -2682,9 +2717,6 @@ class InstanceKind {
static const String kFloat32x4List = 'Float32x4List';
static const String kFloat64x2List = 'Float64x2List';
/// An instance of the Dart class Record.
static const String kRecord = 'Record';
/// An instance of the Dart class StackTrace.
static const String kStackTrace = 'StackTrace';
@ -2716,9 +2748,6 @@ class InstanceKind {
/// An instance of the Dart class FunctionType.
static const String kFunctionType = 'FunctionType';
/// An instance of the Dart class RecordType.
static const String kRecordType = 'RecordType';
/// An instance of the Dart class BoundedType.
static const String kBoundedType = 'BoundedType';
@ -2878,29 +2907,18 @@ class BoundField {
static BoundField? parse(Map<String, dynamic>? json) =>
json == null ? null : BoundField._fromJson(json);
/// Provided for fields of instances that are NOT of the following instance
/// kinds:
/// - Record
///
/// Note: this property is deprecated and will be replaced by `name`.
FieldRef? decl;
/// [name] can be one of [String] or [int].
dynamic name;
/// [value] can be one of [InstanceRef] or [Sentinel].
dynamic value;
BoundField({
this.decl,
this.name,
this.value,
});
BoundField._fromJson(Map<String, dynamic> json) {
decl = createServiceObject(json['decl'], const ['FieldRef']) as FieldRef?;
name =
createServiceObject(json['name'], const ['String', 'int']) as dynamic;
value =
createServiceObject(json['value'], const ['InstanceRef', 'Sentinel'])
as dynamic;
@ -2910,14 +2928,12 @@ class BoundField {
final json = <String, dynamic>{};
json.addAll({
'decl': decl?.toJson(),
'name': name?.toJson(),
'value': value?.toJson(),
});
return json;
}
String toString() =>
'[BoundField decl: ${decl}, name: ${name}, value: ${value}]';
String toString() => '[BoundField decl: ${decl}, value: ${value}]';
}
/// A `BoundVariable` represents a local variable bound to a particular value in
@ -3610,6 +3626,13 @@ class CpuSamples extends Response {
/// The number of samples returned.
int? sampleCount;
/// The timespan the set of returned samples covers, in microseconds
/// (deprecated).
///
/// Note: this property is deprecated and will always return -1. Use
/// `timeExtentMicros` instead.
int? timeSpan;
/// The start of the period of time in which the returned samples were
/// collected.
int? timeOriginMicros;
@ -3633,6 +3656,7 @@ class CpuSamples extends Response {
this.samplePeriod,
this.maxStackDepth,
this.sampleCount,
this.timeSpan,
this.timeOriginMicros,
this.timeExtentMicros,
this.pid,
@ -3644,6 +3668,7 @@ class CpuSamples extends Response {
samplePeriod = json['samplePeriod'] ?? -1;
maxStackDepth = json['maxStackDepth'] ?? -1;
sampleCount = json['sampleCount'] ?? -1;
timeSpan = json['timeSpan'] ?? -1;
timeOriginMicros = json['timeOriginMicros'] ?? -1;
timeExtentMicros = json['timeExtentMicros'] ?? -1;
pid = json['pid'] ?? -1;
@ -3667,6 +3692,7 @@ class CpuSamples extends Response {
'samplePeriod': samplePeriod ?? -1,
'maxStackDepth': maxStackDepth ?? -1,
'sampleCount': sampleCount ?? -1,
'timeSpan': timeSpan ?? -1,
'timeOriginMicros': timeOriginMicros ?? -1,
'timeExtentMicros': timeExtentMicros ?? -1,
'pid': pid ?? -1,
@ -3676,9 +3702,7 @@ class CpuSamples extends Response {
return json;
}
String toString() => '[CpuSamples ' //
'samplePeriod: ${samplePeriod}, maxStackDepth: ${maxStackDepth}, ' //
'sampleCount: ${sampleCount}, timeOriginMicros: ${timeOriginMicros}, timeExtentMicros: ${timeExtentMicros}, pid: ${pid}, functions: ${functions}, samples: ${samples}]';
String toString() => '[CpuSamples]';
}
class CpuSamplesEvent {
@ -3694,6 +3718,13 @@ class CpuSamplesEvent {
/// The number of samples returned.
int? sampleCount;
/// The timespan the set of returned samples covers, in microseconds
/// (deprecated).
///
/// Note: this property is deprecated and will always return -1. Use
/// `timeExtentMicros` instead.
int? timeSpan;
/// The start of the period of time in which the returned samples were
/// collected.
int? timeOriginMicros;
@ -3717,6 +3748,7 @@ class CpuSamplesEvent {
this.samplePeriod,
this.maxStackDepth,
this.sampleCount,
this.timeSpan,
this.timeOriginMicros,
this.timeExtentMicros,
this.pid,
@ -3728,6 +3760,7 @@ class CpuSamplesEvent {
samplePeriod = json['samplePeriod'] ?? -1;
maxStackDepth = json['maxStackDepth'] ?? -1;
sampleCount = json['sampleCount'] ?? -1;
timeSpan = json['timeSpan'] ?? -1;
timeOriginMicros = json['timeOriginMicros'] ?? -1;
timeExtentMicros = json['timeExtentMicros'] ?? -1;
pid = json['pid'] ?? -1;
@ -3745,6 +3778,7 @@ class CpuSamplesEvent {
'samplePeriod': samplePeriod ?? -1,
'maxStackDepth': maxStackDepth ?? -1,
'sampleCount': sampleCount ?? -1,
'timeSpan': timeSpan ?? -1,
'timeOriginMicros': timeOriginMicros ?? -1,
'timeExtentMicros': timeExtentMicros ?? -1,
'pid': pid ?? -1,
@ -3754,9 +3788,7 @@ class CpuSamplesEvent {
return json;
}
String toString() => '[CpuSamplesEvent ' //
'samplePeriod: ${samplePeriod}, maxStackDepth: ${maxStackDepth}, ' //
'sampleCount: ${sampleCount}, timeOriginMicros: ${timeOriginMicros}, timeExtentMicros: ${timeExtentMicros}, pid: ${pid}, functions: ${functions}, samples: ${samples}]';
String toString() => '[CpuSamplesEvent]';
}
/// See [getCpuSamples] and [CpuSamples].
@ -5991,24 +6023,15 @@ class InboundReference {
/// The object holding the inbound reference.
ObjRef? source;
/// If source is a List, parentListIndex is the index of the inbound reference
/// (deprecated).
///
/// Note: this property is deprecated and will be replaced by `parentField`.
/// If source is a List, parentListIndex is the index of the inbound
/// reference.
@optional
int? parentListIndex;
/// If `source` is a `List`, `parentField` is the index of the inbound
/// reference. If `source` is a record, `parentField` is the field name of the
/// inbound reference. If `source` is an instance of any other kind,
/// `parentField` is the field containing the inbound reference.
///
/// Note: In v5.0 of the spec, `@Field` will no longer be a part of this
/// property's type, i.e. the type will become `string|int`.
///
/// [parentField] can be one of [FieldRef], [String] or [int].
/// If source is a field of an object, parentField is the field containing the
/// inbound reference.
@optional
dynamic parentField;
FieldRef? parentField;
InboundReference({
this.source,
@ -6019,8 +6042,8 @@ class InboundReference {
InboundReference._fromJson(Map<String, dynamic> json) {
source = createServiceObject(json['source'], const ['ObjRef']) as ObjRef?;
parentListIndex = json['parentListIndex'];
parentField = createServiceObject(
json['parentField'], const ['FieldRef', 'String', 'int']) as dynamic;
parentField = createServiceObject(json['parentField'], const ['FieldRef'])
as FieldRef?;
}
Map<String, dynamic> toJson() {
@ -7118,9 +7141,7 @@ class RetainingObject {
ObjRef? value;
/// If `value` is a List, `parentListIndex` is the index where the previous
/// object on the retaining path is located (deprecated).
///
/// Note: this property is deprecated and will be replaced by `parentField`.
/// object on the retaining path is located.
@optional
int? parentListIndex;
@ -7131,10 +7152,8 @@ class RetainingObject {
/// If `value` is a non-List, non-Map object, `parentField` is the name of the
/// field containing the previous object on the retaining path.
///
/// [parentField] can be one of [String] or [int].
@optional
dynamic parentField;
String? parentField;
RetainingObject({
this.value,
@ -7148,9 +7167,7 @@ class RetainingObject {
parentListIndex = json['parentListIndex'];
parentMapKey =
createServiceObject(json['parentMapKey'], const ['ObjRef']) as ObjRef?;
parentField =
createServiceObject(json['parentField'], const ['String', 'int'])
as dynamic;
parentField = json['parentField'];
}
Map<String, dynamic> toJson() {
@ -7160,7 +7177,7 @@ class RetainingObject {
});
_setIfNotNull(json, 'parentListIndex', parentListIndex);
_setIfNotNull(json, 'parentMapKey', parentMapKey?.toJson());
_setIfNotNull(json, 'parentField', parentField?.toJson());
_setIfNotNull(json, 'parentField', parentField);
return json;
}

View file

@ -7,7 +7,6 @@
library get_object_rpc_test;
import 'dart:collection';
import 'dart:convert' show base64Decode;
import 'dart:typed_data';
@ -694,23 +693,19 @@ var tests = <IsolateTest>[
as InstanceRef;
final objectId = evalResult.id!;
final result = await service.getObject(isolateId, objectId) as Instance;
expect(result.kind, InstanceKind.kRecord);
expect(result.kind, '_Record');
expect(result.json!['_vmType'], 'Record');
expect(result.id, startsWith('objects/'));
expect(result.valueAsString, isNull);
expect(result.classRef!.name, '_Record');
expect(result.size, isPositive);
final fieldsMap = HashMap.fromEntries(
result.fields!.map((f) => MapEntry(f.name, f.value)));
expect(fieldsMap.keys.length, 4);
expect(fieldsMap.containsKey(0), true);
expect(fieldsMap[0].valueAsString, '1');
expect(fieldsMap.containsKey("x"), true);
expect(fieldsMap["x"].valueAsString, '2');
expect(fieldsMap.containsKey(1), true);
expect(fieldsMap[1].valueAsString, '3.0');
expect(fieldsMap.containsKey("y"), true);
expect(fieldsMap["y"].valueAsString, '4.0');
final fields = result.fields!;
expect(fields.length, 4);
// TODO(derekx): Include field names in this test once they are accessible
// through package:vm_service.
Set<String> fieldValues =
Set.from(fields.map((f) => f.value.valueAsString));
expect(fieldValues.containsAll(['1', '2', '3.0', '4.0']), true);
},
// library.

View 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',
);

View file

@ -637,7 +637,7 @@ class SetCommand extends DebuggerCommand {
};
static Future _setBreakOnException(debugger, name, value) async {
var result = await debugger.isolate.setIsolatePauseMode(value);
var result = await debugger.isolate.setExceptionPauseMode(value);
if (result.isError) {
debugger.console.print(result.toString());
} else {

View file

@ -1886,8 +1886,8 @@ class Isolate extends ServiceObjectOwner implements M.Isolate {
return invokeRpc('setName', {'name': newName});
}
Future setIsolatePauseMode(String mode) {
return invokeRpc('setIsolatePauseMode', {'exceptionPauseMode': mode});
Future setExceptionPauseMode(String mode) {
return invokeRpc('setExceptionPauseMode', {'mode': mode});
}
Future<ServiceMap> getStack({int? limit}) {

View file

@ -11,8 +11,8 @@ var tests = <VMTest>[
(VM vm) async {
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], 'Version');
expect(result['major'], 4);
expect(result['minor'], 0);
expect(result['major'], 3);
expect(result['minor'], 62);
expect(result['_privateMajor'], 0);
expect(result['_privateMinor'], 0);
},

View file

@ -52,8 +52,8 @@ var tests = <IsolateTest>[
bool shouldBeCaught) async {
print("Evaluating $expression with pause on $pauseMode exception");
expect(
(await isolate.setIsolatePauseMode(pauseMode)) is DartError, isFalse);
expect((await isolate.setExceptionPauseMode(pauseMode)) is DartError,
isFalse);
var t;
if (shouldPause) {

View file

@ -632,7 +632,7 @@ class SetCommand extends DebuggerCommand {
};
static Future _setBreakOnException(debugger, name, value) async {
var result = await debugger.isolate.setIsolatePauseMode(value);
var result = await debugger.isolate.setExceptionPauseMode(value);
if (result.isError) {
debugger.console.print(result.toString());
} else {

View file

@ -1894,8 +1894,8 @@ class Isolate extends ServiceObjectOwner implements M.Isolate {
return invokeRpc('setName', {'name': newName});
}
Future setIsolatePauseMode(String mode) {
return invokeRpc('setIsolatePauseMode', {'exceptionPauseMode': mode});
Future setExceptionPauseMode(String mode) {
return invokeRpc('setExceptionPauseMode', {'mode': mode});
}
Future<ServiceMap> getStack({int limit}) {

View file

@ -11,8 +11,8 @@ var tests = <VMTest>[
(VM vm) async {
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(4));
expect(result['minor'], equals(0));
expect(result['major'], equals(3));
expect(result['minor'], equals(62));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},

View file

@ -52,8 +52,8 @@ var tests = <IsolateTest>[
bool shouldBeCaught) async {
print("Evaluating $expression with pause on $pauseMode exception");
expect(
(await isolate.setIsolatePauseMode(pauseMode)) is DartError, isFalse);
expect((await isolate.setExceptionPauseMode(pauseMode)) is DartError,
isFalse);
var t;
if (shouldPause) {

View file

@ -1124,8 +1124,8 @@ void Instance::PrintSharedInstanceJSON(JSONObject* jsobj,
if (!field.is_static()) {
field_value = GetField(field);
JSONObject jsfield(&jsarr);
jsfield.AddProperty("type", "BoundField");
jsfield.AddProperty("decl", field);
jsfield.AddProperty("name", field.UserVisibleNameCString());
jsfield.AddProperty("value", field_value);
}
}
@ -1219,7 +1219,7 @@ void FunctionType::PrintJSONImpl(JSONStream* stream, bool ref) const {
void RecordType::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
jsobj.AddProperty("kind", "RecordType");
jsobj.AddProperty("kind", "_RecordType");
if (ref) {
return;
}
@ -1630,7 +1630,7 @@ void Closure::PrintJSONImpl(JSONStream* stream, bool ref) const {
void Record::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
jsobj.AddProperty("kind", "Record");
jsobj.AddProperty("kind", "_Record");
if (ref) {
return;
}

View file

@ -1559,6 +1559,9 @@ void Profile::PrintHeaderJSON(JSONObject* obj) {
obj->AddProperty("maxStackDepth",
static_cast<intptr_t>(FLAG_max_profile_depth));
obj->AddProperty("sampleCount", sample_count());
// TODO(bkonyi): remove timeSpan after next major revision.
ASSERT(SERVICE_PROTOCOL_MAJOR_VERSION == 3);
obj->AddProperty64("timeSpan", -1);
obj->AddPropertyTimeMicros("timeOriginMicros", min_time());
obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan());
obj->AddProperty64("pid", pid);

View file

@ -2321,7 +2321,6 @@ static void PrintInboundReferences(Thread* thread,
(slot_offset.Value() - Array::element_offset(0)) /
Array::kBytesPerElement;
jselement.AddProperty("parentListIndex", element_index);
jselement.AddProperty("parentField", element_index);
} else if (source.IsRecord()) {
AddParentFieldToResponseBasedOnRecord(thread, &field_names, &name,
jselement, Record::Cast(source),
@ -2352,7 +2351,6 @@ static void PrintInboundReferences(Thread* thread,
(slot_offset.Value() - Context::variable_offset(0)) /
Context::kBytesPerElement;
jselement.AddProperty("parentListIndex", element_index);
jselement.AddProperty("parentField", element_index);
} else {
jselement.AddProperty("_parentWordOffset", slot_offset.Value());
}
@ -2447,7 +2445,6 @@ static void PrintRetainingPath(Thread* thread,
(slot_offset.Value() - Array::element_offset(0)) /
Array::kBytesPerElement;
jselement.AddProperty("parentListIndex", element_index);
jselement.AddProperty("parentField", element_index);
} else if (element.IsRecord()) {
AddParentFieldToResponseBasedOnRecord(thread, &field_names, &name,
jselement, Record::Cast(element),
@ -2494,7 +2491,6 @@ static void PrintRetainingPath(Thread* thread,
(slot_offset.Value() - Context::variable_offset(0)) /
Context::kBytesPerElement;
jselement.AddProperty("parentListIndex", element_index);
jselement.AddProperty("parentField", element_index);
} else {
jselement.AddProperty("_parentWordOffset", slot_offset.Value());
}
@ -5419,6 +5415,27 @@ static const MethodParameter* const set_exception_pause_mode_params[] = {
NULL,
};
static void SetExceptionPauseMode(Thread* thread, JSONStream* js) {
const char* mode = js->LookupParam("mode");
if (mode == NULL) {
PrintMissingParamError(js, "mode");
return;
}
Dart_ExceptionPauseInfo info =
EnumMapper(mode, exception_pause_mode_names, exception_pause_mode_values);
if (info == kInvalidExceptionPauseInfo) {
PrintInvalidParamError(js, "mode");
return;
}
Isolate* isolate = thread->isolate();
isolate->debugger()->SetExceptionPauseInfo(info);
if (Service::debug_stream.enabled()) {
ServiceEvent event(isolate, ServiceEvent::kDebuggerSettingsUpdate);
Service::HandleEvent(&event);
}
PrintSuccess(js);
}
static const MethodParameter* const set_isolate_pause_mode_params[] = {
ISOLATE_PARAMETER,
new EnumParameter("exceptionPauseMode", false, exception_pause_mode_names),
@ -5872,6 +5889,8 @@ static const ServiceMethodDescriptor service_methods_[] = {
evaluate_compiled_expression_params },
{ "setBreakpointState", SetBreakpointState,
set_breakpoint_state_params },
{ "setExceptionPauseMode", SetExceptionPauseMode,
set_exception_pause_mode_params },
{ "setIsolatePauseMode", SetIsolatePauseMode,
set_isolate_pause_mode_params },
{ "setFlag", SetFlag,

View file

@ -16,8 +16,8 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 4
#define SERVICE_PROTOCOL_MINOR_VERSION 0
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
#define SERVICE_PROTOCOL_MINOR_VERSION 62
class Array;
class EmbedderServiceHandler;

View file

@ -1,8 +1,8 @@
# Dart VM Service Protocol 4.0
# Dart VM Service Protocol 3.62
> Please post feedback to the [observatory-discuss group][discuss-list]
This document describes of _version 4.0_ of the Dart VM Service Protocol. This
This document describes of _version 3.62_ 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.
@ -71,6 +71,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
- [removeBreakpoint](#removebreakpoint)
- [resume](#resume)
- [setBreakpointState](#setbreakpointstate)
- [setExceptionPauseMode](#setexceptionpausemode)
- [setFlag](#setflag)
- [setLibraryDebuggable](#setlibrarydebuggable)
- [setName](#setname)
@ -120,7 +121,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
- [NativeFunction](#nativefunction)
- [Null](#null)
- [Object](#object)
- [Parameter](#parameter)
- [Parameter](#parameter)[
- [PortList](#portlist)
- [ReloadReport](#reloadreport)
- [Response](#response)
@ -143,7 +144,7 @@ The Service Protocol uses [JSON-RPC 2.0][].
- [TimelineFlags](#timelineflags)
- [Timestamp](#timestamp)
- [TypeArguments](#typearguments)
- [TypeParameters](#typeparameters)
- [TypeParameters](#typeparameters)[
- [UnresolvedSourceLocation](#unresolvedsourcelocation)
- [UriList](#urilist)
- [Version](#version)
@ -1383,6 +1384,25 @@ The returned [Breakpoint](#breakpoint) is the updated breakpoint with its new
values.
See [Breakpoint](#breakpoint).
### setExceptionPauseMode
```
@deprecated('Use setIsolatePauseMode instead')
Success|Sentinel setExceptionPauseMode(string isolateId,
ExceptionPauseMode mode)
```
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.
### setIsolatePauseMode
@ -1397,6 +1417,9 @@ 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
@ -1685,12 +1708,7 @@ class AllocationProfile extends Response {
```
class BoundField {
// Provided for fields of instances that are NOT of the following instance kinds:
// Record
//
// Note: this property is deprecated and will be replaced by `name`.
@Field decl;
string|int name;
@Instance|Sentinel value;
}
```
@ -1962,6 +1980,12 @@ class CpuSamples extends Response {
// The number of samples returned.
int sampleCount;
// The timespan the set of returned samples covers, in microseconds (deprecated).
//
// Note: this property is deprecated and will always return -1. Use `timeExtentMicros`
// instead.
int timeSpan;
// The start of the period of time in which the returned samples were
// collected.
int timeOriginMicros;
@ -1998,6 +2022,12 @@ class CpuSamplesEvent {
// The number of samples returned.
int sampleCount;
// The timespan the set of returned samples covers, in microseconds (deprecated).
//
// Note: this property is deprecated and will always return -1. Use `timeExtentMicros`
// instead.
int timeSpan;
// The start of the period of time in which the returned samples were
// collected.
int timeOriginMicros;
@ -3103,9 +3133,6 @@ enum InstanceKind {
Float32x4List,
Float64x2List,
// An instance of the Dart class Record.
Record,
// An instance of the Dart class StackTrace.
StackTrace,
@ -3137,9 +3164,6 @@ enum InstanceKind {
// An instance of the Dart class FunctionType.
FunctionType,
// An instance of the Dart class RecordType.
RecordType,
// An instance of the Dart class BoundedType.
BoundedType,
@ -3320,21 +3344,12 @@ class InboundReference {
// The object holding the inbound reference.
@Object source;
// If source is a List, parentListIndex is the index of the inbound reference (deprecated).
//
// Note: this property is deprecated and will be replaced by `parentField`.
// If source is a List, parentListIndex is the index of the inbound reference.
int parentListIndex [optional];
// If `source` is a `List`, `parentField` is the index of the inbound
// reference.
// If `source` is a record, `parentField` is the field name of the inbound
// reference.
// If `source` is an instance of any other kind, `parentField` is the field
// containing the inbound reference.
//
// Note: In v5.0 of the spec, `@Field` will no longer be a part of this
// property's type, i.e. the type will become `string|int`.
@Field|string|int parentField [optional];
// If source is a field of an object, parentField is the field containing the
// inbound reference.
@Field parentField [optional];
}
```
@ -3746,9 +3761,7 @@ class RetainingObject {
@Object value;
// If `value` is a List, `parentListIndex` is the index where the previous
// object on the retaining path is located (deprecated).
//
// Note: this property is deprecated and will be replaced by `parentField`.
// object on the retaining path is located.
int parentListIndex [optional];
// If `value` is a Map, `parentMapKey` is the key mapping to the previous
@ -3757,7 +3770,7 @@ class RetainingObject {
// If `value` is a non-List, non-Map object, `parentField` is the name of the
// field containing the previous object on the retaining path.
string|int parentField [optional];
string parentField [optional];
}
```
@ -4402,6 +4415,5 @@ version | comments
3.60 | Added `gcType` property to `Event`.
3.61 | Added `isolateGroupId` property to `@Isolate` and `Isolate`.
3.62 | Added `Set` to `InstanceKind`.
4.0 | Added `Record` and `RecordType` `InstanceKind`s, added a deprecation notice to the `decl` property of `BoundField`, added `name` property to `BoundField`, added a deprecation notice to the `parentListIndex` property of `InboundReference`, changed the type of the `parentField` property of `InboundReference` from `@Field` to `@Field\|string\|int`, added a deprecation notice to the `parentListIndex` property of `RetainingObject`, changed the type of the `parentField` property of `RetainingObject` from `string` to `string\|int`, removed the deprecated `setExceptionPauseMode` procedure, removed the deprecated `timeSpan` property from `CpuSamples`, and removed the deprecated `timeSpan` property from `CpuSamplesEvent`.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss