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