summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2018-03-02 23:07:27 +0000
committer android-build-merger <android-build-merger@google.com> 2018-03-02 23:07:27 +0000
commitdfa174fb1979ab81355f6c6e9ee17da82d842b66 (patch)
tree1da6c9c6e1fdbcf7dcaab45c5e2c3101c79c390b
parentdbf2c9c17d1ece552a073cdb2d57617739355270 (diff)
parent78d627ded362a1820c78011bed0adb745948a0ce (diff)
Merge "Fix handling for partial cdex conversion rejection in multidex"
am: 78d627ded3 Change-Id: Id59cf30921ccd0beb301a45b003e6f480aa93dd7
-rw-r--r--dex2oat/dex2oat_test.cc28
-rw-r--r--dex2oat/linker/oat_writer.cc6
2 files changed, 33 insertions, 1 deletions
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index b16c56a3ad..6b75595005 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1716,6 +1716,34 @@ TEST_F(Dex2oatTest, CompactDexGenerationFailure) {
}
}
+TEST_F(Dex2oatTest, CompactDexGenerationFailureMultiDex) {
+ // Create a multidex file with only one dex that gets rejected for cdex conversion.
+ ScratchFile apk_file;
+ {
+ FILE* file = fdopen(apk_file.GetFd(), "w+b");
+ ZipWriter writer(file);
+ // Add vdex to zip.
+ writer.StartEntry("classes.dex", ZipWriter::kCompress);
+ size_t length = 0u;
+ std::unique_ptr<uint8_t[]> bytes(DecodeBase64(kDuplicateMethodInputDex, &length));
+ ASSERT_GE(writer.WriteBytes(&bytes[0], length), 0);
+ writer.FinishEntry();
+ writer.StartEntry("classes2.dex", ZipWriter::kCompress);
+ std::unique_ptr<const DexFile> dex(OpenTestDexFile("ManyMethods"));
+ ASSERT_GE(writer.WriteBytes(dex->Begin(), dex->Size()), 0);
+ writer.FinishEntry();
+ writer.Finish();
+ ASSERT_EQ(apk_file.GetFile()->Flush(), 0);
+ }
+ const std::string dex_location = apk_file.GetFilename();
+ const std::string odex_location = GetOdexDir() + "/output.odex";
+ GenerateOdexForTest(dex_location,
+ odex_location,
+ CompilerFilter::kQuicken,
+ { "--compact-dex-level=fast" },
+ true);
+}
+
TEST_F(Dex2oatTest, StderrLoggerOutput) {
std::string dex_location = GetScratchDir() + "/Dex2OatStderrLoggerTest.jar";
std::string odex_location = GetOdexDir() + "/Dex2OatStderrLoggerTest.odex";
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index c980320c0c..2feb14a357 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -3372,6 +3372,7 @@ bool OatWriter::WriteDexFiles(OutputStream* out,
CHECK(!update_input_vdex) << "Update input vdex should have empty dex container";
DexContainer::Section* const section = dex_container_->GetDataSection();
if (section->Size() > 0) {
+ CHECK(compact_dex_level_ != CompactDexLevel::kCompactDexLevelNone);
const off_t existing_offset = out->Seek(0, kSeekCurrent);
if (static_cast<uint32_t>(existing_offset) != vdex_dex_shared_data_offset_) {
PLOG(ERROR) << "Expected offset " << vdex_dex_shared_data_offset_ << " but got "
@@ -3395,7 +3396,10 @@ bool OatWriter::WriteDexFiles(OutputStream* out,
PLOG(ERROR) << "Failed to read dex header for updating";
return false;
}
- CHECK(CompactDexFile::IsMagicValid(header.magic_)) << "Must be compact dex";
+ if (!CompactDexFile::IsMagicValid(header.magic_)) {
+ // Non-compact dex file, probably failed to convert due to duplicate methods.
+ continue;
+ }
CHECK_GT(vdex_dex_shared_data_offset_, oat_dex_file.dex_file_offset_);
// Offset is from the dex file base.
header.data_off_ = vdex_dex_shared_data_offset_ - oat_dex_file.dex_file_offset_;