Work around relocated boot.oat corruption
Bug: 18143314
(cherry picked from commit 7dd7261845258b7c29b588829c80164b878f4424)
Change-Id: I70e708940663bf53ebe5320f53fd2dcebb0c623f
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 5b77540..6e1639c 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -115,18 +115,6 @@
CHECK_EQ(0, TEMP_FAILURE_RETRY(closedir(cache_dir))) << "Unable to close directory.";
}
-static void RemoveImageFiles(const std::string& image_filename, std::string* error_msg) {
- if (TEMP_FAILURE_RETRY(unlink(image_filename.c_str())) != 0) {
- *error_msg = StringPrintf("Failed to remove image file after previous error: %s",
- error_msg->c_str());
- }
- std::string oat_filename(ImageHeader::GetOatLocationFromImageLocation(image_filename));
- if (TEMP_FAILURE_RETRY(unlink(oat_filename.c_str())) != 0) {
- *error_msg = StringPrintf("Failed to remove oat file after previous error: %s",
- error_msg->c_str());
- }
-}
-
static bool GenerateImage(const std::string& image_filename, InstructionSet image_isa,
std::string* error_msg) {
const std::string boot_class_path_string(Runtime::Current()->GetBootClassPathString());
@@ -445,7 +433,11 @@
*error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s': %s",
image_location, system_filename.c_str(),
cache_filename.c_str(), reason.c_str());
- RemoveImageFiles(cache_filename, error_msg);
+ // We failed to create files, remove any possibly garbage output.
+ // Since ImageCreationAllowed was true above, we are the zygote
+ // and therefore the only process expected to generate these for
+ // the device.
+ PruneDexCache(image_isa);
return nullptr;
}
}
@@ -492,19 +484,23 @@
return space;
}
- // If the /system file exists, it should be up-to-date, don't try to generate it. Same if it is
- // a relocated copy from something in /system (i.e. checksum's match).
- // Otherwise, log a warning and fall through to GenerateImage.
if (relocated_version_used) {
- LOG(FATAL) << "Attempted to use relocated version of " << image_location << " "
- << "at " << cache_filename << " generated from " << system_filename << " "
- << "but image failed to load: " << *error_msg;
+ // Something is wrong with the relocated copy (even though checksums match). Cleanup.
+ // This can happen if the .oat is corrupt, since the above only checks the .art checksums.
+ // TODO: Check the oat file validity earlier.
+ *error_msg = StringPrintf("Attempted to use relocated version of %s at %s generated from %s "
+ "but image failed to load: %s",
+ image_location, cache_filename.c_str(), system_filename.c_str(),
+ error_msg->c_str());
+ PruneDexCache(image_isa);
return nullptr;
} else if (is_system) {
+ // If the /system file exists, it should be up-to-date, don't try to generate it.
*error_msg = StringPrintf("Failed to load /system image '%s': %s",
image_filename->c_str(), error_msg->c_str());
return nullptr;
} else {
+ // Otherwise, log a warning and fall through to GenerateImage.
LOG(WARNING) << *error_msg;
}
}
@@ -520,7 +516,11 @@
} else if (!GenerateImage(cache_filename, image_isa, error_msg)) {
*error_msg = StringPrintf("Failed to generate image '%s': %s",
cache_filename.c_str(), error_msg->c_str());
- RemoveImageFiles(cache_filename, error_msg);
+ // We failed to create files, remove any possibly garbage output.
+ // Since ImageCreationAllowed was true above, we are the zygote
+ // and therefore the only process expected to generate these for
+ // the device.
+ PruneDexCache(image_isa);
return nullptr;
} else {
// Note that we must not use the file descriptor associated with