diff options
-rw-r--r-- | compiler/elf_writer_test.cc | 2 | ||||
-rw-r--r-- | compiler/image_writer.cc | 4 | ||||
-rw-r--r-- | compiler/llvm/llvm_compilation_unit.cc | 4 | ||||
-rw-r--r-- | compiler/sea_ir/debug/dot_gen.h | 2 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 8 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 2 | ||||
-rw-r--r-- | runtime/class_linker.cc | 97 | ||||
-rw-r--r-- | runtime/dex_file_test.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 5 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 2 | ||||
-rw-r--r-- | runtime/image_test.cc | 4 | ||||
-rw-r--r-- | runtime/native/dalvik_system_DexFile.cc | 8 | ||||
-rw-r--r-- | runtime/oat_file.cc | 17 | ||||
-rw-r--r-- | runtime/os.h | 13 | ||||
-rw-r--r-- | runtime/os_linux.cc | 23 | ||||
-rw-r--r-- | runtime/output_stream_test.cc | 2 | ||||
-rw-r--r-- | runtime/thread.cc | 10 | ||||
-rw-r--r-- | runtime/trace.cc | 2 | ||||
-rw-r--r-- | runtime/utils.cc | 1 | ||||
-rw-r--r-- | test/Android.mk | 2 |
20 files changed, 159 insertions, 51 deletions
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc index e48806ecc4..ffe1f72926 100644 --- a/compiler/elf_writer_test.cc +++ b/compiler/elf_writer_test.cc @@ -62,7 +62,7 @@ TEST_F(ElfWriterTest, dlsym) { ASSERT_EQ(0, dlclose(dl_oat_so)); - UniquePtr<File> file(OS::OpenFile(elf_filename.c_str(), false)); + UniquePtr<File> file(OS::OpenFileForReading(elf_filename.c_str())); ASSERT_TRUE(file.get() != NULL); { UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, false)); diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index a40e3fc149..4e9ae54d8e 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -79,7 +79,7 @@ bool ImageWriter::Write(const std::string& image_filename, dex_caches_.insert(dex_cache); } - UniquePtr<File> oat_file(OS::OpenFile(oat_filename.c_str(), true, false)); + UniquePtr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str())); if (oat_file.get() == NULL) { LOG(ERROR) << "Failed to open oat file " << oat_filename << " for " << oat_location; return false; @@ -145,7 +145,7 @@ bool ImageWriter::Write(const std::string& image_filename, PatchOatCodeAndMethods(); Thread::Current()->TransitionFromRunnableToSuspended(kNative); - UniquePtr<File> image_file(OS::OpenFile(image_filename.c_str(), true)); + UniquePtr<File> image_file(OS::CreateEmptyFile(image_filename.c_str())); if (image_file.get() == NULL) { LOG(ERROR) << "Failed to open image file " << image_filename; return false; diff --git a/compiler/llvm/llvm_compilation_unit.cc b/compiler/llvm/llvm_compilation_unit.cc index 9296fc7050..aa439ccbae 100644 --- a/compiler/llvm/llvm_compilation_unit.cc +++ b/compiler/llvm/llvm_compilation_unit.cc @@ -155,7 +155,7 @@ void LlvmCompilationUnit::DumpBitcodeToFile() { std::string bitcode; DumpBitcodeToString(bitcode); std::string filename(StringPrintf("%s/Art%u.bc", DumpDirectory().c_str(), cunit_id_)); - UniquePtr<File> output(OS::OpenFile(filename.c_str(), true)); + UniquePtr<File> output(OS::CreateEmptyFile(filename.c_str())); output->WriteFully(bitcode.data(), bitcode.size()); LOG(INFO) << ".bc file written successfully: " << filename; } @@ -182,7 +182,7 @@ bool LlvmCompilationUnit::Materialize() { if (kDumpELF) { // Dump the ELF image for debugging std::string filename(StringPrintf("%s/Art%u.o", DumpDirectory().c_str(), cunit_id_)); - UniquePtr<File> output(OS::OpenFile(filename.c_str(), true)); + UniquePtr<File> output(OS::CreateEmptyFile(filename.c_str())); output->WriteFully(elf_object_.data(), elf_object_.size()); LOG(INFO) << ".o file written successfully: " << filename; } diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h index 675d83d515..5270582c16 100644 --- a/compiler/sea_ir/debug/dot_gen.h +++ b/compiler/sea_ir/debug/dot_gen.h @@ -103,7 +103,7 @@ class DotConversion { LOG(INFO) << "Starting to write SEA string to file."; DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types); graph->Accept(&dgv); - art::File* file = art::OS::OpenFile(filename.c_str(), true, true); + art::File* file = art::OS::OpenFile(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC); art::FileOutputStream fos(file); std::string graph_as_string = dgv.GetResult(); graph_as_string += "}"; diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 25cfda6a43..ceb6bf6d80 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -313,7 +313,7 @@ class Dex2Oat { oat_data_begin = image_writer.GetOatDataBegin(); } - UniquePtr<File> oat_file(OS::OpenFile(oat_filename.c_str(), true, false)); + UniquePtr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str())); if (oat_file.get() == NULL) { PLOG(ERROR) << "Failed to open ELF file: " << oat_filename; return false; @@ -808,7 +808,7 @@ static int dex2oat(int argc, char** argv) { UniquePtr<File> oat_file; bool create_file = !oat_unstripped.empty(); // as opposed to using open file descriptor if (create_file) { - oat_file.reset(OS::OpenFile(oat_unstripped.c_str(), true)); + oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str())); if (oat_location.empty()) { oat_location = oat_filename; } @@ -1023,8 +1023,8 @@ static int dex2oat(int argc, char** argv) { if (oat_unstripped != oat_stripped) { timings.NewSplit("dex2oat OatFile copy"); oat_file.reset(); - UniquePtr<File> in(OS::OpenFile(oat_unstripped.c_str(), false)); - UniquePtr<File> out(OS::OpenFile(oat_stripped.c_str(), true)); + UniquePtr<File> in(OS::OpenFileForReading(oat_unstripped.c_str())); + UniquePtr<File> out(OS::CreateEmptyFile(oat_stripped.c_str())); size_t buffer_size = 8192; UniquePtr<uint8_t> buffer(new uint8_t[buffer_size]); while (true) { diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 67398afd5f..fbfdfd9e8d 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -777,7 +777,7 @@ class ImageDumper { os_ = saved_os; } os << "STATS:\n" << std::flush; - UniquePtr<File> file(OS::OpenFile(image_filename_.c_str(), false)); + UniquePtr<File> file(OS::OpenFileForReading(image_filename_.c_str())); stats_.file_bytes = file->GetLength(); size_t header_bytes = sizeof(ImageHeader); stats_.header_bytes = header_bytes; diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index bd36a6c394..039e7bc0a7 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -659,6 +659,7 @@ void ClassLinker::RegisterOatFileLocked(const OatFile& oat_file) { CHECK_NE(&oat_file, oat_files_[i]) << oat_file.GetLocation(); } } + VLOG(class_linker) << "Registering " << oat_file.GetLocation(); oat_files_.push_back(&oat_file); } @@ -694,22 +695,39 @@ const DexFile* ClassLinker::FindDexFileInOatLocation(const std::string& dex_loca UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, NULL, !Runtime::Current()->IsCompiler())); if (oat_file.get() == NULL) { + VLOG(class_linker) << "Failed to find existing oat file at " << oat_location; return NULL; } Runtime* runtime = Runtime::Current(); const ImageHeader& image_header = runtime->GetHeap()->GetImageSpace()->GetImageHeader(); - if (oat_file->GetOatHeader().GetImageFileLocationOatChecksum() != image_header.GetOatChecksum()) { + uint32_t expected_image_oat_checksum = image_header.GetOatChecksum(); + uint32_t actual_image_oat_checksum = oat_file->GetOatHeader().GetImageFileLocationOatChecksum(); + if (expected_image_oat_checksum != actual_image_oat_checksum) { + VLOG(class_linker) << "Failed to find oat file at " << oat_location + << " with expected image oat checksum of " << expected_image_oat_checksum + << ", found " << actual_image_oat_checksum; return NULL; } - if (oat_file->GetOatHeader().GetImageFileLocationOatDataBegin() - != reinterpret_cast<uint32_t>(image_header.GetOatDataBegin())) { + + uint32_t expected_image_oat_offset = reinterpret_cast<uint32_t>(image_header.GetOatDataBegin()); + uint32_t actual_image_oat_offset = oat_file->GetOatHeader().GetImageFileLocationOatDataBegin(); + if (expected_image_oat_offset != actual_image_oat_offset) { + VLOG(class_linker) << "Failed to find oat file at " << oat_location + << " with expected image oat offset " << expected_image_oat_offset + << ", found " << actual_image_oat_offset; return NULL; } const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); if (oat_dex_file == NULL) { + VLOG(class_linker) << "Failed to find oat file at " << oat_location << " containing " << dex_location; return NULL; } - if (oat_dex_file->GetDexFileLocationChecksum() != dex_location_checksum) { + uint32_t expected_dex_checksum = dex_location_checksum; + uint32_t actual_dex_checksum = oat_dex_file->GetDexFileLocationChecksum(); + if (expected_dex_checksum != actual_dex_checksum) { + VLOG(class_linker) << "Failed to find oat file at " << oat_location + << " with expected dex checksum of " << expected_dex_checksum + << ", found " << actual_dex_checksum; return NULL; } RegisterOatFileLocked(*oat_file.release()); @@ -722,6 +740,58 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_location); } +class ScopedFlock { + public: + ScopedFlock() {} + + bool Init(const std::string& filename) { + while (true) { + file_.reset(OS::OpenFileWithFlags(filename.c_str(), O_CREAT | O_RDWR)); + if (file_.get() == NULL) { + LOG(ERROR) << "Failed to open file: " << filename; + return false; + } + int flock_result = TEMP_FAILURE_RETRY(flock(file_->Fd(), LOCK_EX)); + if (flock_result != 0) { + PLOG(ERROR) << "Failed to lock file: " << filename; + return false; + } + struct stat fstat_stat; + int fstat_result = TEMP_FAILURE_RETRY(fstat(file_->Fd(), &fstat_stat)); + if (fstat_result != 0) { + PLOG(ERROR) << "Failed to fstat: " << filename; + return false; + } + struct stat stat_stat; + int stat_result = TEMP_FAILURE_RETRY(stat(filename.c_str(), &stat_stat)); + if (stat_result != 0) { + PLOG(WARNING) << "Failed to stat, will retry: " << filename; + // ENOENT can happen if someone racing with us unlinks the file we created so just retry. + continue; + } + if (fstat_stat.st_dev != stat_stat.st_dev || fstat_stat.st_ino != stat_stat.st_ino) { + LOG(WARNING) << "File changed while locking, will retry: " << filename; + continue; + } + return true; + } + } + + File& GetFile() { + return *file_; + } + + ~ScopedFlock() { + int flock_result = TEMP_FAILURE_RETRY(flock(file_->Fd(), LOCK_UN)); + CHECK_EQ(0, flock_result); + } + + private: + UniquePtr<File> file_; + + DISALLOW_COPY_AND_ASSIGN(ScopedFlock); +}; + const DexFile* ClassLinker::FindOrCreateOatFileForDexLocationLocked(const std::string& dex_location, const std::string& oat_location) { uint32_t dex_location_checksum; @@ -730,6 +800,17 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocationLocked(const std::s return NULL; } + // We play a locking game here so that if two different processes + // race to generate (or worse, one tries to open a partial generated + // file) we will be okay. This is actually common with apps that use + // DexClassLoader to work around the dex method reference limit and + // that have a background service running in a separate process. + ScopedFlock scoped_flock; + if (!scoped_flock.Init(oat_location)) { + LOG(ERROR) << "Failed to open locked oat file: " << oat_location; + return NULL; + } + // Check if we already have an up-to-date output file const DexFile* dex_file = FindDexFileInOatLocation(dex_location, dex_location_checksum, @@ -739,12 +820,8 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocationLocked(const std::s } // Generate the output oat file for the dex file - UniquePtr<File> file(OS::OpenFile(oat_location.c_str(), true)); - if (file.get() == NULL) { - LOG(ERROR) << "Failed to create oat file: " << oat_location; - return NULL; - } - if (!GenerateOatFile(dex_location, file->Fd(), oat_location)) { + VLOG(class_linker) << "Generating oat file " << oat_location << " for " << dex_location; + if (!GenerateOatFile(dex_location, scoped_flock.GetFile().Fd(), oat_location)) { LOG(ERROR) << "Failed to generate oat file: " << oat_location; return NULL; } diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index e7899ecf31..6449493f1f 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -64,7 +64,7 @@ static const DexFile* OpenDexFileBase64(const char* base64, CHECK(dex_bytes.get() != NULL); // write to provided file - UniquePtr<File> file(OS::OpenFile(location.c_str(), true)); + UniquePtr<File> file(OS::CreateEmptyFile(location.c_str())); CHECK(file.get() != NULL); if (!file->WriteFully(dex_bytes.get(), length)) { PLOG(FATAL) << "Failed to write base64 as dex file"; diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 6b8c41ed41..bf0fffaad2 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -269,7 +269,10 @@ mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_ } void ThrowStackOverflowError(Thread* self) { - CHECK(!self->IsHandlingStackOverflow()) << "Recursive stack overflow."; + if (self->IsHandlingStackOverflow()) { + LOG(ERROR) << "Recursive stack overflow."; + // We don't fail here because SetStackEndForStackOverflow will print better diagnostics. + } if (Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled()) { // Remove extra entry pushed onto second stack during method tracing. diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 22562df512..f959cff7b4 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -160,7 +160,7 @@ ImageSpace* ImageSpace::Init(const std::string& image_file_name, bool validate_o LOG(INFO) << "ImageSpace::Init entering image_file_name=" << image_file_name; } - UniquePtr<File> file(OS::OpenFile(image_file_name.c_str(), false)); + UniquePtr<File> file(OS::OpenFileForReading(image_file_name.c_str())); if (file.get() == NULL) { LOG(ERROR) << "Failed to open " << image_file_name; return NULL; diff --git a/runtime/image_test.cc b/runtime/image_test.cc index 334f7abfd3..dcafc193dd 100644 --- a/runtime/image_test.cc +++ b/runtime/image_test.cc @@ -65,7 +65,7 @@ TEST_F(ImageTest, WriteRead) { } } // Workound bug that mcld::Linker::emit closes tmp_elf by reopening as tmp_oat. - UniquePtr<File> tmp_oat(OS::OpenFile(tmp_elf.GetFilename().c_str(), true, false)); + UniquePtr<File> tmp_oat(OS::OpenFileReadWrite(tmp_elf.GetFilename().c_str())); ASSERT_TRUE(tmp_oat.get() != NULL); ScratchFile tmp_image; @@ -80,7 +80,7 @@ TEST_F(ImageTest, WriteRead) { } { - UniquePtr<File> file(OS::OpenFile(tmp_image.GetFilename().c_str(), false)); + UniquePtr<File> file(OS::OpenFileForReading(tmp_image.GetFilename().c_str())); ASSERT_TRUE(file.get() != NULL); ImageHeader image_header; file->ReadFully(&image_header, sizeof(image_header)); diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index dc3573dfec..061dfb84db 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -84,7 +84,7 @@ class NullableScopedUtfChars { void operator=(const NullableScopedUtfChars&); }; -static jint DexFile_openDexFile(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) { +static jint DexFile_openDexFileNative(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) { ScopedUtfChars sourceName(env, javaSourceName); if (sourceName.c_str() == NULL) { return 0; @@ -141,21 +141,25 @@ static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, j ScopedObjectAccess soa(env); const DexFile* dex_file = toDexFile(cookie); if (dex_file == NULL) { + VLOG(class_linker) << "Failed to find dex_file"; return NULL; } ScopedUtfChars class_name(env, javaName); if (class_name.c_str() == NULL) { + VLOG(class_linker) << "Failed to find class_name"; return NULL; } const std::string descriptor(DotToDescriptor(class_name.c_str())); const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor); if (dex_class_def == NULL) { + VLOG(class_linker) << "Failed to find dex_class_def"; return NULL; } ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); class_linker->RegisterDexFile(*dex_file); mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(javaLoader); mirror::Class* result = class_linker->DefineClass(descriptor, class_loader, *dex_file, *dex_class_def); + VLOG(class_linker) << "DexFile_defineClassNative returning " << result; return soa.AddLocalReference<jclass>(result); } @@ -300,7 +304,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(DexFile, defineClassNative, "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;"), NATIVE_METHOD(DexFile, getClassNameList, "(I)[Ljava/lang/String;"), NATIVE_METHOD(DexFile, isDexOptNeeded, "(Ljava/lang/String;)Z"), - NATIVE_METHOD(DexFile, openDexFile, "(Ljava/lang/String;Ljava/lang/String;I)I"), + NATIVE_METHOD(DexFile, openDexFileNative, "(Ljava/lang/String;Ljava/lang/String;I)I"), }; void register_dalvik_system_DexFile(JNIEnv* env) { diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 1f34317d26..afa823dbd9 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -74,7 +74,7 @@ OatFile* OatFile::Open(const std::string& filename, // // On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile. // This won't work for portable runtime execution because it doesn't process relocations. - UniquePtr<File> file(OS::OpenFile(filename.c_str(), false, false)); + UniquePtr<File> file(OS::OpenFileForReading(filename.c_str())); if (file.get() == NULL) { return NULL; } @@ -125,11 +125,13 @@ OatFile::~OatFile() { bool OatFile::Dlopen(const std::string& elf_filename, byte* requested_base) { char* absolute_path = realpath(elf_filename.c_str(), NULL); if (absolute_path == NULL) { + VLOG(class_linker) << "Failed to find absolute path for " << elf_filename; return false; } dlopen_handle_ = dlopen(absolute_path, RTLD_NOW); free(absolute_path); if (dlopen_handle_ == NULL) { + VLOG(class_linker) << "Failed to dlopen " << elf_filename << ": " << dlerror(); return false; } begin_ = reinterpret_cast<byte*>(dlsym(dlopen_handle_, "oatdata")); @@ -319,7 +321,14 @@ const OatFile::OatDexFile* OatFile::GetOatDexFile(const std::string& dex_file_lo Table::const_iterator it = oat_dex_files_.find(dex_file_location); if (it == oat_dex_files_.end()) { if (warn_if_not_found) { - LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_file_location; + LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_file_location + << " in OatFile " << GetLocation(); + if (kIsDebugBuild) { + for (Table::const_iterator it = oat_dex_files_.begin(); it != oat_dex_files_.end(); ++it) { + LOG(WARNING) << "OatFile " << GetLocation() + << " contains OatDexFile " << it->second->GetDexFileLocation(); + } + } } return NULL; } @@ -360,11 +369,11 @@ const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_ind uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index]; const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset; - CHECK_LT(oat_class_pointer, oat_file_->End()); + CHECK_LT(oat_class_pointer, oat_file_->End()) << oat_file_->GetLocation(); mirror::Class::Status status = *reinterpret_cast<const mirror::Class::Status*>(oat_class_pointer); const byte* methods_pointer = oat_class_pointer + sizeof(status); - CHECK_LT(methods_pointer, oat_file_->End()); + CHECK_LT(methods_pointer, oat_file_->End()) << oat_file_->GetLocation(); return new OatClass(oat_file_, status, diff --git a/runtime/os.h b/runtime/os.h index 6767566673..6248d5fc14 100644 --- a/runtime/os.h +++ b/runtime/os.h @@ -29,8 +29,17 @@ typedef ::unix_file::FdFile File; class OS { public: - // Open a file. The returned pointer must be deleted by the caller. - static File* OpenFile(const char* name, bool writable, bool create = true); + // Open an existing file with read only access. + static File* OpenFileForReading(const char* name); + + // Open an existing file with read/write access. + static File* OpenFileReadWrite(const char* name); + + // Create an empty file with read/write access. + static File* CreateEmptyFile(const char* name); + + // Open a file with the specified open(2) flags. + static File* OpenFileWithFlags(const char* name, int flags); // Check if a file exists. static bool FileExists(const char* name); diff --git a/runtime/os_linux.cc b/runtime/os_linux.cc index d3a1ccbcb8..7ce17e0aee 100644 --- a/runtime/os_linux.cc +++ b/runtime/os_linux.cc @@ -27,17 +27,20 @@ namespace art { -File* OS::OpenFile(const char* name, bool writable, bool create) { +File* OS::OpenFileForReading(const char* name) { + return OpenFileWithFlags(name, O_RDONLY); +} + +File* OS::OpenFileReadWrite(const char* name) { + return OpenFileWithFlags(name, O_RDWR); +} + +File* OS::CreateEmptyFile(const char* name) { + return OpenFileWithFlags(name, O_RDWR | O_CREAT | O_TRUNC); +} + +File* OS::OpenFileWithFlags(const char* name, int flags) { CHECK(name != NULL); - int flags = 0; - if (writable) { - flags |= O_RDWR; - if (create) { - flags |= (O_CREAT | O_TRUNC); - } - } else { - flags |= O_RDONLY; - } UniquePtr<File> file(new File); if (!file->Open(name, flags, 0666)) { return NULL; diff --git a/runtime/output_stream_test.cc b/runtime/output_stream_test.cc index c9e0edefcd..8da2ac91fe 100644 --- a/runtime/output_stream_test.cc +++ b/runtime/output_stream_test.cc @@ -62,7 +62,7 @@ TEST_F(OutputStreamTest, File) { FileOutputStream output_stream(tmp.GetFile()); SetOutputStream(output_stream); GenerateTestOutput(); - UniquePtr<File> in(OS::OpenFile(tmp.GetFilename().c_str(), false)); + UniquePtr<File> in(OS::OpenFileForReading(tmp.GetFilename().c_str())); EXPECT_TRUE(in.get() != NULL); std::vector<uint8_t> actual(in->GetLength()); bool readSuccess = in->ReadFully(&actual[0], actual.size()); diff --git a/runtime/thread.cc b/runtime/thread.cc index 7e3afb59a5..48e595f545 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2218,11 +2218,13 @@ void Thread::VerifyStackImpl() { // Set the stack end to that to be used during a stack overflow void Thread::SetStackEndForStackOverflow() { - // During stack overflow we allow use of the full stack + // During stack overflow we allow use of the full stack. if (stack_end_ == stack_begin_) { - DumpStack(std::cerr); - LOG(FATAL) << "Need to increase kStackOverflowReservedBytes (currently " - << kStackOverflowReservedBytes << ")"; + // However, we seem to have already extended to use the full stack. + LOG(ERROR) << "Need to increase kStackOverflowReservedBytes (currently " + << kStackOverflowReservedBytes << ")?"; + DumpStack(LOG(ERROR)); + LOG(FATAL) << "Recursive stack overflow."; } stack_end_ = stack_begin_; diff --git a/runtime/trace.cc b/runtime/trace.cc index 29765c9009..13e2bf6deb 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -318,7 +318,7 @@ void Trace::Start(const char* trace_filename, int trace_fd, int buffer_size, int UniquePtr<File> trace_file; if (!direct_to_ddms) { if (trace_fd < 0) { - trace_file.reset(OS::OpenFile(trace_filename, true)); + trace_file.reset(OS::CreateEmptyFile(trace_filename)); } else { trace_file.reset(new File(trace_fd, "tracefile")); trace_file->DisableAutoClose(); diff --git a/runtime/utils.cc b/runtime/utils.cc index 87cd21c478..6856bb76de 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -1229,6 +1229,7 @@ bool IsValidDexFilename(const std::string& filename) { bool IsValidOatFilename(const std::string& filename) { return (EndsWith(filename, ".odex") || + EndsWith(filename, ".dex") || EndsWith(filename, ".oat") || EndsWith(filename, DexFile::kClassesDex)); } diff --git a/test/Android.mk b/test/Android.mk index 87e15a8127..596c411e9c 100644 --- a/test/Android.mk +++ b/test/Android.mk @@ -111,7 +111,7 @@ test-art-target-oat-$(1): $(ART_TEST_OUT)/oat-test-dex-$(1).jar test-art-target- $(hide) rm /tmp/test-art-target-oat-$(1) $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).odex: $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).jar $(HOST_CORE_IMG_OUT) | $(DEX2OAT) - $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --boot-image=$(HOST_CORE_IMG_OUT) --dex-file=$$< --oat-file=$$@ --instruction-set=$(HOST_ARCH) --host --host-prefix="" --android-root=$(HOST_OUT) + $(DEX2OAT) --runtime-arg -Xms16m --runtime-arg -Xmx16m --boot-image=$(HOST_CORE_IMG_OUT) --dex-file=$(PWD)/$$< --oat-file=$(PWD)/$$@ --instruction-set=$(HOST_ARCH) --host --host-prefix="" --android-root=$(HOST_OUT) .PHONY: test-art-host-oat-default-$(1) test-art-host-oat-default-$(1): $(HOST_OUT_JAVA_LIBRARIES)/oat-test-dex-$(1).odex test-art-host-dependencies |