Fix apps with more than one dex file with the same name
Reverts most of 60836d5a9bcf8b30984aae4279a4f6233b0bf622 which I
believe was an incorrect attempt to address issue introduced in
8d31bbd3d6536de12bc20e3d29cfe03fe848f9da, which is also reverted here.
Also adds some debugging aids include operator<< for DexFile and
MemMap and checksum information to OatFile logging.
Bug: 12802375
Change-Id: Idd6f7dd487f6e01e9479cd15cd4b61580160e8a3
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 462c328..f1f5905 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -649,15 +649,9 @@
const OatFile* ClassLinker::RegisterOatFile(const OatFile* oat_file) {
WriterMutexLock mu(Thread::Current(), dex_lock_);
- for (size_t i = 0; i < oat_files_.size(); ++i) {
- if (UNLIKELY(oat_file->GetLocation() == oat_files_[i]->GetLocation())) {
- VLOG(class_linker) << "Attempt to register oat file that's already registered: "
- << oat_file->GetLocation();
- for (size_t j = i; j < oat_files_.size(); ++j) {
- CHECK_NE(oat_file, oat_files_[j]) << "Attempt to re-register dex file.";
- }
- delete oat_file;
- return oat_files_[i];
+ if (kIsDebugBuild) {
+ for (size_t i = 0; i < oat_files_.size(); ++i) {
+ CHECK_NE(oat_file, oat_files_[i]) << oat_file->GetLocation();
}
}
VLOG(class_linker) << "Registering " << oat_file->GetLocation();
@@ -826,20 +820,6 @@
<< oat_location << "': " << *error_msg;
error_msg->clear();
- {
- // We might have registered an outdated OatFile in FindDexFileInOatLocation().
- // Get rid of it as its MAP_PRIVATE mapping may not reflect changes we're about to do.
- WriterMutexLock mu(Thread::Current(), dex_lock_);
- for (size_t i = 0; i < oat_files_.size(); ++i) {
- if (oat_location == oat_files_[i]->GetLocation()) {
- VLOG(class_linker) << "De-registering old OatFile: " << oat_location;
- delete oat_files_[i];
- oat_files_.erase(oat_files_.begin() + i);
- break;
- }
- }
- }
-
// Generate the output oat file for the dex file
VLOG(class_linker) << "Generating oat file " << oat_location << " for " << dex_location;
if (!GenerateOatFile(dex_location, scoped_flock.GetFile().Fd(), oat_location, error_msg)) {
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 429c516..d28d986 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -284,6 +284,27 @@
}
}
+DexFile::DexFile(const byte* base, size_t size,
+ const std::string& location,
+ uint32_t location_checksum,
+ MemMap* mem_map)
+ : begin_(base),
+ size_(size),
+ location_(location),
+ location_checksum_(location_checksum),
+ mem_map_(mem_map),
+ modification_lock("DEX modification lock"),
+ header_(reinterpret_cast<const Header*>(base)),
+ string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
+ type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
+ field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),
+ method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
+ proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
+ class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)) {
+ CHECK(begin_ != NULL) << GetLocation();
+ CHECK_GT(size_, 0U) << GetLocation();
+}
+
DexFile::~DexFile() {
// We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and
// that's only called after DetachCurrentThread, which means there's no JNIEnv. We could
@@ -292,25 +313,12 @@
}
bool DexFile::Init(std::string* error_msg) {
- InitMembers();
if (!CheckMagicAndVersion(error_msg)) {
return false;
}
return true;
}
-void DexFile::InitMembers() {
- const byte* b = begin_;
- header_ = reinterpret_cast<const Header*>(b);
- const Header* h = header_;
- string_ids_ = reinterpret_cast<const StringId*>(b + h->string_ids_off_);
- type_ids_ = reinterpret_cast<const TypeId*>(b + h->type_ids_off_);
- field_ids_ = reinterpret_cast<const FieldId*>(b + h->field_ids_off_);
- method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_);
- proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_);
- class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_);
-}
-
bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
CHECK(header_->magic_ != NULL) << GetLocation();
if (!IsMagicValid(header_->magic_)) {
@@ -856,6 +864,13 @@
}
}
+std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
+ os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]",
+ dex_file.GetLocation().c_str(),
+ dex_file.GetHeader().checksum_, dex_file.GetLocationChecksum(),
+ dex_file.Begin(), dex_file.Begin() + dex_file.Size());
+ return os;
+}
std::string Signature::ToString() const {
if (dex_file_ == nullptr) {
CHECK(proto_id_ == nullptr);
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 69593cd..bc2bfde 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -849,30 +849,11 @@
DexFile(const byte* base, size_t size,
const std::string& location,
uint32_t location_checksum,
- MemMap* mem_map)
- : begin_(base),
- size_(size),
- location_(location),
- location_checksum_(location_checksum),
- mem_map_(mem_map),
- modification_lock("DEX modification lock"),
- header_(0),
- string_ids_(0),
- type_ids_(0),
- field_ids_(0),
- method_ids_(0),
- proto_ids_(0),
- class_defs_(0) {
- CHECK(begin_ != NULL) << GetLocation();
- CHECK_GT(size_, 0U) << GetLocation();
- }
+ MemMap* mem_map);
// Top-level initializer that calls other Init methods.
bool Init(std::string* error_msg);
- // Caches pointers into to the various file sections.
- void InitMembers();
-
// Returns true if the header magic and version numbers are of the expected values.
bool CheckMagicAndVersion(std::string* error_msg) const;
@@ -903,26 +884,27 @@
Mutex modification_lock;
// Points to the header section.
- const Header* header_;
+ const Header* const header_;
// Points to the base of the string identifier list.
- const StringId* string_ids_;
+ const StringId* const string_ids_;
// Points to the base of the type identifier list.
- const TypeId* type_ids_;
+ const TypeId* const type_ids_;
// Points to the base of the field identifier list.
- const FieldId* field_ids_;
+ const FieldId* const field_ids_;
// Points to the base of the method identifier list.
- const MethodId* method_ids_;
+ const MethodId* const method_ids_;
// Points to the base of the prototype identifier list.
- const ProtoId* proto_ids_;
+ const ProtoId* const proto_ids_;
// Points to the base of the class definition list.
- const ClassDef* class_defs_;
+ const ClassDef* const class_defs_;
};
+std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
// Iterate over a dex file's ProtoId's paramters
class DexFileParameterIterator {
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 0a3e1a1..2795e1d 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -120,7 +120,7 @@
CHECK_NE(0, prot);
CHECK_NE(0, flags & (MAP_SHARED | MAP_PRIVATE));
if (byte_count == 0) {
- return new MemMap("file", NULL, 0, NULL, 0, prot);
+ return new MemMap(filename, NULL, 0, NULL, 0, prot);
}
// Adjust 'offset' to be page-aligned as required by mmap.
int page_offset = start % kPageSize;
@@ -153,7 +153,7 @@
maps.c_str());
return NULL;
}
- return new MemMap("file", actual + page_offset, byte_count, actual, page_aligned_byte_count,
+ return new MemMap(filename, actual + page_offset, byte_count, actual, page_aligned_byte_count,
prot);
}
@@ -267,4 +267,11 @@
return false;
}
+std::ostream& operator<<(std::ostream& os, const MemMap& mem_map) {
+ os << StringPrintf("[MemMap: %s prot=%x %p-%p]",
+ mem_map.GetName().c_str(), mem_map.GetProtect(),
+ mem_map.BaseBegin(), mem_map.BaseEnd());
+ return os;
+}
+
} // namespace art
diff --git a/runtime/mem_map.h b/runtime/mem_map.h
index 2c65833..d2059b5 100644
--- a/runtime/mem_map.h
+++ b/runtime/mem_map.h
@@ -62,6 +62,10 @@
// Releases the memory mapping
~MemMap();
+ const std::string& GetName() const {
+ return name_;
+ }
+
bool Protect(int prot);
int GetProtect() const {
@@ -80,6 +84,18 @@
return Begin() + Size();
}
+ void* BaseBegin() const {
+ return base_begin_;
+ }
+
+ size_t BaseSize() const {
+ return base_size_;
+ }
+
+ void* BaseEnd() const {
+ return reinterpret_cast<byte*>(BaseBegin()) + BaseSize();
+ }
+
bool HasAddress(const void* addr) const {
return Begin() <= addr && addr < End();
}
@@ -102,6 +118,7 @@
friend class MemMapTest; // To allow access to base_begin_ and base_size_.
};
+std::ostream& operator<<(std::ostream& os, const MemMap& mem_map);
} // namespace art
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index fa2b485..be882048 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -338,12 +338,17 @@
}
if (warn_if_not_found) {
+ std::string checksum("<unspecified>");
+ if (dex_location_checksum != NULL) {
+ checksum = StringPrintf("0x%08x", *dex_location_checksum);
+ }
LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_location
- << " in OatFile " << GetLocation();
+ << " with checksum " << checksum << " 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();
+ << " contains OatDexFile " << it->second->GetDexFileLocation()
+ << " with checksum 0x" << std::hex << it->second->GetDexFileLocationChecksum();
}
}
}