From 6eb85949fdd7b893ed74c82914ed86abc37f1b27 Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Thu, 21 Mar 2024 19:50:46 +0000 Subject: [PATCH] [ VM / DDS ] Add --print-dtd-uri flag and launch DTD from the correct snapshot for AOT This adds support for printing the DTD connection information to stdout when --print-dtd-uri is passed. This change also fixes an issue where DDS would fail to spawn an isolate with the DTD snapshot when DDS was running in AOT mode. This means the SDK must be shipped with both AppJIT and AOT DTD snapshots, at least until dartdev is moved to run from AOT. Fixes https://github.com/dart-lang/sdk/issues/55034 TEST=run_test.dart Change-Id: I788ef9bfe76297a8d594992a2aac440ed9e2ecac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358541 Reviewed-by: Siva Annamalai Commit-Queue: Ben Konyi Reviewed-by: Kenzie Davisson --- pkg/dartdev/lib/src/commands/run.dart | 7 + pkg/dartdev/lib/src/dds_runner.dart | 24 +- pkg/dartdev/test/commands/devtools_test.dart | 85 +++-- pkg/dartdev/test/commands/run_test.dart | 363 ++++++++----------- pkg/dartdev/test/utils.dart | 1 + pkg/dds/CHANGELOG.md | 4 +- pkg/dds/bin/dds.dart | 7 +- pkg/dds/lib/devtools_server.dart | 18 +- pkg/dds/lib/src/dds_impl.dart | 2 - pkg/dds/lib/src/devtools/dtd.dart | 2 +- pkg/dds/pubspec.yaml | 2 +- runtime/bin/dart_embedder_api_impl.cc | 6 +- runtime/bin/main_impl.cc | 2 +- runtime/bin/main_options.cc | 2 + runtime/bin/main_options.h | 3 +- runtime/bin/run_vm_tests.cc | 3 +- runtime/bin/vmservice_impl.cc | 7 +- runtime/bin/vmservice_impl.h | 6 +- sdk/BUILD.gn | 17 +- sdk/lib/_internal/vm/bin/vmservice_io.dart | 41 +-- utils/dartdev/BUILD.gn | 5 - utils/dds/BUILD.gn | 24 -- utils/dtd/BUILD.gn | 6 +- 23 files changed, 281 insertions(+), 356 deletions(-) diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart index 95a629c5376..4e748c93aa5 100644 --- a/pkg/dartdev/lib/src/commands/run.dart +++ b/pkg/dartdev/lib/src/commands/run.dart @@ -264,6 +264,13 @@ class RunCommand extends DartdevCommand { hide: !verbose, help: 'Enable hosting Observatory through the VM Service.', defaultsTo: true) + ..addFlag( + 'print-dtd', + hide: !verbose, + help: 'Prints connection details for the Dart Tooling Daemon (DTD).' + 'Useful for Dart DevTools extension authors working with DTD in the ' + 'extension development environment.', + ) ..addFlag( 'debug-dds', hide: true, diff --git a/pkg/dartdev/lib/src/dds_runner.dart b/pkg/dartdev/lib/src/dds_runner.dart index 79ce257b014..71f99f4486e 100644 --- a/pkg/dartdev/lib/src/dds_runner.dart +++ b/pkg/dartdev/lib/src/dds_runner.dart @@ -24,25 +24,11 @@ class DDSRunner { }) async { final sdkDir = dirname(sdk.dart); final fullSdk = sdkDir.endsWith('bin'); - String snapshotName = fullSdk - ? sdk.ddsAotSnapshot - : absolute(sdkDir, 'dds_aot.dart.snapshot'); - String execName = sdk.dartAotRuntime; - // Check to see if the AOT snapshot and dartaotruntime are available. - // If not, fall back to running from the AppJIT snapshot. - // - // This can happen if: - // - The SDK is built for IA32 which doesn't support AOT compilation - // - We only have artifacts available from the 'runtime' build - // configuration, which the VM SDK build bots frequently run from - if (!Sdk.checkArtifactExists(snapshotName, logError: false) || - !Sdk.checkArtifactExists(sdk.dartAotRuntime, logError: false)) { - snapshotName = - fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot'); - if (!Sdk.checkArtifactExists(snapshotName)) { - return false; - } - execName = sdk.dart; + final execName = sdk.dart; + final snapshotName = + fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot'); + if (!Sdk.checkArtifactExists(snapshotName)) { + return false; } final process = await Process.start( diff --git a/pkg/dartdev/test/commands/devtools_test.dart b/pkg/dartdev/test/commands/devtools_test.dart index c04c9414059..a8afc94d65f 100644 --- a/pkg/dartdev/test/commands/devtools_test.dart +++ b/pkg/dartdev/test/commands/devtools_test.dart @@ -18,6 +18,9 @@ final dartVMServiceRegExp = RegExp( final ddsStartedRegExp = RegExp( r'Started the Dart Development Service \(DDS\) at (http://127.0.0.1:.*)', ); +final dtdStartedRegExp = RegExp( + r'Serving the Dart Tooling Daemon at (ws://127.0.0.1:.*)', +); final servingDevToolsRegExp = RegExp( r'Serving DevTools at (http://127.0.0.1:.*)', ); @@ -138,10 +141,54 @@ void devtools() { }); }); + Future startDevTools({ + String? vmServiceUri, + bool shouldStartDds = false, + bool shouldPrintDtd = false, + }) async { + final process = await p.start([ + 'devtools', + '--no-launch-browser', + if (shouldPrintDtd) '--print-dtd', + if (vmServiceUri != null) vmServiceUri, + ]); + process.stderr.transform(utf8.decoder).listen(print); + + bool startedDds = false; + bool startedDtd = false; + final devToolsServedCompleter = Completer(); + late StreamSubscription sub; + sub = process.stdout + .transform(utf8.decoder) + .transform(const LineSplitter()) + .listen((event) async { + print(event); + if (event.contains(ddsStartedRegExp)) { + startedDds = true; + } else if (event.contains(dtdStartedRegExp)) { + startedDtd = true; + } else if (event.contains(servingDevToolsRegExp)) { + await sub.cancel(); + devToolsServedCompleter.complete(); + } + }); + + await devToolsServedCompleter.future; + expect(startedDds, shouldStartDds); + expect(startedDtd, shouldPrintDtd); + + // kill the process + process.kill(); + } + + test('prints DTD URI', () async { + p = project(); + await startDevTools(shouldPrintDtd: true); + }); + group('spawns DDS integration', () { late TestProject targetProject; Process? targetProjectInstance; - Process? process; setUp(() { // NOTE: we don't use `project()` here since it registers a tear-down @@ -163,9 +210,7 @@ Future main() async { tearDown(() { targetProjectInstance?.kill(); - process?.kill(); targetProjectInstance = null; - process = null; targetProject.dispose(); p.dispose(); }); @@ -199,40 +244,6 @@ Future main() async { return await serviceUriCompleter.future; } - Future startDevTools({ - required String vmServiceUri, - required bool shouldStartDds, - }) async { - process = await p.start([ - 'devtools', - '--no-launch-browser', - vmServiceUri, - ]); - process!.stderr.transform(utf8.decoder).listen(print); - - bool startedDds = false; - final devToolsServedCompleter = Completer(); - late StreamSubscription sub; - sub = process!.stdout - .transform(utf8.decoder) - .transform(const LineSplitter()) - .listen((event) async { - if (event.contains(ddsStartedRegExp)) { - startedDds = true; - } else if (event.contains(servingDevToolsRegExp)) { - await sub.cancel(); - devToolsServedCompleter.complete(); - } - }); - - await devToolsServedCompleter.future; - expect(startedDds, shouldStartDds); - - // kill the process - process!.kill(); - process = null; - } - for (final disableAuthCodes in const [true, false]) { final authCodesEnabledStr = disableAuthCodes ? 'disabled' : 'enabled'; test('with auth codes $authCodesEnabledStr', () async { diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart index 0ee7b80f24d..b743e6a3fe7 100644 --- a/pkg/dartdev/test/commands/run_test.dart +++ b/pkg/dartdev/test/commands/run_test.dart @@ -23,6 +23,7 @@ final dartVMServiceRegExp = RegExp(r'The Dart VM service is listening on (http://127.0.0.1:.*)'); const residentFrontendServerPrefix = 'The Resident Frontend Compiler is listening at 127.0.0.1:'; +const dtdMessagePrefix = 'The Dart Tooling Daemon (DTD) is available at:'; final observeScript = r''' void main() async { @@ -35,6 +36,38 @@ void main() async { } '''; +void Function(String) onVmServicesData( + TestProject p, { + bool expectDevtoolsMsg = true, + bool expectDtdMsg = false, +}) { + bool sawDevtoolsMsg = false; + bool sawVmServiceMsg = false; + bool sawProgramMsg = false; + bool sawDtdMsg = false; + void onDataImpl(event) { + if (event.contains(devToolsMessagePrefix)) { + sawDevtoolsMsg = true; + } else if (event.contains(dartVMServiceMessagePrefix)) { + sawVmServiceMsg = true; + } else if (event.contains('Observe smoke test!')) { + sawProgramMsg = true; + } else if (event.contains(dtdMessagePrefix)) { + sawDtdMsg = true; + } + if (sawProgramMsg && + sawVmServiceMsg && + (sawDtdMsg || !expectDtdMsg) && + (sawDevtoolsMsg || !expectDevtoolsMsg)) { + expect(sawDtdMsg, expectDtdMsg); + expect(sawDevtoolsMsg, expectDevtoolsMsg); + p.kill(); + } + } + + return onDataImpl; +} + void main() async { ensureRunFromSdkBinDart(); @@ -264,7 +297,7 @@ void main(List args) => print("$b $args"); void onData1(event) { if (event.contains('The Dart VM service is listening on')) { final re = RegExp( - r'The Dart VM service is listening on http:\/\/127.0.0.1:\d+\/[a-zA-Z0-9_-]+=\/\n.*'); + r'The Dart VM service is listening on http:\/\/127.0.0.1:\d+\/[a-zA-Z0-9_-]+=\/.*'); expect(re.hasMatch(event), true); p.kill(); } @@ -287,7 +320,7 @@ void main(List args) => print("$b $args"); void onData2(event) { if (event.contains('The Dart VM service is listening on')) { final re = RegExp( - r'The Dart VM service is listening on http:\/\/127.0.0.1:\d+\/\n'); + r'The Dart VM service is listening on http:\/\/127.0.0.1:\d+\/'); expect(re.hasMatch(event), true); p.kill(); } @@ -311,7 +344,7 @@ void main(List args) => print("$b $args"); void onData3(event) { if (event.contains('The Dart VM service is listening on')) { final re = RegExp( - r'The Dart VM service is listening on http:\/\/\[::1\]:\d+\/[a-zA-Z0-9_-]+=\/\n.*'); + r'The Dart VM service is listening on http:\/\/\[::1\]:\d+\/[a-zA-Z0-9_-]+=\/.*'); expect(re.hasMatch(event), true); p.kill(); } @@ -426,7 +459,7 @@ void main(List args) => print("$b $args"); final p = project(mainSrc: observeScript); final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0); final regexp = RegExp( - r'The Dart VM service is listening on http:\/\/127.0.0.1:(\d*)\/[a-zA-Z0-9_-]+=\/\n.*', + r'The Dart VM service is listening on http:\/\/127.0.0.1:(\d*)\/[a-zA-Z0-9_-]+=\/.*', ); void onData(event) { if (event.contains('The Dart VM service is listening on')) { @@ -489,109 +522,67 @@ void main(List args) => print("$b $args"); group('disable', () { test('dart run simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg || sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - 'run', - '--no-dds', - '--enable-vm-service=0', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, false); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + 'run', + '--no-dds', + '--enable-vm-service=0', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDevtoolsMsg: false, + ), + ); }); test('dart simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg || sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - '--no-dds', - '--enable-vm-service=0', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, false); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + '--no-dds', + '--enable-vm-service=0', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDevtoolsMsg: false, + ), + ); }); }); group('explicit enable', () { test('dart run simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - final tempDir = Directory.systemTemp.createTempSync('a'); final serviceInfo = path.join(tempDir.path, 'service.json'); - await p.runWithVmService([ - 'run', - '--dds', - '--enable-vm-service=0', - '--write-service-info=$serviceInfo', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + 'run', + '--dds', + '--enable-vm-service=0', + '--write-service-info=$serviceInfo', + p.relativeFilePath, + ], + onVmServicesData(p), + ); expect(File(serviceInfo).existsSync(), true); }); test('dart simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - final tempDir = Directory.systemTemp.createTempSync('a'); final serviceInfo = path.join(tempDir.path, 'service.json'); - await p.runWithVmService([ - '--dds', - '--enable-vm-service=0', - '--write-service-info=$serviceInfo', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + '--dds', + '--enable-vm-service=0', + '--write-service-info=$serviceInfo', + p.relativeFilePath, + ], + onVmServicesData(p), + ); expect(File(serviceInfo).existsSync(), true); }); }); @@ -600,155 +591,75 @@ void main(List args) => print("$b $args"); group('DevTools', () { test('dart run simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - await p.runWithVmService([ 'run', '--enable-vm-service=0', p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + ], onVmServicesData(p)); }); test('dart simple', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - '--enable-vm-service=0', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + '--enable-vm-service=0', + p.relativeFilePath, + ], + onVmServicesData(p), + ); }); test('dart run explicit', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - 'run', - '--serve-devtools', - '--enable-vm-service=0', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + await p.runWithVmService( + [ + 'run', + '--serve-devtools', + '--enable-vm-service=0', + p.relativeFilePath, + ], + onVmServicesData(p), + ); }); test('dart explicit', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } - if (sawDevtoolsMsg && sawVmServiceMsg) { - p.kill(); - } - } - await p.runWithVmService([ '--serve-devtools', '--enable-vm-service=0', p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, true); - expect(sawVmServiceMsg, true); + ], onVmServicesData(p)); }); test('dart run disabled', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - bool sawProgramMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } else if (event.contains('Observe smoke test!')) { - sawProgramMsg = true; - } - if (sawProgramMsg && sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - 'run', - '--enable-vm-service=0', - '--no-serve-devtools', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, false); - expect(sawVmServiceMsg, true); - expect(sawProgramMsg, true); + await p.runWithVmService( + [ + 'run', + '--enable-vm-service=0', + '--no-serve-devtools', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDevtoolsMsg: false, + ), + ); }); test('dart disabled', () async { p = project(mainSrc: observeScript); - bool sawDevtoolsMsg = false; - bool sawVmServiceMsg = false; - bool sawProgramMsg = false; - void onData(event) { - if (event.contains(devToolsMessagePrefix)) { - sawDevtoolsMsg = true; - } else if (event.contains(dartVMServiceMessagePrefix)) { - sawVmServiceMsg = true; - } else if (event.contains('Observe smoke test!')) { - sawProgramMsg = true; - } - if (sawProgramMsg && sawVmServiceMsg) { - p.kill(); - } - } - - await p.runWithVmService([ - '--enable-vm-service=0', - '--no-serve-devtools', - p.relativeFilePath, - ], onData); - expect(sawDevtoolsMsg, false); - expect(sawVmServiceMsg, true); - expect(sawProgramMsg, true); + await p.runWithVmService( + [ + '--enable-vm-service=0', + '--no-serve-devtools', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDevtoolsMsg: false, + ), + ); }); test('dart run VM service not enabled', () async { @@ -804,6 +715,38 @@ void main(List args) => print("$b $args"); ); }); + group('--print-dtd', () { + test('dart', () async { + p = project(mainSrc: observeScript); + await p.runWithVmService( + [ + '--enable-vm-service=0', + '--print-dtd', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDtdMsg: true, + )); + }); + + test('dart run', () async { + p = project(mainSrc: observeScript); + await p.runWithVmService( + [ + 'run', + '--enable-vm-service=0', + '--print-dtd', + p.relativeFilePath, + ], + onVmServicesData( + p, + expectDtdMsg: true, + ), + ); + }); + }); + group('Observatory', () { void generateServedTest({ required bool serve, @@ -1210,7 +1153,7 @@ void residentRun() { void onData2(event) { if (event.contains('The Dart VM service is listening on')) { final re = RegExp( - r'The Dart VM service is listening on http:\/\/\[::1\]:\d+\/[a-zA-Z0-9_-]+=\/\n.*'); + r'The Dart VM service is listening on http:\/\/\[::1\]:\d+\/[a-zA-Z0-9_-]+=\/.*'); expect(re.hasMatch(event), true); sawVmServiceMsg = true; } diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart index 91658e5ae5f..7c292a8469d 100644 --- a/pkg/dartdev/test/utils.dart +++ b/pkg/dartdev/test/utils.dart @@ -223,6 +223,7 @@ class TestProject { sub = process.stdout .transform(utf8.decoder) + .transform(const LineSplitter()) .listen(onData, onError: onError, onDone: onDone); subError = process.stderr.transform(utf8.decoder).listen(onStderr); diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md index 27179b42a36..ca931328f58 100644 --- a/pkg/dds/CHANGELOG.md +++ b/pkg/dds/CHANGELOG.md @@ -1,7 +1,9 @@ +# 3.4.0 +- Start the Dart Tooling Daemon from the DevTools server when a connection is not passed to the server on start. + # 3.3.1 - [DAP] Fixed an issue introduced in 3.3.0 where `Source.name` could contain a file paths when a `package:` or `dart:` URI should have been used. - Updated `package:devtools_shared` version to ^8.0.1. -- Start the Dart Tooling Daemon from the DevTools server when a connection is not passed to the server on start. # 3.3.0 - **Breaking change:** [DAP] Several signatures in DAP debug adapter classes have been updated to use `Uri`s where they previously used `String path`s. This is to support communicating with the DAP client using URIs instead of file paths. URIs may be used only when the client sets the custom `supportsDartUris` client capability during initialization. diff --git a/pkg/dds/bin/dds.dart b/pkg/dds/bin/dds.dart index 230cfe23dc4..fc1b036ab76 100644 --- a/pkg/dds/bin/dds.dart +++ b/pkg/dds/bin/dds.dart @@ -144,12 +144,15 @@ ${argParser.usage} : null, enableServicePortFallback: enableServicePortFallback, ); + final dtdInfo = dds.hostedDartToolingDaemon; stderr.write(json.encode({ 'state': 'started', 'ddsUri': dds.uri.toString(), if (dds.devToolsUri != null) 'devToolsUri': dds.devToolsUri.toString(), - if (dds.hostedDartToolingDaemon?.uri != null) - 'dtdUri': dds.hostedDartToolingDaemon!.uri, + if (dtdInfo != null) + 'dtd': { + 'uri': dtdInfo.uri, + }, })); } catch (e, st) { writeErrorResponse(e, st); diff --git a/pkg/dds/lib/devtools_server.dart b/pkg/dds/lib/devtools_server.dart index c18ebebb74a..74179b35dc5 100644 --- a/pkg/dds/lib/devtools_server.dart +++ b/pkg/dds/lib/devtools_server.dart @@ -40,6 +40,7 @@ class DevToolsServer { static const argDdsPort = 'dds-port'; static const argDebugMode = 'debug'; static const argDtdUri = 'dtd-uri'; + static const argPrintDtd = 'print-dtd'; static const argLaunchBrowser = 'launch-browser'; static const argMachine = 'machine'; static const argHost = 'host'; @@ -102,7 +103,7 @@ class DevToolsServer { ..addOption( argDtdUri, valueHelp: 'uri', - help: 'A URI pointing to a dart tooling daemon that devtools should ' + help: 'A URI pointing to a Dart Tooling Daemon that DevTools should ' 'interface with.', ) ..addFlag( @@ -197,6 +198,13 @@ class DevToolsServer { help: 'Causes the server to spawn Chrome in headless mode for use in ' 'automated testing.', hide: !verbose, + ) + ..addFlag( + argPrintDtd, + negatable: false, + help: 'Print the address of the Dart Tooling Daemon, if one is hosted ' + 'by the DevTools server.', + hide: !verbose, ); // Deprecated and hidden args. @@ -238,6 +246,7 @@ class DevToolsServer { bool allowEmbedding = true, bool headlessMode = false, bool verboseMode = false, + bool printDtdUri = false, String? hostname, String? customDevToolsPath, int port = 0, @@ -279,9 +288,7 @@ class DevToolsServer { if (dtdUri == null) { final (:uri, :secret) = await startDtd( machineMode: machineMode, - // TODO(https://github.com/dart-lang/sdk/issues/55034): pass the value - // of the Dart CLI flag `--print-dtd` here. - printDtdUri: false, + printDtdUri: printDtdUri, ); dtdUri = uri; dtdSecret = secret; @@ -484,6 +491,8 @@ class DevToolsServer { dtdUri = args[argDtdUri]; } + final printDtdUri = args.wasParsed(argPrintDtd); + if (help) { print( 'Dart DevTools version ${await DevToolsUtils.getVersion(customDevToolsPath ?? "")}'); @@ -551,6 +560,7 @@ class DevToolsServer { appSizeBase: appSizeBase, appSizeTest: appSizeTest, dtdUri: dtdUri, + printDtdUri: printDtdUri, ); } diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart index d15d95c8f9f..90608678379 100644 --- a/pkg/dds/lib/src/dds_impl.dart +++ b/pkg/dds/lib/src/dds_impl.dart @@ -181,8 +181,6 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService { // server on start. _hostedDartToolingDaemon = await startDtd( machineMode: false, - // TODO(https://github.com/dart-lang/sdk/issues/55034): pass the value - // of the Dart CLI flag `--print-dtd` here. printDtdUri: false, ); } diff --git a/pkg/dds/lib/src/devtools/dtd.dart b/pkg/dds/lib/src/devtools/dtd.dart index f5c476984f8..bc0dc5d3cf7 100644 --- a/pkg/dds/lib/src/devtools/dtd.dart +++ b/pkg/dds/lib/src/devtools/dtd.dart @@ -17,7 +17,7 @@ Future startDtd({ required bool printDtdUri, }) async { final sdkPath = File(Platform.resolvedExecutable).parent.parent.path; - String dtdSnapshot = path.absolute( + final dtdSnapshot = path.absolute( sdkPath, 'bin', 'snapshots', diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml index 7d193c80646..f295ed94cc8 100644 --- a/pkg/dds/pubspec.yaml +++ b/pkg/dds/pubspec.yaml @@ -1,5 +1,5 @@ name: dds -version: 3.3.1 +version: 3.4.0 description: >- A library used to spawn the Dart Developer Service, used to communicate with a Dart VM Service instance. diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc index e5a5718c03f..e8976133615 100644 --- a/runtime/bin/dart_embedder_api_impl.cc +++ b/runtime/bin/dart_embedder_api_impl.cc @@ -110,7 +110,8 @@ Dart_Isolate CreateVmServiceIsolate(const IsolateCreationData& data, /*enable_service_port_fallback=*/false, /*wait_for_dds_to_advertise_service=*/false, /*serve_devtools=*/false, - /*serve_observatory=*/true)) { + /*serve_observatory=*/true, + /*print_dtd=*/false)) { *error = Utils::StrDup(bin::VmService::GetErrorMessage()); return nullptr; } @@ -148,7 +149,8 @@ Dart_Isolate CreateVmServiceIsolateFromKernel( /*enable_service_port_fallback=*/false, /*wait_for_dds_to_advertise_service=*/false, /*serve_devtools=*/false, - /*serve_observatory*/ true)) { + /*serve_observatory=*/true, + /*print_dtd=*/false)) { *error = Utils::StrDup(bin::VmService::GetErrorMessage()); return nullptr; } diff --git a/runtime/bin/main_impl.cc b/runtime/bin/main_impl.cc index 7b5a7700fcd..2826f4834c9 100644 --- a/runtime/bin/main_impl.cc +++ b/runtime/bin/main_impl.cc @@ -558,7 +558,7 @@ static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri, Options::vm_write_service_info_filename(), Options::trace_loading(), Options::deterministic(), Options::enable_service_port_fallback(), wait_for_dds_to_advertise_service, serve_devtools, - Options::enable_observatory())) { + Options::enable_observatory(), Options::print_dtd())) { *error = Utils::StrDup(VmService::GetErrorMessage()); return nullptr; } diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc index dbb0e699977..25d484c60c0 100644 --- a/runtime/bin/main_options.cc +++ b/runtime/bin/main_options.cc @@ -557,6 +557,8 @@ bool Options::ParseArguments(int argc, // ignore it. --no-serve-observatory is a VM flag so we don't need to // handle that case here. skipVmOption = true; + } else if (IsOption(argv[i], "print-dtd-uri")) { + skipVmOption = true; } if (!skipVmOption) { temp_vm_options.AddArgument(argv[i]); diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h index 022b1924fd8..b46685c3b13 100644 --- a/runtime/bin/main_options.h +++ b/runtime/bin/main_options.h @@ -52,7 +52,8 @@ namespace bin { V(no_serve_devtools, disable_devtools) \ V(serve_devtools, enable_devtools) \ V(no_serve_observatory, disable_observatory) \ - V(serve_observatory, enable_observatory) + V(serve_observatory, enable_observatory) \ + V(print_dtd, print_dtd) // Boolean flags that have a short form. #define SHORT_BOOL_OPTIONS_LIST(V) \ diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc index 69bbf1804a6..ae1fb3242ba 100644 --- a/runtime/bin/run_vm_tests.cc +++ b/runtime/bin/run_vm_tests.cc @@ -155,7 +155,8 @@ static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri, /*enable_service_port_fallback=*/false, /*wait_for_dds_to_advertise_service=*/false, /*serve_devtools=*/false, - /*serve_observatory-*/ true)) { + /*serve_observatory=*/true, + /*print_dtd=*/false)) { *error = Utils::StrDup(bin::VmService::GetErrorMessage()); return nullptr; } diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc index 9cccf744b87..7b7559b8af6 100644 --- a/runtime/bin/vmservice_impl.cc +++ b/runtime/bin/vmservice_impl.cc @@ -124,7 +124,8 @@ bool VmService::Setup(const char* server_ip, bool enable_service_port_fallback, bool wait_for_dds_to_advertise_service, bool serve_devtools, - bool serve_observatory) { + bool serve_observatory, + bool print_dtd) { Dart_Isolate isolate = Dart_CurrentIsolate(); ASSERT(isolate != nullptr); SetServerAddress(""); @@ -221,6 +222,10 @@ bool VmService::Setup(const char* server_ip, serve_observatory ? Dart_True() : Dart_False()); SHUTDOWN_ON_ERROR(result); + result = Dart_SetField(library, DartUtils::NewString("_printDtd"), + print_dtd ? Dart_True() : Dart_False()); + SHUTDOWN_ON_ERROR(result); + // Are we running on Windows? #if defined(DART_HOST_OS_WINDOWS) Dart_Handle is_windows = Dart_True(); diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h index 1994659bdff..76b6e0b7537 100644 --- a/runtime/bin/vmservice_impl.h +++ b/runtime/bin/vmservice_impl.h @@ -25,7 +25,8 @@ class VmService { bool enable_service_port_fallback, bool wait_for_dds_to_advertise_service, bool serve_devtools, - bool serve_observatory) { + bool serve_observatory, + bool print_dtd) { return false; } @@ -51,7 +52,8 @@ class VmService { bool enable_service_port_fallback, bool wait_for_dds_to_advertise_service, bool serve_devtools, - bool serve_observatory); + bool serve_observatory, + bool print_dtd); static void SetNativeResolver(); diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 759738ef4d5..7c8f4869140 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -46,7 +46,7 @@ declare_args() { # ........dart2wasm_product.snapshot (if not on ia32) # ........dartdev.dart.snapshot (app-jit snapshot or kernel dill file) # ........dartdevc.dart.snapshot -# ........dds_aot.dart.snapshot (AOT snapshot) or dds.dart.snapshot (ia32) +# ........dds.dart.snapshot # ........dart_tooling_daemon.dart.snapshot # ........frontend_server_aot.dart.snapshot (AOT snapshot, if not on ia32) # ........frontend_server.dart.snapshot @@ -125,17 +125,10 @@ _platform_sdk_snapshots = [ "../utils/kernel-service:frontend_server", ], ] -if (dart_target_arch != "ia32" && dart_target_arch != "x86") { - _platform_sdk_snapshots += [ [ - "dds_aot", - "../utils/dds:dds_aot", - ] ] -} else { - _platform_sdk_snapshots += [ [ - "dds", - "../utils/dds:dds", - ] ] -} +_platform_sdk_snapshots += [ [ + "dds", + "../utils/dds:dds", + ] ] if (dart_snapshot_kind == "app-jit") { _platform_sdk_snapshots += [ [ "kernel-service", diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart index 05cd7b3e58b..e49e3141e55 100644 --- a/sdk/lib/_internal/vm/bin/vmservice_io.dart +++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart @@ -65,6 +65,9 @@ bool _waitForDdsToAdvertiseService = false; @pragma('vm:entry-point', !const bool.fromEnvironment('dart.vm.product')) bool _serveObservatory = false; +@pragma('vm:entry-point', !const bool.fromEnvironment('dart.vm.product')) +bool _printDtd = false; + // HTTP server. Server? server; Future? serverFuture; @@ -103,27 +106,12 @@ class _DebuggingSession { ].join('/'); final fullSdk = dartDir.endsWith('bin'); - - final dartAotPath = [ - dartDir, - fullSdk - ? 'dartaotruntime${Platform.isWindows ? '.exe' : ''}' - : 'dart_precompiled_runtime_product${Platform.isWindows ? '.exe' : ''}', - ].join('/'); - String snapshotName = [ + final snapshotName = [ dartDir, fullSdk ? 'snapshots' : 'gen', - 'dds_aot.dart.snapshot', + 'dds.dart.snapshot', ].join('/'); - String execName = dartAotPath; - if (!File(snapshotName).existsSync() || !File(dartAotPath).existsSync()) { - snapshotName = [ - dartDir, - fullSdk ? 'snapshots' : 'gen', - 'dds.dart.snapshot', - ].join('/'); - execName = dartPath.toString(); - } + final execName = dartPath.toString(); _process = await Process.start( execName, @@ -144,20 +132,21 @@ class _DebuggingSession { final result = json.decode(event) as Map; final state = result['state']; if (state == 'started') { - if (result.containsKey('devToolsUri')) { - // TODO(https://github.com/dart-lang/sdk/issues/55034): only print - // this if the Dart CLI flag `--print-dtd` is present. - if (result.containsKey('dtdUri') && false) { - final dtdUri = result['dtdUri']; - print('The Dart Tooling Daemon is listening on $dtdUri'); - } + if (result case {'devToolsUri': String devToolsUri}) { // NOTE: update pkg/dartdev/lib/src/commands/run.dart if this message // is changed to ensure consistency. const devToolsMessagePrefix = 'The Dart DevTools debugger and profiler is available at:'; - final devToolsUri = result['devToolsUri']; print('$devToolsMessagePrefix $devToolsUri'); } + if (result + case { + 'dtd': { + 'uri': String dtdUri, + } + } when _printDtd) { + print('The Dart Tooling Daemon (DTD) is available at: $dtdUri'); + } stderrSub.cancel(); completer.complete(); } else { diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn index 338c04320c1..9bc0edfc592 100644 --- a/utils/dartdev/BUILD.gn +++ b/utils/dartdev/BUILD.gn @@ -28,11 +28,6 @@ application_snapshot("generate_dartdev_snapshot") { "../dtd:dtd", ] - # DDS should be run from AOT snapshot on all architectures except IA32/X86. - if (dart_target_arch != "ia32" && dart_target_arch != "x86") { - deps += [ "../dds:dds_aot" ] - } - vm_args = [ "--sound-null-safety" ] output = "$root_gen_dir/dartdev.dart.snapshot" } diff --git a/utils/dds/BUILD.gn b/utils/dds/BUILD.gn index c4d58fd052d..4b07b103c81 100644 --- a/utils/dds/BUILD.gn +++ b/utils/dds/BUILD.gn @@ -9,10 +9,6 @@ group("dds") { public_deps = [ ":copy_dds_snapshot" ] } -group("dds_aot") { - public_deps = [ ":copy_dds_aot_snapshot" ] -} - copy("copy_dds_snapshot") { visibility = [ ":dds" ] public_deps = [ ":generate_dds_snapshot" ] @@ -20,28 +16,8 @@ copy("copy_dds_snapshot") { outputs = [ "$root_out_dir/dds.dart.snapshot" ] } -copy("copy_dds_aot_snapshot") { - visibility = [ ":dds_aot" ] - public_deps = [ ":generate_dds_aot_snapshot" ] - sources = [ "$root_gen_dir/dds_aot.dart.snapshot" ] - outputs = [ "$root_out_dir/dds_aot.dart.snapshot" ] -} - application_snapshot("generate_dds_snapshot") { main_dart = "../../pkg/dds/bin/dds.dart" training_args = [ "--help" ] output = "$root_gen_dir/dds.dart.snapshot" } - -aot_snapshot("generate_dds_aot_snapshot") { - main_dart = "../../pkg/dds/bin/dds.dart" - output = "$root_gen_dir/dds_aot.dart.snapshot" - - # dartaotruntime has dart_product_config applied to it, - # so it is built in # product mode in both release and - # product builds, and is only built in debug mode in debug - # builds. The following line ensures that the dartaotruntime - # and dds_aot snapshot in an SDK build are - # always compatible with each other. - force_product_mode = !dart_debug -} diff --git a/utils/dtd/BUILD.gn b/utils/dtd/BUILD.gn index 3209923655f..695184ba692 100644 --- a/utils/dtd/BUILD.gn +++ b/utils/dtd/BUILD.gn @@ -2,13 +2,11 @@ # 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("../../build/dart/copy_tree.gni") +import("../aot_snapshot.gni") import("../application_snapshot.gni") group("dtd") { - public_deps = [ - ":copy_dtd_snapshot", - ] + public_deps = [ ":copy_dtd_snapshot" ] } copy("copy_dtd_snapshot") {