Ensure class is initialized when reading its fields from debugger.
Bug: 31016523
Test: mm run-jdwp-tests-ri & mm run-jdwp-tests-host
(cherry-picked from commit de19a25625823496bcf8f92352f709c7a3924bfa)
Change-Id: I02f6c66116f4507c89f7ca1cb480d7029d97c485
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 1d93580..7aa9ac4 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1755,22 +1755,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) {
@@ -1784,10 +1794,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;
@@ -1877,12 +1887,21 @@
uint64_t value, int width, bool is_static)
SHARED_REQUIRES(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) {
@@ -1896,9 +1915,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,