Avoid crash in StringReference.Value JDWP command

Checks for null or invalid object id. Also checks whether the corresponding
object is a java.lang.String.

Bug: 17492221
Bug: 15005460

(cherry picked from commit 29259fa6b0514866d2d4bf57d58c1557b26abbb7)

Change-Id: I52673bdef6912a4cccf5a6eeecb6e1e817b9dd6b
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 001032c..df51973 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1886,11 +1886,25 @@
   return SetFieldValueImpl(0, field_id, value, width, true);
 }
 
-std::string Dbg::StringToUtf8(JDWP::ObjectId string_id) {
+JDWP::JdwpError Dbg::StringToUtf8(JDWP::ObjectId string_id, std::string* str) {
   JDWP::JdwpError error;
-  mirror::String* s = gRegistry->Get<mirror::String*>(string_id, &error);
-  CHECK(s != nullptr) << error;
-  return s->ToModifiedUtf8();
+  mirror::Object* obj = gRegistry->Get<mirror::Object*>(string_id, &error);
+  if (error != JDWP::ERR_NONE) {
+    return error;
+  }
+  if (obj == nullptr) {
+    return JDWP::ERR_INVALID_OBJECT;
+  }
+  {
+    ScopedObjectAccessUnchecked soa(Thread::Current());
+    mirror::Class* java_lang_String = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_String);
+    if (!java_lang_String->IsAssignableFrom(obj->GetClass())) {
+      // This isn't a string.
+      return JDWP::ERR_INVALID_STRING;
+    }
+  }
+  *str = obj->AsString()->ToModifiedUtf8();
+  return JDWP::ERR_NONE;
 }
 
 void Dbg::OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::ExpandBuf* pReply) {