Skip to content

Commit 1e148e6

Browse files
a-sivaCommit Queue
authored andcommitted
Fix issue that was found with the flutter rolls (unable to locate
the dds snapshot) Reland "[SDK] Switch dds and dtd to use an AOT snapshot" This reverts commit 11ab2df. Reason for revert: Fixes the problem that is causing Flutter G3 roll to fail. TEST=ci Original change's description: > Revert "[SDK] Switch dds and dtd to use an AOT snapshot" > > This reverts commit 6450d76. > > Reason for revert: Breaking Flutter G3 roll > > Original change's description: > > [SDK] Switch dds and dtd to use an AOT snapshot > > > > TEST=ci > > > > Change-Id: Ib65ca1d1a05d3bc7b5f5cab25d90fc459ec8d853 > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387133 > > Reviewed-by: Ben Konyi <[email protected]> > > Commit-Queue: Siva Annamalai <[email protected]> > > Change-Id: I9985919063cacfc8673b3e2946eaa163e90c9cc3 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/411200 > Auto-Submit: Ben Konyi <[email protected]> > Reviewed-by: Siva Annamalai <[email protected]> > Bot-Commit: Rubber Stamper <[email protected]> > Commit-Queue: Siva Annamalai <[email protected]> Change-Id: I5ec8e58f905b4ad1d22d507acd8e22e676dc5532 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410921 Commit-Queue: Siva Annamalai <[email protected]> Reviewed-by: Brian Quinlan <[email protected]>
1 parent 7793a2e commit 1e148e6

File tree

11 files changed

+350
-64
lines changed

11 files changed

+350
-64
lines changed

pkg/dartdev/lib/src/commands/development_service.dart

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6+
import 'dart:io';
67

78
import 'package:dds/src/arg_parser.dart';
9+
import 'package:path/path.dart';
810

911
import '../core.dart';
1012
import '../sdk.dart';
11-
import '../utils.dart';
13+
import '../vm_interop_handler.dart';
1214

1315
class DevelopmentServiceCommand extends DartdevCommand {
1416
static const String commandName = 'development-service';
@@ -30,14 +32,50 @@ class DevelopmentServiceCommand extends DartdevCommand {
3032

3133
@override
3234
Future<int> run() async {
33-
// Need to make a copy as argResults!.arguments is an
34-
// UnmodifiableListView object which cannot be passed as
35-
// the args for spawnUri.
36-
final args = [...argResults!.arguments];
37-
return await runFromSnapshot(
38-
snapshot: sdk.ddsSnapshot,
39-
args: args,
40-
verbose: verbose,
41-
);
35+
final sdkDir = dirname(sdk.dart);
36+
final fullSdk = sdkDir.endsWith('bin');
37+
var script = fullSdk
38+
? sdk.dartAotRuntime
39+
: absolute(sdkDir, 'dartaotruntime${Platform.isWindows ? '.exe' : ''}');
40+
var snapshot = fullSdk
41+
? sdk.ddsAotSnapshot
42+
: absolute(sdkDir, 'dds_aot.dart.snapshot');
43+
var useExecProcess = true;
44+
final args = argResults!.arguments;
45+
46+
if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
47+
// On ia32 platforms we do not have an AOT snapshot and so we need
48+
// to run the JIT snapshot.
49+
useExecProcess = false;
50+
script = fullSdk
51+
? sdk.ddsSnapshot
52+
: absolute(sdkDir, 'dds.dart.snapshot');
53+
if (!Sdk.checkArtifactExists(script, logError: false)) {
54+
log.stderr('Error: launching development server failed : '
55+
'Unable to find snapshot for the development server');
56+
return 255;
57+
}
58+
}
59+
final ddsCommand = [
60+
if (useExecProcess) snapshot,
61+
// Add the remaining args.
62+
if (args.isNotEmpty) ...args,
63+
];
64+
try {
65+
VmInteropHandler.run(
66+
script,
67+
ddsCommand,
68+
packageConfigOverride: null,
69+
useExecProcess: useExecProcess,
70+
);
71+
return 0;
72+
} catch (e, st) {
73+
log.stderr('Error: launching development server failed');
74+
log.stderr(e.toString());
75+
if (verbose) {
76+
log.stderr(st.toString());
77+
}
78+
return 255;
79+
}
4280
}
4381
}

pkg/dartdev/lib/src/commands/tooling_daemon.dart

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:dtd_impl/dtd.dart' as dtd show DartToolingDaemonOptions;
88

99
import '../core.dart';
1010
import '../sdk.dart';
11-
import '../utils.dart';
11+
import '../vm_interop_handler.dart';
1212

