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,