Add extra logging for bug 77342775.
Test: testrunner.py --host --64 --optimizing
Test: Repeat with disabled filtering to Lorg/apache/http/,
manually expect failure messages.
Bug: 77342775
Change-Id: I98b1e4fb77dc5c6b57a91c7dda19e1a4b15c29be
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 945442d..8fd95ed 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -24,6 +24,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "class_linker-inl.h"
+#include "debug_print.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_instruction-inl.h"
#include "dex/invoke_type.h"
@@ -152,6 +153,7 @@
// ClassCastException
void ThrowClassCastException(ObjPtr<mirror::Class> dest_type, ObjPtr<mirror::Class> src_type) {
+ DumpB77342775DebugData(dest_type, src_type);
ThrowException("Ljava/lang/ClassCastException;", nullptr,
StringPrintf("%s cannot be cast to %s",
mirror::Class::PrettyDescriptor(src_type).c_str(),
@@ -279,6 +281,7 @@
<< "' does not implement interface '" << mirror::Class::PrettyDescriptor(target_class)
<< "' in call to '"
<< ArtMethod::PrettyMethod(method) << "'";
+ DumpB77342775DebugData(target_class, this_object->GetClass());
ThrowException("Ljava/lang/IncompatibleClassChangeError;",
referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
msg.str().c_str());
@@ -295,6 +298,7 @@
<< "' does not implement interface '"
<< mirror::Class::PrettyDescriptor(interface_method->GetDeclaringClass())
<< "' in call to '" << ArtMethod::PrettyMethod(interface_method) << "'";
+ DumpB77342775DebugData(interface_method->GetDeclaringClass(), this_object->GetClass());
ThrowException("Ljava/lang/IncompatibleClassChangeError;",
referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
msg.str().c_str());
diff --git a/runtime/debug_print.cc b/runtime/debug_print.cc
index 44a1836..c7530be 100644
--- a/runtime/debug_print.cc
+++ b/runtime/debug_print.cc
@@ -110,4 +110,50 @@
return oss.str();
}
+void DumpB77342775DebugData(ObjPtr<mirror::Class> target_class, ObjPtr<mirror::Class> src_class) {
+ std::string target_descriptor_storage;
+ const char* target_descriptor = target_class->GetDescriptor(&target_descriptor_storage);
+ const char kCheckedPrefix[] = "Lorg/apache/http/";
+ // Avoid spam for other packages. (That spam would break some ART run-tests for example.)
+ if (strncmp(target_descriptor, kCheckedPrefix, sizeof(kCheckedPrefix) - 1) != 0) {
+ return;
+ }
+ auto matcher = [target_descriptor, target_class](ObjPtr<mirror::Class> klass)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (klass->DescriptorEquals(target_descriptor)) {
+ LOG(ERROR) << " descriptor match in "
+ << DescribeLoaders(klass->GetClassLoader(), target_descriptor)
+ << " match? " << std::boolalpha << (klass == target_class);
+ }
+ };
+
+ std::string source_descriptor_storage;
+ const char* source_descriptor = src_class->GetDescriptor(&source_descriptor_storage);
+
+ if (target_class->IsInterface()) {
+ ObjPtr<mirror::IfTable> iftable = src_class->GetIfTable();
+ CHECK(iftable != nullptr);
+ size_t ifcount = iftable->Count();
+ LOG(ERROR) << "Maybe bug 77342775, looking for " << target_descriptor
+ << " with loader " << DescribeLoaders(src_class->GetClassLoader(), target_descriptor)
+ << " in interface table for " << source_descriptor << " ifcount=" << ifcount;
+ for (size_t i = 0; i != ifcount; ++i) {
+ ObjPtr<mirror::Class> iface = iftable->GetInterface(i);
+ CHECK(iface != nullptr);
+ LOG(ERROR) << " iface #" << i << ": " << iface->PrettyDescriptor();
+ matcher(iface);
+ }
+ } else {
+ LOG(ERROR) << "Maybe bug 77342775, looking for " << target_descriptor
+ << " with loader " << DescribeLoaders(src_class->GetClassLoader(), target_descriptor)
+ << " in superclass chain for " << source_descriptor;
+ for (ObjPtr<mirror::Class> klass = src_class;
+ klass != nullptr;
+ klass = klass->GetSuperClass()) {
+ LOG(ERROR) << " - " << klass->PrettyDescriptor();
+ matcher(klass);
+ }
+ }
+}
+
} // namespace art
diff --git a/runtime/debug_print.h b/runtime/debug_print.h
index 479c36a..df00f06 100644
--- a/runtime/debug_print.h
+++ b/runtime/debug_print.h
@@ -29,6 +29,9 @@
std::string DescribeLoaders(ObjPtr<mirror::ClassLoader> loader, const char* class_descriptor)
REQUIRES_SHARED(Locks::mutator_lock_) COLD_ATTR;
+void DumpB77342775DebugData(ObjPtr<mirror::Class> target_class, ObjPtr<mirror::Class> src_class)
+ REQUIRES_SHARED(Locks::mutator_lock_) COLD_ATTR;
+
} // namespace art
#endif // ART_RUNTIME_DEBUG_PRINT_H_
diff --git a/runtime/verifier/register_line-inl.h b/runtime/verifier/register_line-inl.h
index 39d73f5..5160daf 100644
--- a/runtime/verifier/register_line-inl.h
+++ b/runtime/verifier/register_line-inl.h
@@ -20,6 +20,7 @@
#include "register_line.h"
#include "base/logging.h" // For VLOG.
+#include "debug_print.h"
#include "method_verifier.h"
#include "reg_type_cache-inl.h"
@@ -147,6 +148,14 @@
}
verifier->Fail(fail_type) << "register v" << vsrc << " has type "
<< src_type << " but expected " << check_type;
+ if (check_type.IsNonZeroReferenceTypes() &&
+ !check_type.IsUnresolvedTypes() &&
+ check_type.HasClass() &&
+ src_type.IsNonZeroReferenceTypes() &&
+ !src_type.IsUnresolvedTypes() &&
+ src_type.HasClass()) {
+ DumpB77342775DebugData(check_type.GetClass(), src_type.GetClass());
+ }
return false;
}
if (check_type.IsLowHalf()) {