Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 86858e9

Browse files
committed
Fix interface method discovery in Java Cloud Debugger
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=108658925
1 parent 4f932d6 commit 86858e9

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/agent/jvm_class_metadata_reader.cc

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "jvm_instance_field_reader.h"
2222
#include "jvm_static_field_reader.h"
2323
#include "jvmti_buffer.h"
24+
#include "jni_proxy_object.h"
2425

2526
namespace devtools {
2627
namespace cdbg {
@@ -104,10 +105,27 @@ void JvmClassMetadataReader::LoadClassMetadata(jclass cls, Entry* metadata) {
104105
&registered_methods,
105106
metadata);
106107

108+
LoadImplementedInterfacesMetadata(
109+
static_cast<jclass>(current_class_ref.get()),
110+
&registered_methods,
111+
metadata);
112+
107113
// Free the current local reference and allocate a new local reference
108114
// corresponding to the superclass of "current_class_ref".
109-
current_class_ref.reset(
115+
JniLocalRef next(
110116
jni()->GetSuperclass(static_cast<jclass>(current_class_ref.get())));
117+
118+
// Don't skip "java.lang.Object" even if "cls" is an interface.
119+
if ((next == nullptr) &&
120+
!jni()->IsSameObject(current_class_ref.get(),
121+
jniproxy::Object()->GetClass())) {
122+
LoadSingleClassMetadata(
123+
jniproxy::Object()->GetClass(),
124+
&registered_methods,
125+
metadata);
126+
}
127+
128+
current_class_ref = std::move(next);
111129
}
112130

113131
// Reverse the the lists to accomodate for LoadFieldInfo appending new
@@ -121,6 +139,28 @@ void JvmClassMetadataReader::LoadClassMetadata(jclass cls, Entry* metadata) {
121139
}
122140

123141

142+
void JvmClassMetadataReader::LoadImplementedInterfacesMetadata(
143+
jclass parent,
144+
std::set<std::pair<string, string>>* registered_methods,
145+
Entry* metadata) {
146+
jvmtiError err = JVMTI_ERROR_NONE;
147+
148+
jint count = 0;
149+
JvmtiBuffer<jclass> interfaces;
150+
err = jvmti()->GetImplementedInterfaces(parent, &count, interfaces.ref());
151+
if (err != JVMTI_ERROR_NONE) {
152+
LOG(ERROR) << "GetImplementedInterfaces failed, error: " << err;
153+
return;
154+
}
155+
156+
for (int i = 0; i < count; ++i) {
157+
jclass interface = interfaces.get()[i];
158+
LoadSingleClassMetadata(interface, registered_methods, metadata);
159+
LoadImplementedInterfacesMetadata(interface, registered_methods, metadata);
160+
}
161+
}
162+
163+
124164
void JvmClassMetadataReader::LoadSingleClassMetadata(
125165
jclass cls,
126166
std::set<std::pair<string, string>>* registered_methods,

src/agent/jvm_class_metadata_reader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ class JvmClassMetadataReader : public ClassMetadataReader {
7676
// function assumes previously uninitialized structure.
7777
void LoadClassMetadata(jclass cls, Entry* metadata);
7878

79+
// Loads metadata of all implemented interfaces of a class.
80+
void LoadImplementedInterfacesMetadata(
81+
jclass parent,
82+
std::set<std::pair<string, string>>* registered_methods,
83+
Entry* metadata);
84+
7985
// Loads metadata of a single Java class ignoring overloaded methods.
8086
void LoadSingleClassMetadata(
8187
jclass cls,

0 commit comments

Comments
 (0)