Don't let the oat file close BCP FD passed from outside
Bug: 186132447
Test: odrefresh --use-compilation-os=10 --force-compile
# complete successfully with other changes
Test: TH
Change-Id: I3393ccd8fdc8ece71dbed8d16ef3c62ba935ea75
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index 62014aa..a7dd13e 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -311,8 +311,39 @@
std::string* error_msg,
std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
ScopedTrace trace("Dex file open Zip " + std::string(location));
+ return OpenZipInternal(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg),
+ location,
+ verify,
+ verify_checksum,
+ error_msg,
+ dex_files);
+}
+
+bool ArtDexFileLoader::OpenZipFromOwnedFd(
+ int fd,
+ const std::string& location,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
+ ScopedTrace trace("Dex file open Zip " + std::string(location) + " (owned fd)");
+ return OpenZipInternal(ZipArchive::OpenFromOwnedFd(fd, location.c_str(), error_msg),
+ location,
+ verify,
+ verify_checksum,
+ error_msg,
+ dex_files);
+}
+
+bool ArtDexFileLoader::OpenZipInternal(
+ ZipArchive* raw_zip_archive,
+ const std::string& location,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
DCHECK(dex_files != nullptr) << "DexFile::OpenZip: out-param is nullptr";
- std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg));
+ std::unique_ptr<ZipArchive> zip_archive(raw_zip_archive);
if (zip_archive.get() == nullptr) {
DCHECK(!error_msg->empty());
return false;
diff --git a/libdexfile/dex/art_dex_file_loader.h b/libdexfile/dex/art_dex_file_loader.h
index 786142a..49c81f4 100644
--- a/libdexfile/dex/art_dex_file_loader.h
+++ b/libdexfile/dex/art_dex_file_loader.h
@@ -110,7 +110,8 @@
bool mmap_shared,
std::string* error_msg) const;
- // Opens dex files from within a .jar, .zip, or .apk file
+ // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
+ // descriptor ownership is taken over, i.e. will be closed by this class.
bool OpenZip(int fd,
const std::string& location,
bool verify,
@@ -118,6 +119,15 @@
std::string* error_msg,
std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+ // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
+ // descriptor is assumed owned by the caller.
+ bool OpenZipFromOwnedFd(int fd,
+ const std::string& location,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+
private:
bool OpenWithMagic(uint32_t magic,
int fd,
@@ -152,6 +162,13 @@
std::string* error_msg,
DexFileLoaderErrorCode* error_code) const;
+ bool OpenZipInternal(ZipArchive* raw_zip_archive,
+ const std::string& location,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+
static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
size_t size,
const uint8_t* data_base,
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index a6a1a01..0d6339b 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -734,15 +734,21 @@
const ArtDexFileLoader dex_file_loader;
bool loaded = false;
CHECK(zip_fd == -1 || dex_fds.empty()); // Allow only the supported combinations.
- int fd = zip_fd >= 0 ?: dex_fd;
- if (fd != -1) {
- // Note that we assume dex_fds are backing by jars.
- loaded = dex_file_loader.OpenZip(fd,
+ if (zip_fd != -1) {
+ loaded = dex_file_loader.OpenZip(zip_fd,
dex_file_location,
/*verify=*/ false,
/*verify_checksum=*/ false,
error_msg,
&new_dex_files);
+ } else if (dex_fd != -1) {
+ // Note that we assume dex_fds are backing by jars.
+ loaded = dex_file_loader.OpenZipFromOwnedFd(dex_fd,
+ dex_file_location,
+ /*verify=*/ false,
+ /*verify_checksum=*/ false,
+ error_msg,
+ &new_dex_files);
} else {
loaded = dex_file_loader.Open(dex_file_name.c_str(),
dex_file_location,