Fixup JDWP for obsolete methods
We needed to implement some additional methods and behaviors in JDWP
in order to support JVMTI obsolete methods.
Test: Manual (using art/test/915-obsolete-2 & jdb debugger)
Test: Manual (using art/test/915-obsolete-2 & Android Studio/IntelliJ debugger)
Bug: 31455788
Change-Id: I20c2fa27a2dd002e37526b126f23ce552f19e623
(cherry picked from commit 7337631929812fb8a60b5182eba076a32d1cb851)
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index b2fba67..868d8df 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1396,7 +1396,8 @@
mirror::Class* c = m->GetDeclaringClass();
location->type_tag = GetTypeTag(c);
location->class_id = gRegistry->AddRefType(c);
- location->method_id = ToMethodId(m);
+ // The RI Seems to return 0 for all obsolete methods. For compatibility we shall do the same.
+ location->method_id = m->IsObsolete() ? 0 : ToMethodId(m);
location->dex_pc = (m->IsNative() || m->IsProxyMethod()) ? static_cast<uint64_t>(-1) : dex_pc;
}
}
@@ -1409,6 +1410,15 @@
return m->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName();
}
+bool Dbg::IsMethodObsolete(JDWP::MethodId method_id) {
+ ArtMethod* m = FromMethodId(method_id);
+ if (m == nullptr) {
+ // NB Since we return 0 as MID for obsolete methods we want to default to true here.
+ return true;
+ }
+ return m->IsObsolete();
+}
+
std::string Dbg::GetFieldName(JDWP::FieldId field_id) {
ArtField* f = FromFieldId(field_id);
if (f == nullptr) {
@@ -3717,10 +3727,9 @@
if (!m->IsRuntimeMethod()) {
++stack_depth;
if (method == nullptr) {
- mirror::DexCache* dex_cache = m->GetDeclaringClass()->GetDexCache();
+ const DexFile* dex_file = m->GetDexFile();
method = m;
- if (dex_cache != nullptr) {
- const DexFile* dex_file = dex_cache->GetDexFile();
+ if (dex_file != nullptr) {
line_number = annotations::GetLineNumFromPC(dex_file, m, GetDexPc());
}
}
diff --git a/runtime/debugger.h b/runtime/debugger.h
index a7fd160..27124e1 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -370,6 +370,8 @@
//
static std::string GetMethodName(JDWP::MethodId method_id)
REQUIRES_SHARED(Locks::mutator_lock_);
+ static bool IsMethodObsolete(JDWP::MethodId method_id)
+ REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId ref_type_id, bool with_generic,
JDWP::ExpandBuf* pReply)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 964c567..971d039 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -761,12 +761,11 @@
return ERR_NONE;
}
-// Default implementation for IDEs relying on this command.
static JdwpError M_IsObsolete(JdwpState*, Request* request, ExpandBuf* reply)
REQUIRES_SHARED(Locks::mutator_lock_) {
request->ReadRefTypeId(); // unused reference type ID
- request->ReadMethodId(); // unused method ID
- expandBufAdd1(reply, false); // a method is never obsolete.
+ MethodId id = request->ReadMethodId();
+ expandBufAdd1(reply, Dbg::IsMethodObsolete(id));
return ERR_NONE;
}