From c5b215f7004c46a274a54e232f0cd146c7494f9a Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Tue, 12 Sep 2017 14:49:37 -0700 Subject: Update the context classpath after the dex files are opened. The classpath stored in the context maybe be out of sync with the list of opened dex files if any of the dex file is a multidex or cannot be opened. This CL ensures that OpenDexFiles updates the classpath with the dex file locations that were open. The change does not affect the current use of ClassLoaderContext. It is a preparatory step for b/62269291 Bug: 62269291 Test: m test-art-host-gtest-class_loader_context_test Change-Id: Ibe675df9b2c06a4df8189f0d72df8b4061603a0e --- runtime/class_loader_context_test.cc | 147 +++++++++++++---------------------- 1 file changed, 56 insertions(+), 91 deletions(-) (limited to 'runtime/class_loader_context_test.cc') diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc index 18472743fb..ae3dcecb4a 100644 --- a/runtime/class_loader_context_test.cc +++ b/runtime/class_loader_context_test.cc @@ -87,60 +87,29 @@ class ClassLoaderContextTest : public CommonRuntimeTest { void VerifyOpenDexFiles( ClassLoaderContext* context, size_t index, - std::vector>*>& all_dex_files, - LocationCheck mode = LocationCheck::kEquals, - BaseLocationCheck base_mode = BaseLocationCheck::kEquals) { + std::vector>* all_dex_files) { ASSERT_TRUE(context != nullptr); ASSERT_TRUE(context->dex_files_open_attempted_); ASSERT_TRUE(context->dex_files_open_result_); ClassLoaderContext::ClassLoaderInfo& info = context->class_loader_chain_[index]; - ASSERT_EQ(all_dex_files.size(), info.classpath.size()); + ASSERT_EQ(all_dex_files->size(), info.classpath.size()); + ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size()); size_t cur_open_dex_index = 0; - for (size_t k = 0; k < all_dex_files.size(); k++) { - std::vector>& dex_files_for_cp_elem = *(all_dex_files[k]); - for (size_t i = 0; i < dex_files_for_cp_elem.size(); i++) { - ASSERT_LT(cur_open_dex_index, info.opened_dex_files.size()); - - std::unique_ptr& opened_dex_file = + for (size_t k = 0; k < all_dex_files->size(); k++) { + std::unique_ptr& opened_dex_file = info.opened_dex_files[cur_open_dex_index++]; - std::unique_ptr& expected_dex_file = dex_files_for_cp_elem[i]; - - std::string expected_location = expected_dex_file->GetBaseLocation(); - UniqueCPtr expected_real_location( - realpath(expected_location.c_str(), nullptr)); - ASSERT_TRUE(expected_real_location != nullptr) << expected_location; - expected_location.assign(expected_real_location.get()); - expected_location += DexFile::GetMultiDexSuffix(expected_dex_file->GetLocation()); - - switch (mode) { - case LocationCheck::kEquals: - ASSERT_EQ(expected_dex_file->GetLocation(), opened_dex_file->GetLocation()); - break; - case LocationCheck::kEndsWith: - ASSERT_TRUE(android::base::EndsWith(expected_dex_file->GetLocation(), - opened_dex_file->GetLocation().c_str())) - << opened_dex_file->GetLocation() << " vs " << expected_dex_file->GetLocation(); - break; - } - ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum()); - - std::string class_path_location = info.classpath[k]; - UniqueCPtr class_path_location_real( - realpath(class_path_location.c_str(), nullptr)); - ASSERT_TRUE(class_path_location_real != nullptr); - class_path_location.assign(class_path_location_real.get()); - switch (base_mode) { - case BaseLocationCheck::kEquals: - ASSERT_EQ(class_path_location, opened_dex_file->GetBaseLocation()); - break; - - case BaseLocationCheck::kEndsWith: - ASSERT_TRUE(android::base::EndsWith(opened_dex_file->GetBaseLocation(), - class_path_location.c_str())) - << info.classpath[k] << " vs " << opened_dex_file->GetBaseLocation(); - break; - } - } + std::unique_ptr& expected_dex_file = (*all_dex_files)[k]; + + std::string expected_location = expected_dex_file->GetBaseLocation(); + UniqueCPtr expected_real_location( + realpath(expected_location.c_str(), nullptr)); + ASSERT_TRUE(expected_real_location != nullptr) << expected_location; + expected_location.assign(expected_real_location.get()); + expected_location += DexFile::GetMultiDexSuffix(expected_dex_file->GetLocation()); + + ASSERT_EQ(expected_location, opened_dex_file->GetLocation()); + ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum()); + ASSERT_EQ(info.classpath[k], opened_dex_file->GetLocation()); } } @@ -182,6 +151,11 @@ class ClassLoaderContextTest : public CommonRuntimeTest { } } + void PretendContextOpenedDexFiles(ClassLoaderContext* context) { + context->dex_files_open_attempted_ = true; + context->dex_files_open_result_ = true; + } + private: void VerifyClassLoaderInfo(ClassLoaderContext* context, size_t index, @@ -201,11 +175,9 @@ class ClassLoaderContextTest : public CommonRuntimeTest { ClassLoaderContext::ClassLoaderType type, const std::string& test_name) { std::vector> dex_files = OpenTestDexFiles(test_name.c_str()); - std::vector>*> all_dex_files; - all_dex_files.push_back(&dex_files); VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str())); - VerifyOpenDexFiles(context, index, all_dex_files); + VerifyOpenDexFiles(context, index, &dex_files); } }; @@ -276,11 +248,8 @@ TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) { TEST_F(ClassLoaderContextTest, OpenValidDexFiles) { std::string multidex_name = GetTestDexFileName("MultiDex"); - std::vector> multidex_files = OpenTestDexFiles("MultiDex"); std::string myclass_dex_name = GetTestDexFileName("MyClass"); - std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); std::string dex_name = GetTestDexFileName("Main"); - std::vector> dex_files = OpenTestDexFiles("Main"); std::unique_ptr context = ClassLoaderContext::Create( @@ -290,14 +259,16 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFiles) { ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir*/ "")); VerifyContextSize(context.get(), 2); - std::vector>*> all_dex_files0; - all_dex_files0.push_back(&multidex_files); - all_dex_files0.push_back(&myclass_dex_files); - std::vector>*> all_dex_files1; - all_dex_files1.push_back(&dex_files); - - VerifyOpenDexFiles(context.get(), 0, all_dex_files0); - VerifyOpenDexFiles(context.get(), 1, all_dex_files1); + + std::vector> all_dex_files0 = OpenTestDexFiles("MultiDex"); + std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); + for (size_t i = 0; i < myclass_dex_files.size(); i++) { + all_dex_files0.emplace_back(myclass_dex_files[i].release()); + } + VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); + + std::vector> all_dex_files1 = OpenTestDexFiles("Main"); + VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); } class ScratchSymLink { @@ -330,11 +301,10 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFilesSymLink) { ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir*/ "")); VerifyContextSize(context.get(), 1); - std::vector>*> all_dex_files0; + std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); - all_dex_files0.push_back(&myclass_dex_files); - VerifyOpenDexFiles(context.get(), 0, all_dex_files0); + VerifyOpenDexFiles(context.get(), 0, &myclass_dex_files); } static std::string CreateRelativeString(const std::string& in, const char* cwd) { @@ -353,11 +323,8 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) { PLOG(FATAL) << "Could not get working directory"; } std::string multidex_name = CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf); - std::vector> multidex_files = OpenTestDexFiles("MultiDex"); std::string myclass_dex_name = CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf); - std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); std::string dex_name = CreateRelativeString(GetTestDexFileName("Main"), cwd_buf); - std::vector> dex_files = OpenTestDexFiles("Main"); std::unique_ptr context = @@ -367,15 +334,15 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) { ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir*/ "")); - VerifyContextSize(context.get(), 2); - std::vector>*> all_dex_files0; - all_dex_files0.push_back(&multidex_files); - all_dex_files0.push_back(&myclass_dex_files); - std::vector>*> all_dex_files1; - all_dex_files1.push_back(&dex_files); - - VerifyOpenDexFiles(context.get(), 0, all_dex_files0, LocationCheck::kEndsWith); - VerifyOpenDexFiles(context.get(), 1, all_dex_files1, LocationCheck::kEndsWith); + std::vector> all_dex_files0 = OpenTestDexFiles("MultiDex"); + std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); + for (size_t i = 0; i < myclass_dex_files.size(); i++) { + all_dex_files0.emplace_back(myclass_dex_files[i].release()); + } + VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); + + std::vector> all_dex_files1 = OpenTestDexFiles("Main"); + VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); } TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) { @@ -384,12 +351,8 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) { PLOG(FATAL) << "Could not get working directory"; } std::string multidex_name = CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf); - std::vector> multidex_files = OpenTestDexFiles("MultiDex"); std::string myclass_dex_name = CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf); - std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); std::string dex_name = CreateRelativeString(GetTestDexFileName("Main"), cwd_buf); - std::vector> dex_files = OpenTestDexFiles("Main"); - std::unique_ptr context = ClassLoaderContext::Create( @@ -399,16 +362,15 @@ TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) { ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf)); VerifyContextSize(context.get(), 2); - std::vector>*> all_dex_files0; - all_dex_files0.push_back(&multidex_files); - all_dex_files0.push_back(&myclass_dex_files); - std::vector>*> all_dex_files1; - all_dex_files1.push_back(&dex_files); - - VerifyOpenDexFiles( - context.get(), 0, all_dex_files0, LocationCheck::kEquals, BaseLocationCheck::kEndsWith); - VerifyOpenDexFiles( - context.get(), 1, all_dex_files1, LocationCheck::kEquals, BaseLocationCheck::kEndsWith); + std::vector> all_dex_files0 = OpenTestDexFiles("MultiDex"); + std::vector> myclass_dex_files = OpenTestDexFiles("MyClass"); + for (size_t i = 0; i < myclass_dex_files.size(); i++) { + all_dex_files0.emplace_back(myclass_dex_files[i].release()); + } + VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); + + std::vector> all_dex_files1 = OpenTestDexFiles("Main"); + VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); } TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) { @@ -660,6 +622,9 @@ TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) { TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) { std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]"; std::unique_ptr context = ParseContextWithChecksums(context_spec); + // Pretend that we successfully open the dex files to pass the DCHECKS. + // (as it's much easier to test all the corner cases without relying on actual dex files). + PretendContextOpenedDexFiles(context.get()); VerifyContextSize(context.get(), 2); VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); -- cgit v1.2.3-59-g8ed1b