Dump registered class loaders and their dex files for SIGQUIT.
bug: 112405321
Test: take a bugreport
Change-Id: I67f0a61fb42a70023d349f5aa628ac5d15c4d5fe
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e19dedc..8239329 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -8548,6 +8548,49 @@
ReaderMutexLock mu(soa.Self(), *Locks::classlinker_classes_lock_);
os << "Zygote loaded classes=" << NumZygoteClasses() << " post zygote classes="
<< NumNonZygoteClasses() << "\n";
+ ReaderMutexLock mu2(soa.Self(), *Locks::dex_lock_);
+ os << "Dumping registered class loaders\n";
+ size_t class_loader_index = 0;
+ for (const ClassLoaderData& class_loader : class_loaders_) {
+ ObjPtr<mirror::ClassLoader> loader =
+ ObjPtr<mirror::ClassLoader>::DownCast(soa.Self()->DecodeJObject(class_loader.weak_root));
+ if (loader != nullptr) {
+ os << "#" << class_loader_index++ << " " << loader->GetClass()->PrettyDescriptor() << ": [";
+ bool saw_one_dex_file = false;
+ for (const DexCacheData& dex_cache : dex_caches_) {
+ if (dex_cache.IsValid() && dex_cache.class_table == class_loader.class_table) {
+ if (saw_one_dex_file) {
+ os << ":";
+ }
+ saw_one_dex_file = true;
+ os << dex_cache.dex_file->GetLocation();
+ }
+ }
+ os << "]";
+ bool found_parent = false;
+ if (loader->GetParent() != nullptr) {
+ size_t parent_index = 0;
+ for (const ClassLoaderData& class_loader2 : class_loaders_) {
+ ObjPtr<mirror::ClassLoader> loader2 = ObjPtr<mirror::ClassLoader>::DownCast(
+ soa.Self()->DecodeJObject(class_loader2.weak_root));
+ if (loader2 == loader->GetParent()) {
+ os << ", parent #" << parent_index;
+ found_parent = true;
+ break;
+ }
+ parent_index++;
+ }
+ if (!found_parent) {
+ os << ", unregistered parent of type "
+ << loader->GetParent()->GetClass()->PrettyDescriptor();
+ }
+ } else {
+ os << ", no parent";
+ }
+ os << "\n";
+ }
+ }
+ os << "Done dumping class loaders\n";
}
class CountClassesVisitor : public ClassLoaderVisitor {