From 45d06f2302f93c89545a4e3bf3b852768f8985c0 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Mon, 21 Aug 2023 14:17:40 +0000 Subject: [PATCH] [dds/dap] Include Isolate IDs in Threads when used over DDS See https://github.com/dart-lang/sdk/issues/53086 Change-Id: I380744f9e0d604168f026684b31fe689bb8947c8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317701 Reviewed-by: Ben Konyi --- pkg/dds/CHANGELOG.md | 1 + .../src/dap/adapters/dds_hosted_adapter.dart | 41 +++++++++++++++++++ pkg/dds/lib/src/dap/constants.dart | 1 + pkg/dds/test/dap_handler_test.dart | 27 +++++++++++- 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md index 8267e2dad43f..bdb6d64d924a 100644 --- a/pkg/dds/CHANGELOG.md +++ b/pkg/dds/CHANGELOG.md @@ -1,5 +1,6 @@ # 2.9.5 - [DAP] The change to use VM Service Isolate numbers for `threadId`s has been reverted because Isolate numbers can be larger than the 32-bit integers allowed in DAP. +- [DAP] Threads returned from `threadsRequest` from the DDS DAP handler now include `isolateId` fields to allow mapping back to VM Service Isolates. # 2.9.4 - Updated `devtools_shared` to ^2.26.1 diff --git a/pkg/dds/lib/src/dap/adapters/dds_hosted_adapter.dart b/pkg/dds/lib/src/dap/adapters/dds_hosted_adapter.dart index 7da098e073ab..f7d3bfecbcab 100644 --- a/pkg/dds/lib/src/dap/adapters/dds_hosted_adapter.dart +++ b/pkg/dds/lib/src/dap/adapters/dds_hosted_adapter.dart @@ -100,6 +100,28 @@ class DdsHostedAdapter extends DartDebugAdapter threadsRequest( + Request request, + void args, + void Function(ThreadsResponseBody) sendResponse, + ) async { + final threads = [ + for (final thread in isolateManager.threads) + ThreadWithIsolateId( + id: thread.threadId, + name: thread.isolate.name ?? '', + isolateId: + thread.isolate.id ?? '', + ) + ]; + sendResponse(ThreadsResponseBody(threads: threads)); + } + /// Handles custom requests that are specific to the DDS-hosted adapter, such /// as translating between VM IDs and DAP IDs. @override @@ -228,3 +250,22 @@ class DdsHostedAdapter extends DartDebugAdapter toJson() => { + ...super.toJson(), + 'isolateId': isolateId, + }; +} diff --git a/pkg/dds/lib/src/dap/constants.dart b/pkg/dds/lib/src/dap/constants.dart index db2f03241c1c..ae971f8fb40e 100644 --- a/pkg/dds/lib/src/dap/constants.dart +++ b/pkg/dds/lib/src/dap/constants.dart @@ -6,6 +6,7 @@ class Command { static const initialize = 'initialize'; static const configurationDone = 'configurationDone'; static const attach = 'attach'; + static const threads = 'threads'; static const createVariableForInstance = r'$/createVariableForInstance'; static const getVariablesInstanceId = r'$/getVariablesInstanceId'; } diff --git a/pkg/dds/test/dap_handler_test.dart b/pkg/dds/test/dap_handler_test.dart index ae6f54051dd6..b61235ffb319 100644 --- a/pkg/dds/test/dap_handler_test.dart +++ b/pkg/dds/test/dap_handler_test.dart @@ -35,7 +35,8 @@ void main() { }); var nextSeq = 1; - Future sendDapRequest(String request, Object? arguments) async { + Future sendDapRequest(String request, + [Object? arguments]) async { final result = await service.sendDapRequest( jsonEncode( Request( @@ -153,4 +154,28 @@ void main() { expect(await variableToString(variablesReference), 'MyClass'); expect(await instanceToString(isolateId, mappedInstanceId), 'MyClass'); }); + + test('DAP includes Isolate IDs in Threads', () async { + await createProcess(pauseOnStart: false); + dds = await DartDevelopmentService.startDartDevelopmentService( + remoteVmServiceUri, + ); + service = await vmServiceConnectUri(dds!.wsUri!.toString()); + + // Get the expected isolateId. + final isolateId = (await service.getVM()).isolates!.first.id!; + + // Ask DAP for all threads. + final threadsResult = await sendDapRequest(Command.threads); + final threadsBody = threadsResult.dapResponse.body as Map; + + final threads = threadsBody['threads'] as List; + expect(threads, hasLength(1)); + final thread = threads[0] as Map; + expect(thread, { + 'id': 1, + 'name': 'main', + 'isolateId': isolateId, + }); + }); }