Adjust the dladdr-based introspection logic used in art::GetAndroidRootSafe.
This logic originally assumed that the libartbase library linked into
the current binary was always located in a directory within the
Android Root. This is no longer true on target since libartbase moved
to the Runtime APEX; therefore we now only use that logic on host in
art::GetAndroidRootSafe.
Eventually we should be able to use this logic on target to find the
Android Runtime Root (in art::GetAndroidRuntimeRootSafe), as
libartbase is installed in the Runtime APEX. However, this is not
always true at the moment, as ART gtests still install another copy of
libartbase in /system/lib(64) (the Android Root) on target.
Also improve the documentation of methods `art::GetAndroidRoot(Safe)`
and `art::GetAndroidRuntimeRoot(Safe)`.
Test: m test-art-host-gtest-file_utils_test
Bug: 121117762
Bug: 129534335
Change-Id: I835207110dae0a550c06ac98ed4915241cc61c6f
diff --git a/libartbase/base/file_utils_test.cc b/libartbase/base/file_utils_test.cc
index 0a5a7a7..a217770 100644
--- a/libartbase/base/file_utils_test.cc
+++ b/libartbase/base/file_utils_test.cc
@@ -79,19 +79,22 @@
ASSERT_EQ(0, setenv("ANDROID_ROOT", "/this/is/obviously/bogus", /* overwrite */ 1));
EXPECT_EQ(GetAndroidRootSafe(&error_msg), "");
- // Unset ANDROID_ROOT and see that it still returns something (as libart code is running).
- ASSERT_EQ(0, unsetenv("ANDROID_ROOT"));
- std::string android_root3 = GetAndroidRootSafe(&error_msg);
- // This should be the same as the other root (modulo realpath), otherwise the test setup is
- // broken. On non-bionic. On bionic we can be running with a different libart that lives outside
- // of ANDROID_ROOT
- UniqueCPtr<char> real_root3(realpath(android_root3.c_str(), nullptr));
+ // Inferring the Android Root from the location of libartbase only works on host.
+ if (!kIsTargetBuild) {
+ // Unset ANDROID_ROOT and see that it still returns something (as libartbase code is running).
+ ASSERT_EQ(0, unsetenv("ANDROID_ROOT"));
+ std::string android_root3 = GetAndroidRootSafe(&error_msg);
+ // This should be the same as the other root (modulo realpath), otherwise the test setup is
+ // broken. On non-bionic. On bionic we can be running with a different libartbase that lives
+ // outside of ANDROID_ROOT.
+ UniqueCPtr<char> real_root3(realpath(android_root3.c_str(), nullptr));
#if !defined(__BIONIC__ ) || defined(__ANDROID__)
- UniqueCPtr<char> real_root(realpath(android_root.c_str(), nullptr));
- EXPECT_STREQ(real_root.get(), real_root3.get()) << error_msg;
+ UniqueCPtr<char> real_root(realpath(android_root.c_str(), nullptr));
+ EXPECT_STREQ(real_root.get(), real_root3.get()) << error_msg;
#else
- EXPECT_STRNE(real_root3.get(), "") << error_msg;
+ EXPECT_STRNE(real_root3.get(), "") << error_msg;
#endif
+ }
// Reset ANDROID_ROOT, as other things may depend on it.
ASSERT_EQ(0, setenv("ANDROID_ROOT", android_root_env.c_str(), /* overwrite */ 1));
@@ -118,6 +121,32 @@
ASSERT_EQ(0, setenv("ANDROID_RUNTIME_ROOT", "/this/is/obviously/bogus", /* overwrite */ 1));
EXPECT_EQ(GetAndroidRuntimeRootSafe(&error_msg), "");
+ // Inferring the Android Runtime Root from the location of libartbase only works on target.
+ if (kIsTargetBuild) {
+ // Disabled for now, as we cannot reliably use `GetRootContainingLibartbase`
+ // to find the Android Runtime Root on target yet (see comment in
+ // `GetAndroidRuntimeRootSafe`).
+ //
+ // TODO(b/129534335): Re-enable this part of the test on target when the
+ // only instance of libartbase is the one from the Runtime APEX.
+ if ((false)) {
+ // Unset ANDROID_RUNTIME_ROOT and see that it still returns something (as
+ // libartbase code is running).
+ ASSERT_EQ(0, unsetenv("ANDROID_RUNTIME_ROOT"));
+ std::string android_runtime_root3 = GetAndroidRuntimeRootSafe(&error_msg);
+ // This should be the same as the other root (modulo realpath), otherwise
+ // the test setup is broken. On non-bionic. On bionic we can be running
+ // with a different libartbase that lives outside of ANDROID_RUNTIME_ROOT.
+ UniqueCPtr<char> real_root3(realpath(android_runtime_root3.c_str(), nullptr));
+#if !defined(__BIONIC__ ) || defined(__ANDROID__)
+ UniqueCPtr<char> real_root(realpath(android_runtime_root.c_str(), nullptr));
+ EXPECT_STREQ(real_root.get(), real_root3.get()) << error_msg;
+#else
+ EXPECT_STRNE(real_root3.get(), "") << error_msg;
+#endif
+ }
+ }
+
// Reset ANDROID_RUNTIME_ROOT, as other things may depend on it.
ASSERT_EQ(0, setenv("ANDROID_RUNTIME_ROOT", android_runtime_root_env.c_str(), /* overwrite */ 1));
}