Avoid dynamic lookups of the engine library's symbols on Android (flutter/engine#11001)
The dynamic linker on some older versions of Android on x86 fails when doing dlsym(RTLD_DEFAULT) lookups of symbols exported by the engine library itself. The engine needs to do this for some data files that are linked into the engine library (ICU data and Dart snapshot blobs). To work around this, the engine will declare static symbols for these data objects on the affected platforms. Fixes https://github.com/flutter/flutter/issues/20091
This commit is contained in:
@@ -20,6 +20,14 @@ const char* DartSnapshot::kIsolateDataSymbol = "kDartIsolateSnapshotData";
|
||||
const char* DartSnapshot::kIsolateInstructionsSymbol =
|
||||
"kDartIsolateSnapshotInstructions";
|
||||
|
||||
// On Windows and Android (in debug mode) the engine finds the Dart snapshot
|
||||
// data through symbols that are statically linked into the executable.
|
||||
// On other platforms this data is obtained by a dynamic symbol lookup.
|
||||
#define DART_SNAPSHOT_STATIC_LINK \
|
||||
(OS_WIN || (OS_ANDROID && FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG))
|
||||
|
||||
#if !DART_SNAPSHOT_STATIC_LINK
|
||||
|
||||
static std::unique_ptr<const fml::Mapping> GetFileMapping(
|
||||
const std::string& path,
|
||||
bool executable) {
|
||||
@@ -83,11 +91,13 @@ static std::shared_ptr<const fml::Mapping> SearchMapping(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // !DART_SNAPSHOT_STATIC_LINK
|
||||
|
||||
static std::shared_ptr<const fml::Mapping> ResolveVMData(
|
||||
const Settings& settings) {
|
||||
#if OS_WIN
|
||||
#if DART_SNAPSHOT_STATIC_LINK
|
||||
return std::make_unique<fml::NonOwnedMapping>(kDartVmSnapshotData, 0);
|
||||
#else // OS_WIN
|
||||
#else // DART_SNAPSHOT_STATIC_LINK
|
||||
return SearchMapping(
|
||||
settings.vm_snapshot_data, // embedder_mapping_callback
|
||||
settings.vm_snapshot_data_path, // file_path
|
||||
@@ -95,14 +105,14 @@ static std::shared_ptr<const fml::Mapping> ResolveVMData(
|
||||
DartSnapshot::kVMDataSymbol, // native_library_symbol_name
|
||||
false // is_executable
|
||||
);
|
||||
#endif // OS_WIN
|
||||
#endif // DART_SNAPSHOT_STATIC_LINK
|
||||
}
|
||||
|
||||
static std::shared_ptr<const fml::Mapping> ResolveVMInstructions(
|
||||
const Settings& settings) {
|
||||
#if OS_WIN
|
||||
#if DART_SNAPSHOT_STATIC_LINK
|
||||
return std::make_unique<fml::NonOwnedMapping>(kDartVmSnapshotInstructions, 0);
|
||||
#else // OS_WIN
|
||||
#else // DART_SNAPSHOT_STATIC_LINK
|
||||
return SearchMapping(
|
||||
settings.vm_snapshot_instr, // embedder_mapping_callback
|
||||
settings.vm_snapshot_instr_path, // file_path
|
||||
@@ -110,14 +120,14 @@ static std::shared_ptr<const fml::Mapping> ResolveVMInstructions(
|
||||
DartSnapshot::kVMInstructionsSymbol, // native_library_symbol_name
|
||||
true // is_executable
|
||||
);
|
||||
#endif // OS_WIN
|
||||
#endif // DART_SNAPSHOT_STATIC_LINK
|
||||
}
|
||||
|
||||
static std::shared_ptr<const fml::Mapping> ResolveIsolateData(
|
||||
const Settings& settings) {
|
||||
#if OS_WIN
|
||||
#if DART_SNAPSHOT_STATIC_LINK
|
||||
return std::make_unique<fml::NonOwnedMapping>(kDartIsolateSnapshotData, 0);
|
||||
#else // OS_WIN
|
||||
#else // DART_SNAPSHOT_STATIC_LINK
|
||||
return SearchMapping(
|
||||
settings.isolate_snapshot_data, // embedder_mapping_callback
|
||||
settings.isolate_snapshot_data_path, // file_path
|
||||
@@ -125,15 +135,15 @@ static std::shared_ptr<const fml::Mapping> ResolveIsolateData(
|
||||
DartSnapshot::kIsolateDataSymbol, // native_library_symbol_name
|
||||
false // is_executable
|
||||
);
|
||||
#endif // OS_WIN
|
||||
#endif // DART_SNAPSHOT_STATIC_LINK
|
||||
}
|
||||
|
||||
static std::shared_ptr<const fml::Mapping> ResolveIsolateInstructions(
|
||||
const Settings& settings) {
|
||||
#if OS_WIN
|
||||
#if DART_SNAPSHOT_STATIC_LINK
|
||||
return std::make_unique<fml::NonOwnedMapping>(
|
||||
kDartIsolateSnapshotInstructions, 0);
|
||||
#else // OS_WIN
|
||||
#else // DART_SNAPSHOT_STATIC_LINK
|
||||
return SearchMapping(
|
||||
settings.isolate_snapshot_instr, // embedder_mapping_callback
|
||||
settings.isolate_snapshot_instr_path, // file_path
|
||||
@@ -141,7 +151,7 @@ static std::shared_ptr<const fml::Mapping> ResolveIsolateInstructions(
|
||||
DartSnapshot::kIsolateInstructionsSymbol, // native_library_symbol_name
|
||||
true // is_executable
|
||||
);
|
||||
#endif // OS_WIN
|
||||
#endif // DART_SNAPSHOT_STATIC_LINK
|
||||
}
|
||||
|
||||
fml::RefPtr<DartSnapshot> DartSnapshot::VMSnapshotFromSettings(
|
||||
|
||||
@@ -53,6 +53,20 @@ static const std::string gDartFlagsWhitelist[] = {
|
||||
// Include again for struct definition.
|
||||
#include "flutter/shell/common/switches.h"
|
||||
|
||||
// Define symbols for the ICU data that is linked into the Flutter library on
|
||||
// Android. This is a workaround for crashes seen when doing dynamic lookups
|
||||
// of the engine's own symbols on some older versions of Android.
|
||||
#if OS_ANDROID
|
||||
extern uint8_t _binary_icudtl_dat_start[];
|
||||
extern uint8_t _binary_icudtl_dat_end[];
|
||||
|
||||
static std::unique_ptr<fml::Mapping> GetICUStaticMapping() {
|
||||
return std::make_unique<fml::NonOwnedMapping>(
|
||||
_binary_icudtl_dat_start,
|
||||
_binary_icudtl_dat_end - _binary_icudtl_dat_start);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace flutter {
|
||||
|
||||
void PrintUsage(const std::string& executable_name) {
|
||||
@@ -298,9 +312,14 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
|
||||
&icu_symbol_prefix);
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::ICUNativeLibPath),
|
||||
&native_lib_path);
|
||||
|
||||
#if OS_ANDROID
|
||||
settings.icu_mapper = GetICUStaticMapping;
|
||||
#else
|
||||
settings.icu_mapper = [icu_symbol_prefix, native_lib_path] {
|
||||
return GetSymbolMapping(icu_symbol_prefix, native_lib_path);
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user