Skip to content

Commit d870a71

Browse files
bkonyicommit-bot@chromium.org
authored and
commit-bot@chromium.org
committed
[ VM ] Print a meaningful error message when a user attempts to run an AOT snapshot with a JIT VM.
Fixes #42482 Change-Id: I284a5673e30f59b127e69c712df93552cdfcde41 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154834 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
1 parent eae54cf commit d870a71

File tree

7 files changed

+153
-3
lines changed

7 files changed

+153
-3
lines changed

runtime/bin/main.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,9 +1221,16 @@ void main(int argc, char** argv) {
12211221
#endif // !defined(DART_PRECOMPILED_RUNTIME)
12221222

12231223
if (should_run_user_program) {
1224-
// Run the main isolate until we aren't told to restart.
1225-
while (RunMainIsolate(script_name, &dart_options)) {
1226-
Syslog::PrintErr("Restarting VM\n");
1224+
if (!Dart_IsPrecompiledRuntime() && Snapshot::IsAOTSnapshot(script_name)) {
1225+
Syslog::PrintErr(
1226+
"%s is an AOT snapshot and should be run with 'dartaotruntime'\n",
1227+
script_name);
1228+
Platform::Exit(kErrorExitCode);
1229+
} else {
1230+
// Run the main isolate until we aren't told to restart.
1231+
while (RunMainIsolate(script_name, &dart_options)) {
1232+
Syslog::PrintErr("Restarting VM\n");
1233+
}
12271234
}
12281235
}
12291236

runtime/bin/snapshot_utils.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,5 +537,24 @@ void Snapshot::GenerateAppAOTAsAssembly(const char* snapshot_filename) {
537537
}
538538
}
539539

540+
bool Snapshot::IsAOTSnapshot(const char* snapshot_filename) {
541+
// Header is simply "ELF" prefixed with the DEL character.
542+
const char elf_header[] = {0x7F, 0x45, 0x4C, 0x46};
543+
const int64_t elf_header_len = strlen(elf_header);
544+
File* file = File::Open(NULL, snapshot_filename, File::kRead);
545+
if (file == nullptr) {
546+
return false;
547+
}
548+
if (file->Length() < elf_header_len) {
549+
file->Release();
550+
return false;
551+
}
552+
auto buf = std::unique_ptr<char[]>(new char[elf_header_len]);
553+
bool success = file->ReadFully(buf.get(), elf_header_len);
554+
file->Release();
555+
ASSERT(success);
556+
return (strncmp(elf_header, buf.get(), elf_header_len) == 0);
557+
}
558+
540559
} // namespace bin
541560
} // namespace dart

