diff options
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r-- | runtime/runtime.cc | 106 |
1 files changed, 92 insertions, 14 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 370ee02790..433f564b2d 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -34,6 +34,7 @@ #include <cstdio> #include <cstdlib> #include <limits> +#include <string.h> #include <thread> #include <unordered_set> #include <vector> @@ -1004,12 +1005,19 @@ bool Runtime::Start() { !jit_options_->GetProfileSaverOptions().GetProfilePath().empty()) { std::vector<std::string> dex_filenames; Split(class_path_string_, ':', &dex_filenames); - // It's ok to pass "" to the ref profile filename. It indicates we don't have + + // We pass "" as the package name because at this point we don't know it. It could be the + // Zygote or it could be a dalvikvm cmd line execution. The package name will be re-set during + // post-fork or during RegisterAppInfo. + // + // Also, it's ok to pass "" to the ref profile filename. It indicates we don't have // a reference profile. RegisterAppInfo( + /*package_name=*/ "", dex_filenames, jit_options_->GetProfileSaverOptions().GetProfilePath(), - /*ref_profile_filename=*/ ""); + /*ref_profile_filename=*/ "", + kVMRuntimePrimaryApk); } return true; @@ -1056,6 +1064,22 @@ void Runtime::InitNonZygoteOrPostFork( DCHECK(!IsZygote()); if (is_system_server) { + // Register the system server code paths. + // TODO: Ideally this should be done by the VMRuntime#RegisterAppInfo. However, right now + // the method is only called when we set up the profile. It should be called all the time + // (simillar to the apps). Once that's done this manual registration can be removed. + const char* system_server_classpath = getenv("SYSTEMSERVERCLASSPATH"); + if (system_server_classpath == nullptr || (strlen(system_server_classpath) == 0)) { + LOG(WARNING) << "System server class path not set"; + } else { + std::vector<std::string> jars = android::base::Split(system_server_classpath, ":"); + app_info_.RegisterAppInfo("android", + jars, + /*cur_profile_path=*/ "", + /*ref_profile_path=*/ "", + AppInfo::CodeType::kPrimaryApk); + } + // Set the system server package name to "android". // This is used to tell the difference between samples provided by system server // and samples generated by other apps when processing boot image profiles. @@ -1101,6 +1125,8 @@ void Runtime::InitNonZygoteOrPostFork( session_data.session_id = GetRandomNumber<int64_t>(1, std::numeric_limits<int64_t>::max()); // TODO: set session_data.compilation_reason and session_data.compiler_filter metrics_reporter_->MaybeStartBackgroundThread(session_data); + // Also notify about any updates to the app info. + metrics_reporter_->NotifyAppInfoUpdated(&app_info_); } StartSignalCatcher(); @@ -1283,7 +1309,13 @@ void Runtime::InitializeApexVersions() { if (info == apex_infos.end() || info->second->getIsFactory()) { result += '/'; } else { - android::base::StringAppendF(&result, "/%" PRIu64, info->second->getVersionCode()); + // In case lastUpdateMillis field is populated in apex-info-list.xml, we + // prefer to use it as version scheme. If the field is missing we + // fallback to the version code of the APEX. + uint64_t version = info->second->hasLastUpdateMillis() + ? info->second->getLastUpdateMillis() + : info->second->getVersionCode(); + android::base::StringAppendF(&result, "/%" PRIu64, version); } } #endif @@ -1308,6 +1340,12 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // Reload all the flags value (from system properties and device configs). ReloadAllFlags(__FUNCTION__); + deny_art_apex_data_files_ = runtime_options.Exists(Opt::DenyArtApexDataFiles); + if (deny_art_apex_data_files_) { + // We will run slower without those files if the system has taken an ART APEX update. + LOG(WARNING) << "ART APEX data files are untrusted."; + } + // Early override for logging output. if (runtime_options.Exists(Opt::UseStderrLogger)) { android::base::SetLogger(android::base::StderrLogger); @@ -1316,6 +1354,7 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { MemMap::Init(); verifier_missing_kthrow_fatal_ = runtime_options.GetOrDefault(Opt::VerifierMissingKThrowFatal); + force_java_zygote_fork_loop_ = runtime_options.GetOrDefault(Opt::ForceJavaZygoteForkLoop); perfetto_hprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoHprof); perfetto_javaheapprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoJavaHeapStackProf); @@ -1371,7 +1410,21 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { } std::string system_oat_filename = ImageHeader::GetOatLocationFromImageLocation( GetSystemImageFilename(image_location_.c_str(), instruction_set_)); - std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation(image_location_); + std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation( + image_location_); + + if (deny_art_apex_data_files_ && (LocationIsOnArtApexData(system_oat_filename) || + LocationIsOnArtApexData(system_oat_location))) { + // This code path exists for completeness, but we don't expect it to be hit. + // + // `deny_art_apex_data_files` defaults to false unless set at the command-line. The image + // locations come from the -Ximage argument and it would need to be specified as being on + // the ART APEX data directory. This combination of flags would say apexdata is compromised, + // use apexdata to load image files, which is obviously not a good idea. + LOG(ERROR) << "Could not open boot oat file from untrusted location: " << system_oat_filename; + return false; + } + std::string error_msg; std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, system_oat_filename, @@ -1761,6 +1814,14 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { } } + // Now that the boot image space is set, cache the boot classpath checksums, + // to be used when validating oat files. + ArrayRef<gc::space::ImageSpace* const> image_spaces(GetHeap()->GetBootImageSpaces()); + ArrayRef<const DexFile* const> bcp_dex_files(GetClassLinker()->GetBootClassPath()); + boot_class_path_checksums_ = gc::space::ImageSpace::GetBootClassPathChecksums(image_spaces, + bcp_dex_files); + + // Cache the apex versions. InitializeApexVersions(); CHECK(class_linker_ != nullptr); @@ -2037,6 +2098,10 @@ void Runtime::InitNativeMethods() { // a regular JNI libraries with a regular JNI_OnLoad. Most JNI libraries can // just use System.loadLibrary, but libcore can't because it's the library // that implements System.loadLibrary! + // + // By setting calling class to java.lang.Object, the caller location for these + // JNI libs is core-oj.jar in the ART APEX, and hence they are loaded from the + // com_android_art linker namespace. // libicu_jni has to be initialized before libopenjdk{d} due to runtime dependency from // libopenjdk{d} to Icu4cMetadata native methods in libicu_jni. See http://b/143888405 @@ -2553,9 +2618,22 @@ void Runtime::ClearCalleeSaveMethods() { } } -void Runtime::RegisterAppInfo(const std::vector<std::string>& code_paths, +void Runtime::RegisterAppInfo(const std::string& package_name, + const std::vector<std::string>& code_paths, const std::string& profile_output_filename, - const std::string& ref_profile_filename) { + const std::string& ref_profile_filename, + int32_t code_type) { + app_info_.RegisterAppInfo( + package_name, + code_paths, + profile_output_filename, + ref_profile_filename, + AppInfo::FromVMRuntimeConstants(code_type)); + + if (metrics_reporter_ != nullptr) { + metrics_reporter_->NotifyAppInfoUpdated(&app_info_); + } + if (jit_.get() == nullptr) { // We are not JITing. Nothing to do. return; @@ -3127,6 +3205,8 @@ void Runtime::NotifyStartupCompleted() { return; } + VLOG(startup) << app_info_; + VLOG(startup) << "Adding NotifyStartupCompleted task"; // Use the heap task processor since we want to be exclusive with the GC and we don't want to // block the caller if the GC is running. @@ -3138,18 +3218,16 @@ void Runtime::NotifyStartupCompleted() { ProfileSaver::NotifyStartupCompleted(); if (metrics_reporter_ != nullptr) { - std::string compilation_reason; - CompilerFilter::Filter compiler_filter; - if (oat_file_manager_->GetPrimaryOatFileInfo(&compilation_reason, &compiler_filter)) { - metrics_reporter_->SetCompilationInfo( - compilation_reason.empty() ? metrics::CompilationReasonFromName(compilation_reason) - : metrics::CompilationReason::kUnknown, - compiler_filter); - } metrics_reporter_->NotifyStartupCompleted(); } } +void Runtime::NotifyDexFileLoaded() { + if (metrics_reporter_ != nullptr) { + metrics_reporter_->NotifyAppInfoUpdated(&app_info_); + } +} + bool Runtime::GetStartupCompleted() const { return startup_completed_.load(std::memory_order_seq_cst); } |