未验证 提交 42069bef 编写于 作者: C Chinmay Garde 提交者: GitHub

Fix runtime_unittest in AOT mode by loading AOT symbols from ELF loader. (#16283)

This regressed when the symbols were no longer packed in discrete blobs but
instead moved to an ELF file.

Regressed in https://github.com/flutter/engine/commit/d9080029af4b917fd5813c1db7f96d509343e01e
Unnoticed because of https://github.com/flutter/flutter/issues/49733
Fixes https://github.com/flutter/flutter/issues/49763
上级 e625e174
......@@ -147,6 +147,7 @@ source_set("runtime_unittests_common") {
"$flutter_root/shell/common",
"$flutter_root/testing:dart",
"$flutter_root/third_party/tonic",
"//third_party/dart/runtime/bin:elf_loader",
"//third_party/skia",
]
}
......
......@@ -4,17 +4,65 @@
#include "flutter/runtime/runtime_test.h"
#include "flutter/fml/file.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "flutter/runtime/dart_snapshot.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/testing/testing.h"
namespace flutter {
namespace testing {
static constexpr const char* kAOTAppELFFileName = "app_elf_snapshot.so";
static ELFAOTSymbols LoadELFIfNecessary() {
if (!DartVM::IsRunningPrecompiledCode()) {
return {};
}
const auto elf_path =
fml::paths::JoinPaths({GetFixturesPath(), kAOTAppELFFileName});
if (!fml::IsFile(elf_path)) {
FML_LOG(ERROR) << "App AOT file does not exist for this fixture. Attempts "
"to launch the Dart VM will fail.";
return {};
}
ELFAOTSymbols symbols;
// Must not be freed.
const char* error = nullptr;
auto loaded_elf =
Dart_LoadELF(elf_path.c_str(), // file path
0, // file offset
&error, // error (out)
&symbols.vm_snapshot_data, // vm snapshot data (out)
&symbols.vm_snapshot_instrs, // vm snapshot instrs (out)
&symbols.vm_isolate_data, // vm isolate data (out)
&symbols.vm_isolate_instrs // vm isolate instr (out)
);
if (loaded_elf == nullptr) {
FML_LOG(ERROR) << "Could not fetch AOT symbols from loaded ELF. Attempts "
"to launch the Dart VM will fail. Error: "
<< error;
return {};
}
symbols.loaded_elf.reset(loaded_elf);
return symbols;
}
RuntimeTest::RuntimeTest()
: native_resolver_(std::make_shared<TestDartNativeResolver>()),
assets_dir_(fml::OpenDirectory(GetFixturesPath(),
false,
fml::FilePermission::kRead)) {}
fml::FilePermission::kRead)),
aot_symbols_(LoadELFIfNecessary()) {}
void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) {
if (!assets_dir_.is_valid()) {
......@@ -24,28 +72,25 @@ void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) {
settings.assets_dir = assets_dir_.get();
// In JIT execution, all snapshots are present within the binary itself and
// don't need to be explicitly suppiled by the embedder.
// don't need to be explicitly supplied by the embedder. In AOT, these
// snapshots will be present in the application AOT dylib.
if (DartVM::IsRunningPrecompiledCode()) {
settings.vm_snapshot_data = [this]() {
return fml::FileMapping::CreateReadOnly(assets_dir_, "vm_snapshot_data");
settings.vm_snapshot_data = [&]() {
return std::make_unique<fml::NonOwnedMapping>(
aot_symbols_.vm_snapshot_data, 0u);
};
settings.isolate_snapshot_data = [this]() {
return fml::FileMapping::CreateReadOnly(assets_dir_,
"isolate_snapshot_data");
settings.isolate_snapshot_data = [&]() {
return std::make_unique<fml::NonOwnedMapping>(
aot_symbols_.vm_isolate_data, 0u);
};
settings.vm_snapshot_instr = [&]() {
return std::make_unique<fml::NonOwnedMapping>(
aot_symbols_.vm_snapshot_instrs, 0u);
};
settings.isolate_snapshot_instr = [&]() {
return std::make_unique<fml::NonOwnedMapping>(
aot_symbols_.vm_isolate_instrs, 0u);
};
if (DartVM::IsRunningPrecompiledCode()) {
settings.vm_snapshot_instr = [this]() {
return fml::FileMapping::CreateReadExecute(assets_dir_,
"vm_snapshot_instr");
};
settings.isolate_snapshot_instr = [this]() {
return fml::FileMapping::CreateReadExecute(assets_dir_,
"isolate_snapshot_instr");
};
}
} else {
settings.application_kernels = [this]() {
std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
......
......@@ -11,10 +11,25 @@
#include "flutter/fml/macros.h"
#include "flutter/testing/test_dart_native_resolver.h"
#include "flutter/testing/thread_test.h"
#include "third_party/dart/runtime/bin/elf_loader.h"
namespace flutter {
namespace testing {
struct LoadedELFDeleter {
void operator()(Dart_LoadedElf* elf) { Dart_UnloadELF(elf); }
};
using UniqueLoadedELF = std::unique_ptr<Dart_LoadedElf, LoadedELFDeleter>;
struct ELFAOTSymbols {
UniqueLoadedELF loaded_elf;
const uint8_t* vm_snapshot_data = nullptr;
const uint8_t* vm_snapshot_instrs = nullptr;
const uint8_t* vm_isolate_data = nullptr;
const uint8_t* vm_isolate_instrs = nullptr;
};
class RuntimeTest : public ThreadTest {
public:
RuntimeTest();
......@@ -24,10 +39,11 @@ class RuntimeTest : public ThreadTest {
void AddNativeCallback(std::string name, Dart_NativeFunction callback);
private:
void SetSnapshotsAndAssets(Settings& settings);
std::shared_ptr<TestDartNativeResolver> native_resolver_;
fml::UniqueFD assets_dir_;
ELFAOTSymbols aot_symbols_;
void SetSnapshotsAndAssets(Settings& settings);
FML_DISALLOW_COPY_AND_ASSIGN(RuntimeTest);
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册