runtime/bin/snapshot_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class Snapshot {
3434
static void GenerateAppJIT(const char* snapshot_filename);
3535
static void GenerateAppAOTAsAssembly(const char* snapshot_filename);
3636

37+
// Returns true if snapshot_filename points to an AOT snapshot (aka,
38+
// an ELF binary). May report false negatives.
39+
static bool IsAOTSnapshot(const char* snapshot_filename);
40+
3741
static AppSnapshot* TryReadAppendedAppSnapshotElf(const char* container_path);
3842
static AppSnapshot* TryReadAppSnapshot(
3943
const char* script_uri,
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
import 'dart:io';
5+
6+
import 'package:expect/expect.dart';
7+
import 'package:path/path.dart' as path;
8+
9+
main() {
10+
final buildDir = path.dirname(Platform.executable);
11+
final sdkDir = path.dirname(path.dirname(buildDir));
12+
final platformDill = path.join(buildDir, 'vm_platform_strong.dill');
13+
final genSnapshot = path.join(buildDir, 'gen_snapshot');
14+
15+
final exePath = Platform.resolvedExecutable;
16+
final genSnapshotPath =
17+
Uri.parse(Platform.executable).resolve('gen_snapshot').path;
18+
final powTest = Platform.script.resolve('pow_test.dart').path;
19+
final d = Directory.systemTemp.createTempSync('aot_tmp');
20+
final kernelOutput = d.uri.resolve('pow_test.dill').path;
21+
final aotOutput = d.uri.resolve('pow_test.aot').path;
22+
23+
final genKernelResult = Process.runSync(
24+
'pkg/vm/tool/gen_kernel',
25+
[
26+
'--aot',
27+
'--platform=$platformDill',
28+
'-o',
29+
kernelOutput,
30+
powTest,
31+
],
32+
);
33+
Expect.equals(genKernelResult.exitCode, 0);
34+
35+
final genAotResult = Process.runSync(
36+
genSnapshot,
37+
[
38+
'--snapshot_kind=app-aot-elf',
39+
'--elf=$aotOutput',
40+
kernelOutput,
41+
],
42+
);
43+
Expect.equals(genAotResult.exitCode, 0);
44+
45+
final runAotResult = Process.runSync(
46+
exePath,
47+
[
48+
'run',
49+
aotOutput,
50+
],
51+
);
52+
Expect.equals(runAotResult.exitCode, 255);
53+
Expect.stringContainsInOrder(
54+
runAotResult.stderr,
55+
[
56+
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
57+
],
58+
);
59+
}

tests/standalone/standalone_precompiled.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
dwarf_stack_trace_test: Pass, RuntimeError # Issue 35563
77

88
[ $runtime == dart_precompiled ]
9+
check_for_aot_snapshot_jit_test: SkipByDesign
910
http_launch_test: Skip
1011
io/addlatexhash_test: Skip
1112
io/dart_std_io_pipe_test: Skip
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
import 'dart:io';
5+
6+
import 'package:expect/expect.dart';
7+
import 'package:path/path.dart' as path;
8+
9+
main() {
10+
final buildDir = path.dirname(Platform.executable);
11+
final sdkDir = path.dirname(path.dirname(buildDir));
12+
final platformDill = path.join(buildDir, 'vm_platform_strong.dill');
13+
final genSnapshot = path.join(buildDir, 'gen_snapshot');
14+
15+
final exePath = Platform.resolvedExecutable;
16+
final genSnapshotPath =
17+
Uri.parse(Platform.executable).resolve('gen_snapshot').path;
18+
final powTest = Platform.script.resolve('pow_test.dart').path;
19+
final d = Directory.systemTemp.createTempSync('aot_tmp');
20+
final kernelOutput = d.uri.resolve('pow_test.dill').path;
21+
final aotOutput = d.uri.resolve('pow_test.aot').path;
22+
23+
final genKernelResult = Process.runSync(
24+
'pkg/vm/tool/gen_kernel',
25+
[
26+
'--aot',
27+
'--platform=$platformDill',
28+
'-o',
29+
kernelOutput,
30+
powTest,
31+
],
32+
);
33+
Expect.equals(genKernelResult.exitCode, 0);
34+
35+
final genAotResult = Process.runSync(
36+
genSnapshot,
37+
[
38+
'--snapshot_kind=app-aot-elf',
39+
'--elf=$aotOutput',
40+
kernelOutput,
41+
],
42+
);
43+
Expect.equals(genAotResult.exitCode, 0);
44+
45+
final runAotResult = Process.runSync(
46+
exePath,
47+
[
48+
'run',
49+
aotOutput,
50+
],
51+
);
52+
Expect.equals(runAotResult.exitCode, 255);
53+
Expect.stringContainsInOrder(
54+
runAotResult.stderr,
55+
[
56+
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
57+
],
58+
);
59+
}

tests/standalone_2/standalone_2_precompiled.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# BSD-style license that can be found in the LICENSE file.
44

55
[ $runtime == dart_precompiled ]
6+
check_for_aot_snapshot_jit_test: SkipByDesign
67
http_launch_test: Skip
78
io/addlatexhash_test: Skip
89
io/dart_std_io_pipe_test: Skip

0 commit comments

Comments
 (0)