From 93d339d9b2949ca85d031bb9ebb7a0612b095fa8 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Wed, 27 Mar 2019 09:56:45 +0000 Subject: Revert^2: InMemoryDexClassLoader in ClassLoaderContext follow-up Address follow-up comments on Ic64065819018a1e56dee0f65405d26beb8fd7bbd. In particular, the classpath elements of IMC are replaced with "" magic value to make it clear that the dex location is bogus, and a clarifying comment is added. Previously this CL would fail on target because IMC classpath was not being replaced with "" and context matching failed. This was only a problem on target because OatFile::ResolveRelativeEncodedDexLocation ignores non-absolute locations on host. This reverts commit 93d99f3665cbd890509f4c707e1a62c5f26d320e. Test: m test-art-gtest-class_loader_context_test Bug: 72131483 Change-Id: I27cbfa69c24d412cc1b6bcce88218cc95e324ef5 --- runtime/class_loader_context_test.cc | 92 +++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 22 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 6d44b71b67..0c36fd42c2 100644 --- a/runtime/class_loader_context_test.cc +++ b/runtime/class_loader_context_test.cc @@ -122,7 +122,7 @@ class ClassLoaderContextTest : public CommonRuntimeTest { size_t index, const std::string& test_name) { VerifyClassLoaderFromTestDex( - context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name); + context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, ""); } enum class LocationCheck { @@ -141,7 +141,8 @@ class ClassLoaderContextTest : public CommonRuntimeTest { void VerifyOpenDexFiles( ClassLoaderContext* context, size_t index, - std::vector>* all_dex_files) { + std::vector>* all_dex_files, + bool classpath_matches_dex_location = true) { ASSERT_TRUE(context != nullptr); ASSERT_TRUE(context->dex_files_open_attempted_); ASSERT_TRUE(context->dex_files_open_result_); @@ -169,7 +170,9 @@ class ClassLoaderContextTest : public CommonRuntimeTest { ASSERT_EQ(expected_location, opened_location); } ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum()); - ASSERT_EQ(info.classpath[k], opened_location); + if (classpath_matches_dex_location) { + ASSERT_EQ(info.classpath[k], opened_location); + } } } @@ -250,11 +253,20 @@ class ClassLoaderContextTest : public CommonRuntimeTest { void VerifyClassLoaderFromTestDex(ClassLoaderContext* context, size_t index, ClassLoaderContext::ClassLoaderType type, - const std::string& test_name) { + const std::string& test_name, + const std::string& classpath = "") { std::vector> dex_files = OpenTestDexFiles(test_name.c_str()); - VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str())); - VerifyOpenDexFiles(context, index, &dex_files); + // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath. + // Otherwise assume it is equal to dex location (here test dex file name). + VerifyClassLoaderInfo(context, + index, + type, + classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath); + VerifyOpenDexFiles(context, + index, + &dex_files, + /* classpath_matches_dex_location= */ classpath.empty()); } }; @@ -283,10 +295,22 @@ TEST_F(ClassLoaderContextTest, ParseValidContextDLC) { VerifyClassLoaderDLC(context.get(), 0, "a.dex"); } -TEST_F(ClassLoaderContextTest, ParseInvalidContextIMC) { +TEST_F(ClassLoaderContextTest, ParseValidContextIMC) { + std::unique_ptr context = ParseContextWithChecksums("IMC[*111]"); + ASSERT_FALSE(context == nullptr); +} + +TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) { // IMC is treated as an unknown class loader unless a checksum is provided. // This is because the dex location is always bogus. - std::unique_ptr context = ClassLoaderContext::Create("IMC[a.dex]"); + std::unique_ptr context = ClassLoaderContext::Create("IMC[]"); + ASSERT_TRUE(context == nullptr); +} + +TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) { + // IMC does not support arbitrary dex location. A magic marker must be used + // otherwise the spec should be rejected. + std::unique_ptr context = ClassLoaderContext::Create("IMC[a.dex*111]"); ASSERT_TRUE(context == nullptr); } @@ -500,11 +524,7 @@ TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) { std::unique_ptr context; std::string dex_name = GetTestDexFileName("Main"); - context = ParseContextWithChecksums("PCL[" + dex_name + "*111]"); - VerifyContextSize(context.get(), 1); - ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ".")); - - context = ParseContextWithChecksums("IMC[" + dex_name + "*111]"); + context = ParseContextWithChecksums("IMC[*111]"); VerifyContextSize(context.get(), 1); ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ".")); } @@ -1075,6 +1095,23 @@ TEST_F(ClassLoaderContextTest, EncodeInOatFile) { ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile("")); } +TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) { + jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr); + jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a); + + std::unique_ptr context = CreateContextForClassLoader(class_loader_b); + ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); + + std::vector> dex1 = OpenTestDexFiles("Main"); + std::vector> dex2 = OpenTestDexFiles("MyClass"); + ASSERT_EQ(dex2.size(), 1u); + + std::string encoding = context->EncodeContextForOatFile(""); + std::string expected_encoding = "IMC[*" + std::to_string(dex2[0]->GetLocationChecksum()) + + "];PCL[" + CreateClassPathWithChecksums(dex1) + "]"; + ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile("")); +} + TEST_F(ClassLoaderContextTest, EncodeForDex2oat) { std::string dex1_name = GetTestDexFileName("Main"); std::string dex2_name = GetTestDexFileName("MultiDex"); @@ -1082,13 +1119,23 @@ TEST_F(ClassLoaderContextTest, EncodeForDex2oat) { ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]"); ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); - std::vector> dex1 = OpenTestDexFiles("Main"); - std::vector> dex2 = OpenTestDexFiles("MultiDex"); std::string encoding = context->EncodeContextForDex2oat(""); std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]"; ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat("")); } +TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) { + jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr); + jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a); + + std::unique_ptr context = CreateContextForClassLoader(class_loader_b); + ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); + + std::string encoding = context->EncodeContextForDex2oat(""); + std::string expected_encoding = "IMC[];PCL[" + GetTestDexFileName("Main") + "]"; + ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat("")); +} + // TODO(calin) add a test which creates the context for a class loader together with dex_elements. TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) { // The chain is @@ -1202,7 +1249,7 @@ TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) { } TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) { - std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[d.dex*111]"; + std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[*111]"; 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). @@ -1211,7 +1258,7 @@ TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) { VerifyContextSize(context.get(), 3); VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); VerifyClassLoaderDLC(context.get(), 1, "c.dex"); - VerifyClassLoaderIMC(context.get(), 2, "d.dex"); + VerifyClassLoaderIMC(context.get(), 2, ""); ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), ClassLoaderContext::VerificationResult::kVerifies); @@ -1286,18 +1333,19 @@ TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) { TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) { std::string context_spec = - "IMC[a.dex*123:b.dex*456]{IMC[d.dex*321];IMC[e.dex*654]#IMC[f.dex*098:g.dex*999]}" - ";DLC[c.dex*890]"; + "IMC[*123:*456]" + "{IMC[*321];IMC[*654]#IMC[*098:*999]};" + "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); - VerifyClassLoaderIMC(context.get(), 0, "a.dex:b.dex"); + VerifyClassLoaderIMC(context.get(), 0, ":"); VerifyClassLoaderDLC(context.get(), 1, "c.dex"); - VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "d.dex"); - VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "f.dex:g.dex"); + VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, ""); + VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, ":"); ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), ClassLoaderContext::VerificationResult::kVerifies); -- cgit v1.2.3-59-g8ed1b