From de19a25625823496bcf8f92352f709c7a3924bfa Mon Sep 17 00:00:00 2001 From: Jeff Hao Date: Wed, 14 Sep 2016 15:56:35 -0700 Subject: [PATCH] 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 --- runtime/debugger.cc | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/runtime/debugger.cc b/runtime/debugger.cc index b49c01cfb..6ed44fc5c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -1761,22 +1761,32 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje return error; } - mirror::Object* o = Dbg::GetObjectRegistry()->Get(object_id, &error); - if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) { + Thread* self = Thread::Current(); + StackHandleScope<2> hs(self); + MutableHandle + o(hs.NewHandle(Dbg::GetObjectRegistry()->Get(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 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 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje } } 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 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId uint64_t value, int width, bool is_static) REQUIRES_SHARED(Locks::mutator_lock_) { JDWP::JdwpError error; - mirror::Object* o = Dbg::GetObjectRegistry()->Get(object_id, &error); - if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) { + Thread* self = Thread::Current(); + StackHandleScope<2> hs(self); + MutableHandle + o(hs.NewHandle(Dbg::GetObjectRegistry()->Get(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 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 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId } } 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, -- 2.11.0