Ensure class is initialized when reading its fields from debugger.
Bug: 31016523
Test: mm run-jdwp-tests-ri & mm run-jdwp-tests-host
Change-Id: I6bccf8464de7ec1e0c1fdac862cbacf890abede6
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index b49c01c..6ed44fc 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1761,22 +1761,32 @@
return error;
}
- mirror::Object* o = Dbg::GetObjectRegistry()->Get<mirror::Object*>(object_id, &error);
- if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
+ Thread* self = Thread::Current();
+ StackHandleScope<2> hs(self);
+ MutableHandle<mirror::Object>
+ o(hs.NewHandle(Dbg::GetObjectRegistry()->Get<mirror::Object*>(object_id, &error)));
+ if ((!is_static && o.Get() == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
ArtField* f = FromFieldId(field_id);
mirror::Class* receiver_class = c;
- if (receiver_class == nullptr && o != nullptr) {
+ if (receiver_class == nullptr && o.Get() != nullptr) {
receiver_class = o->GetClass();
}
+
// TODO: should we give up now if receiver_class is null?
if (receiver_class != nullptr && !f->GetDeclaringClass()->IsAssignableFrom(receiver_class)) {
LOG(INFO) << "ERR_INVALID_FIELDID: " << PrettyField(f) << " " << PrettyClass(receiver_class);
return JDWP::ERR_INVALID_FIELDID;
}
+ // Ensure the field's class is initialized.
+ Handle<mirror::Class> klass(hs.NewHandle(f->GetDeclaringClass()));
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, klass, true, false)) {
+ LOG(WARNING) << "Not able to initialize class for SetValues: " << PrettyClass(klass.Get());
+ }
+
// The RI only enforces the static/non-static mismatch in one direction.
// TODO: should we change the tests and check both?
if (is_static) {
@@ -1790,10 +1800,10 @@
}
}
if (f->IsStatic()) {
- o = f->GetDeclaringClass();
+ o.Assign(f->GetDeclaringClass());
}
- JValue field_value(GetArtFieldValue(f, o));
+ JValue field_value(GetArtFieldValue(f, o.Get()));
JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor());
Dbg::OutputJValue(tag, &field_value, pReply);
return JDWP::ERR_NONE;
@@ -1883,12 +1893,21 @@
uint64_t value, int width, bool is_static)
REQUIRES_SHARED(Locks::mutator_lock_) {
JDWP::JdwpError error;
- mirror::Object* o = Dbg::GetObjectRegistry()->Get<mirror::Object*>(object_id, &error);
- if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
+ Thread* self = Thread::Current();
+ StackHandleScope<2> hs(self);
+ MutableHandle<mirror::Object>
+ o(hs.NewHandle(Dbg::GetObjectRegistry()->Get<mirror::Object*>(object_id, &error)));
+ if ((!is_static && o.Get() == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
ArtField* f = FromFieldId(field_id);
+ // Ensure the field's class is initialized.
+ Handle<mirror::Class> klass(hs.NewHandle(f->GetDeclaringClass()));
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, klass, true, false)) {
+ LOG(WARNING) << "Not able to initialize class for SetValues: " << PrettyClass(klass.Get());
+ }
+
// The RI only enforces the static/non-static mismatch in one direction.
// TODO: should we change the tests and check both?
if (is_static) {
@@ -1902,9 +1921,9 @@
}
}
if (f->IsStatic()) {
- o = f->GetDeclaringClass();
+ o.Assign(f->GetDeclaringClass());
}
- return SetArtFieldValue(f, o, value, width);
+ return SetArtFieldValue(f, o.Get(), value, width);
}
JDWP::JdwpError Dbg::SetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id, uint64_t value,