1313
class ToolingDaemonCommand extends DartdevCommand {
1414
static const String commandName = 'tooling-daemon';
@@ -30,14 +30,37 @@ class ToolingDaemonCommand extends DartdevCommand {
3030

3131
@override
3232
Future<int> run() async {
33-
// Need to make a copy as argResults!.arguments is an
34-
// UnmodifiableListView object which cannot be passed as
35-
// the args for spawnUri.
36-
final args = [...argResults!.arguments];
37-
return await runFromSnapshot(
38-
snapshot: sdk.dtdSnapshot,
39-
args: args,
40-
verbose: verbose,
41-
);
33+
var script = sdk.dartAotRuntime;
34+
var snapshot = sdk.dtdAotSnapshot;
35+
var useExecProcess = true;
36+
final args = argResults!.arguments;
37+
38+
if (!Sdk.checkArtifactExists(sdk.dtdAotSnapshot, logError: false)) {
39+
// On ia32 platforms we do not have an AOT snapshot and so we need
40+
// to run the JIT snapshot.
41+
useExecProcess = false;
42+
script = sdk.dtdSnapshot;
43+
}
44+
final dtdCommand = [
45+
if (useExecProcess) snapshot,
46+
// Add the remaining args.
47+
if (args.isNotEmpty) ...args,
48+
];
49+
try {
50+
VmInteropHandler.run(
51+
script,
52+
dtdCommand,
53+
packageConfigOverride: null,
54+
useExecProcess : useExecProcess,
55+
);
56+
return 0;
57+
} catch (e, st) {
58+
log.stderr('Error: launching tooling daemon failed');
59+
log.stderr(e.toString());
60+
if (verbose) {
61+
log.stderr(st.toString());
62+
}
63+
return 255;
64+
}
4265
}
4366
}

pkg/dartdev/lib/src/dds_runner.dart

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,23 @@ class DDSRunner {
2424
}) async {
2525
final sdkDir = dirname(sdk.dart);
2626
final fullSdk = sdkDir.endsWith('bin');
27-
final execName = sdk.dart;
28-
final snapshotName =
29-
fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
30-
if (!Sdk.checkArtifactExists(snapshotName)) {
31-
return false;
27+
var execName = fullSdk
28+
? sdk.dartAotRuntime
29+
: absolute(sdkDir, 'dartaotruntime${Platform.isWindows ? '.exe' : ''}');
30+
var snapshotName = fullSdk
31+
? sdk.ddsAotSnapshot
32+
: absolute(sdkDir, 'dds_aot.dart.snapshot');
33+
final isAot = Sdk.checkArtifactExists(snapshotName) ? true : false;
34+
if (!isAot) {
35+
// On ia32 sdks we do not have an AOT runtime and so we would be
36+
// using the regular executable.
37+
snapshotName = fullSdk
38+
? sdk.ddsSnapshot
39+
: absolute(sdkDir, 'dds.dart.snapshot');
40+
if (!Sdk.checkArtifactExists(snapshotName)) {
41+
return false;
42+
}
43+
execName = sdk.dart;
3244
}
3345

3446
final process = await Process.start(

pkg/dartdev/lib/src/sdk.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ class Sdk {
119119
'dart_tooling_daemon.dart.snapshot',
120120
);
121121

122+
String get dtdAotSnapshot => _snapshotPathFor(
123+
'dart_tooling_daemon_aot.dart.snapshot',
124+
);
125+
122126
String get devToolsBinaries => path.absolute(
123127
_runFromBuildRoot
124128
? sdkPath

pkg/dds/lib/src/devtools/dtd.dart

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,64 @@ import 'package:path/path.dart' as path;
1212

1313
import 'utils.dart';
1414

15+
String getDTDSnapshotDir() {
16+
// This logic is originally from pkg/dartdev/lib/src/sdk.dart
17+
//
18+
// Find SDK path.
19+
(String, bool)? trySDKPath(String executablePath) {
20+
// The common case, and how cli_util.dart computes the Dart SDK directory,
21+
// [path.dirname] called twice on Platform.executable. We confirm by
22+
// asserting that the directory `./bin/snapshots/` exists in this directory:
23+
var sdkPath = path.absolute(path.dirname(path.dirname(executablePath)));
24+
var snapshotsDir = path.join(sdkPath, 'bin', 'snapshots');
25+
var runFromBuildRoot = false;
26+
final type = FileSystemEntity.typeSync(snapshotsDir);
27+
if (type != FileSystemEntityType.directory &&
28+
type != FileSystemEntityType.link) {
29+
// This is the less common case where the user is in
30+
// the checked out Dart SDK, and is executing `dart` via:
31+
// ./out/ReleaseX64/dart ... or in google3.
32+
sdkPath = path.absolute(path.dirname(executablePath));
33+
snapshotsDir = sdkPath;
34+
runFromBuildRoot = true;
35+
}
36+
37+
// Try to locate the DartDev snapshot to determine if we're able to find
38+
// the SDK snapshots with this SDK path. This is meant to handle
39+
// non-standard SDK layouts that can involve symlinks (e.g., Brew
40+
// installations, google3 tests, etc).
41+
if (!File(
42+
path.join(snapshotsDir, 'dartdev.dart.snapshot'),
43+
).existsSync()) {
44+
return null;
45+
}
46+
return (sdkPath, runFromBuildRoot);
47+
}
48+
49+
final (sdkPath, runFromBuildRoot) = trySDKPath(Platform.resolvedExecutable) ??
50+
trySDKPath(Platform.executable)!;
51+
52+
final String snapshotDir;
53+
if (runFromBuildRoot) {
54+
snapshotDir = sdkPath;
55+
} else {
56+
snapshotDir = path.absolute(sdkPath, 'bin', 'snapshots');
57+
}
58+
59+
return snapshotDir;
60+
}
61+
1562
Future<DtdInfo?> startDtd({
1663
required bool machineMode,
1764
required bool printDtdUri,
1865
}) async {
19-
final sdkPath = File(Platform.resolvedExecutable).parent.parent.path;
20-
final dtdSnapshot = path.absolute(
21-
sdkPath,
22-
'bin',
23-
'snapshots',
66+
final snapshotDir = getDTDSnapshotDir();
67+
final dtdAotSnapshot = path.absolute(
68+
snapshotDir,
69+
'dart_tooling_daemon_aot.dart.snapshot',
70+
);
71+
final dtdSnapshot = path.absolute(
72+
snapshotDir,
2473
'dart_tooling_daemon.dart.snapshot',
2574
);
2675

@@ -65,15 +114,29 @@ Future<DtdInfo?> startDtd({
65114
});
66115

67116
try {
117+
// Try to spawn an isolate using the AOT snapshot of the tooling daemon.
68118
await Isolate.spawnUri(
69-
Uri.file(dtdSnapshot),
119+
Uri.file(dtdAotSnapshot),
70120
['--machine'],
71121
receivePort.sendPort,
72122
onExit: exitPort.sendPort,
73123
onError: errorPort.sendPort,
74124
);
75125
} catch (_, __) {
76-
completeForError();
126+
// Spawning an isolate using the AOT snapshot of the tooling daemon failed,
127+
// we are probably in a JIT VM, try again using the JIT snapshot of the
128+
// tooling daemon.
129+
try {
130+
await Isolate.spawnUri(
131+
Uri.file(dtdSnapshot),
132+
['--machine'],
133+
receivePort.sendPort,
134+
onExit: exitPort.sendPort,
135+
onError: errorPort.sendPort,
136+
);
137+
} catch (_, __) {
138+
completeForError();
139+
}
77140
}
78141

79142
final result = await completer.future.timeout(

runtime/bin/process_win.cc

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,13 +573,45 @@ class ProcessStarter {
573573
}
574574

575575
int StartForExec() {
576+
ASSERT(mode_ == kInheritStdio);
577+
ASSERT(Process::ModeIsAttached(mode_));
578+
ASSERT(!Process::ModeHasStdio(mode_));
579+
576580
// Setup info
577581
STARTUPINFOEXW startup_info;
578582
ZeroMemory(&startup_info, sizeof(startup_info));
579583
startup_info.StartupInfo.cb = sizeof(startup_info);
580-
ASSERT(mode_ == kInheritStdio);
581-
ASSERT(Process::ModeIsAttached(mode_));
582-
ASSERT(!Process::ModeHasStdio(mode_));
584+
585+
// Setup the handles to inherit. We only want to inherit the three
586+
// handles for stdin, stdout and stderr.
587+
HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
588+
HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
589+
HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
590+
startup_info.StartupInfo.hStdInput = stdin_handle;
591+
startup_info.StartupInfo.hStdOutput = stdout_handle;
592+
startup_info.StartupInfo.hStdError = stderr_handle;
593+
startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
594+
SIZE_T size = 0;
595+
// The call to determine the size of an attribute list always fails with
596+
// ERROR_INSUFFICIENT_BUFFER and that error should be ignored.
597+
if (!InitializeProcThreadAttributeList(nullptr, 1, 0, &size) &&
598+
(GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
599+
return CleanupAndReturnError();
600+
}
601+
attribute_list_ = reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(
602+
Dart_ScopeAllocate(size));
603+
ZeroMemory(attribute_list_, size);
604+
if (!InitializeProcThreadAttributeList(attribute_list_, 1, 0, &size)) {
605+
return CleanupAndReturnError();
606+
}
607+
inherited_handles_ = {stdin_handle, stdout_handle, stderr_handle};
608+
if (!UpdateProcThreadAttribute(
609+
attribute_list_, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
610+
inherited_handles_.data(),
611+
inherited_handles_.size() * sizeof(HANDLE), nullptr, nullptr)) {
612+
return CleanupAndReturnError();
613+
}
614+
startup_info.lpAttributeList = attribute_list_;
583615

584616
PROCESS_INFORMATION process_info;
585617
ZeroMemory(&process_info, sizeof(process_info));
@@ -601,6 +633,9 @@ class ProcessStarter {
601633
}
602634
child_process_handle_ = process_info.hProcess;
603635
CloseHandle(process_info.hThread);
636+
CloseHandle(stdin_handle);
637+
CloseHandle(stdout_handle);
638+
CloseHandle(stderr_handle);
604639

605640
// Return process id.
606641
*id_ = process_info.dwProcessId;

0 commit comments

Comments
 (0)