Dup file descriptor to prevent double close in oat writer.

Bug: 36404686
Test: art --profile --verbose -Xcompiler-option
--compiler-filter=speed-profile -cp benchmarks.dex
benchmarks.CaffeineLoop.java.CaffeineLoop

Change-Id: I4f43627a331b51a3f3a878a75694664c31a0c8b0
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 0b2d7f4..6fbb2bd 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -2793,7 +2793,12 @@
                              &error_msg);
   } else if (oat_dex_file->source_.IsRawFile()) {
     File* raw_file = oat_dex_file->source_.GetRawFile();
-    dex_file = DexFile::OpenDex(raw_file->Fd(), location, /* verify_checksum */ true, &error_msg);
+    int dup_fd = dup(raw_file->Fd());
+    if (dup_fd < 0) {
+      PLOG(ERROR) << "Failed to dup dex file descriptor (" << raw_file->Fd() << ") at " << location;
+      return false;
+    }
+    dex_file = DexFile::OpenDex(dup_fd, location, /* verify_checksum */ true, &error_msg);
   } else {
     // The source data is a vdex file.
     CHECK(oat_dex_file->source_.IsRawData())
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 990ab11..5f81b98 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -463,7 +463,7 @@
                    std::string* error_msg,
                    std::vector<std::unique_ptr<const DexFile>>* dex_files);
 
-  // Open a single dex file from an fd.
+  // Open a single dex file from an fd. This function closes the fd.
   static std::unique_ptr<const DexFile> OpenDex(int fd,
                                                 const std::string& location,
                                                 bool verify_checksum,