diff options
| author | 2018-03-02 23:07:27 +0000 | |
|---|---|---|
| committer | 2018-03-02 23:07:27 +0000 | |
| commit | dfa174fb1979ab81355f6c6e9ee17da82d842b66 (patch) | |
| tree | 1da6c9c6e1fdbcf7dcaab45c5e2c3101c79c390b | |
| parent | dbf2c9c17d1ece552a073cdb2d57617739355270 (diff) | |
| parent | 78d627ded362a1820c78011bed0adb745948a0ce (diff) | |
Merge "Fix handling for partial cdex conversion rejection in multidex"
am: 78d627ded3
Change-Id: Id59cf30921ccd0beb301a45b003e6f480aa93dd7
| -rw-r--r-- | dex2oat/dex2oat_test.cc | 28 | ||||
| -rw-r--r-- | dex2oat/linker/oat_writer.cc | 6 |
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_; |