Revert^2 "Avoid crash when ANDROID_DATA is not writeable."
This reverts commit c702e34372e7120d3b99a42d9a226c6c036b5d17.
Fix the new test when running as root. Instead of relying on
directory permissions (which are ignored for root), create
a dummy file "dalvik-cache" to prevent the creation of the
directory "dalvik-cache/<isa>".
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Pixel 2 XL boots.
Test: m test-art-target-gtest
Bug: 112848347
Bug: 112827048
Change-Id: I0fad66c876c5dd062a38aacc15cdd21c374cc96f
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index eebb103..2a4803a 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1454,6 +1454,7 @@
has_system_(false),
has_cache_(false),
is_global_cache_(true),
+ dalvik_cache_exists_(false),
dalvik_cache_(),
cache_filename_() {
}
@@ -1462,33 +1463,30 @@
void FindImageFiles() {
std::string system_filename;
- bool dalvik_cache_exists = false;
bool found_image = FindImageFilenameImpl(image_location_.c_str(),
image_isa_,
&has_system_,
&system_filename,
- &dalvik_cache_exists,
+ &dalvik_cache_exists_,
&dalvik_cache_,
&is_global_cache_,
&has_cache_,
&cache_filename_);
- DCHECK_EQ(dalvik_cache_exists, !dalvik_cache_.empty());
+ DCHECK(!dalvik_cache_exists_ || !dalvik_cache_.empty());
DCHECK_EQ(found_image, has_system_ || has_cache_);
}
bool HasSystem() const { return has_system_; }
bool HasCache() const { return has_cache_; }
- bool DalvikCacheExists() const { return !dalvik_cache_.empty(); }
+ bool DalvikCacheExists() const { return dalvik_cache_exists_; }
bool IsGlobalCache() const { return is_global_cache_; }
const std::string& GetDalvikCache() const {
- DCHECK(DalvikCacheExists());
return dalvik_cache_;
}
const std::string& GetCacheFilename() const {
- DCHECK(DalvikCacheExists());
return cache_filename_;
}
@@ -1617,6 +1615,7 @@
bool has_system_;
bool has_cache_;
bool is_global_cache_;
+ bool dalvik_cache_exists_;
std::string dalvik_cache_;
std::string cache_filename_;
};
@@ -1769,7 +1768,7 @@
// Step 3: We do not have an existing image in /system,
// so generate an image into the dalvik cache.
- if (!loader.HasSystem()) {
+ if (!loader.HasSystem() && loader.DalvikCacheExists()) {
std::string local_error_msg;
if (!dex2oat_enabled) {
local_error_msg = "Image compilation disabled.";
diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc
index f202a43..a1ffa06 100644
--- a/runtime/gc/space/image_space_test.cc
+++ b/runtime/gc/space/image_space_test.cc
@@ -150,6 +150,48 @@
EXPECT_FALSE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
}
+class NoAccessAndroidDataTest : public ImageSpaceLoadingTest<false, true, false, true> {
+ protected:
+ void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE {
+ const char* android_data = getenv("ANDROID_DATA");
+ CHECK(android_data != nullptr);
+ old_android_data_ = android_data;
+ bad_android_data_ = old_android_data_ + "/no-android-data";
+ int result = setenv("ANDROID_DATA", bad_android_data_.c_str(), /* replace */ 1);
+ CHECK_EQ(result, 0) << strerror(errno);
+ result = mkdir(bad_android_data_.c_str(), /* mode */ 0700);
+ CHECK_EQ(result, 0) << strerror(errno);
+ // Create a regular file "dalvik_cache". GetDalvikCache() shall get EEXIST
+ // when trying to create a directory with the same name and creating a
+ // subdirectory for a particular architecture shall fail.
+ bad_dalvik_cache_ = bad_android_data_ + "/dalvik-cache";
+ int fd = creat(bad_dalvik_cache_.c_str(), /* mode */ 0);
+ CHECK_NE(fd, -1) << strerror(errno);
+ result = close(fd);
+ CHECK_EQ(result, 0) << strerror(errno);
+ ImageSpaceLoadingTest<false, true, false, true>::SetUpRuntimeOptions(options);
+ }
+
+ void TearDown() OVERRIDE {
+ int result = unlink(bad_dalvik_cache_.c_str());
+ CHECK_EQ(result, 0) << strerror(errno);
+ result = rmdir(bad_android_data_.c_str());
+ CHECK_EQ(result, 0) << strerror(errno);
+ result = setenv("ANDROID_DATA", old_android_data_.c_str(), /* replace */ 1);
+ CHECK_EQ(result, 0) << strerror(errno);
+ ImageSpaceLoadingTest<false, true, false, true>::TearDown();
+ }
+
+ private:
+ std::string old_android_data_;
+ std::string bad_android_data_;
+ std::string bad_dalvik_cache_;
+};
+
+TEST_F(NoAccessAndroidDataTest, Test) {
+ EXPECT_TRUE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
+}
+
} // namespace space
} // namespace gc
} // namespace art