Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <unistd.h>
     20 
     21 #include <string>
     22 
     23 #include "atomic.h"
     24 #include "base/logging.h"
     25 #include "base/macros.h"
     26 #include "base/stringprintf.h"
     27 #include "debugger.h"
     28 #include "jdwp/jdwp_constants.h"
     29 #include "jdwp/jdwp_event.h"
     30 #include "jdwp/jdwp_expand_buf.h"
     31 #include "jdwp/jdwp_priv.h"
     32 #include "runtime.h"
     33 #include "thread-inl.h"
     34 #include "UniquePtr.h"
     35 
     36 namespace art {
     37 
     38 namespace JDWP {
     39 
     40 std::string DescribeField(const FieldId& field_id) {
     41   return StringPrintf("%#x (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
     42 }
     43 
     44 std::string DescribeMethod(const MethodId& method_id) {
     45   return StringPrintf("%#x (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
     46 }
     47 
     48 std::string DescribeRefTypeId(const RefTypeId& ref_type_id) {
     49   std::string signature("unknown");
     50   Dbg::GetSignature(ref_type_id, signature);
     51   return StringPrintf("%#llx (%s)", ref_type_id, signature.c_str());
     52 }
     53 
     54 // Helper function: write a variable-width value into the output input buffer.
     55 static void WriteValue(ExpandBuf* pReply, int width, uint64_t value) {
     56   switch (width) {
     57   case 1:     expandBufAdd1(pReply, value); break;
     58   case 2:     expandBufAdd2BE(pReply, value); break;
     59   case 4:     expandBufAdd4BE(pReply, value); break;
     60   case 8:     expandBufAdd8BE(pReply, value); break;
     61   default:    LOG(FATAL) << width; break;
     62   }
     63 }
     64 
     65 static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
     66     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     67   uint8_t tag;
     68   JdwpError rc = Dbg::GetObjectTag(object_id, tag);
     69   if (rc == ERR_NONE) {
     70     expandBufAdd1(reply, tag);
     71     expandBufAddObjectId(reply, object_id);
     72   }
     73   return rc;
     74 }
     75 
     76 static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects)
     77     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     78   expandBufAdd4BE(reply, objects.size());
     79   for (size_t i = 0; i < objects.size(); ++i) {
     80     JdwpError rc = WriteTaggedObject(reply, objects[i]);
     81     if (rc != ERR_NONE) {
     82       return rc;
     83     }
     84   }
     85   return ERR_NONE;
     86 }
     87 
     88 /*
     89  * Common code for *_InvokeMethod requests.
     90  *
     91  * If "is_constructor" is set, this returns "object_id" rather than the
     92  * expected-to-be-void return value of the called function.
     93  */
     94 static JdwpError FinishInvoke(JdwpState*, Request& request, ExpandBuf* pReply,
     95                               ObjectId thread_id, ObjectId object_id,
     96                               RefTypeId class_id, MethodId method_id, bool is_constructor)
     97     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     98   CHECK(!is_constructor || object_id != 0);
     99 
    100   int32_t arg_count = request.ReadSigned32("argument count");
    101 
    102   VLOG(jdwp) << StringPrintf("    --> thread_id=%#llx object_id=%#llx", thread_id, object_id);
    103   VLOG(jdwp) << StringPrintf("        class_id=%#llx method_id=%x %s.%s", class_id,
    104                              method_id, Dbg::GetClassName(class_id).c_str(),
    105                              Dbg::GetMethodName(method_id).c_str());
    106   VLOG(jdwp) << StringPrintf("        %d args:", arg_count);
    107 
    108   UniquePtr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
    109   UniquePtr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : NULL);
    110   for (int32_t i = 0; i < arg_count; ++i) {
    111     argTypes[i] = request.ReadTag();
    112     size_t width = Dbg::GetTagWidth(argTypes[i]);
    113     argValues[i] = request.ReadValue(width);
    114     VLOG(jdwp) << "          " << argTypes[i] << StringPrintf("(%zd): %#llx", width, argValues[i]);
    115   }
    116 
    117   uint32_t options = request.ReadUnsigned32("InvokeOptions bit flags");
    118   VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options,
    119                              (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
    120                              (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
    121 
    122   JdwpTag resultTag;
    123   uint64_t resultValue;
    124   ObjectId exceptObjId;
    125   JdwpError err = Dbg::InvokeMethod(thread_id, object_id, class_id, method_id, arg_count, argValues.get(), argTypes.get(), options, &resultTag, &resultValue, &exceptObjId);
    126   if (err != ERR_NONE) {
    127     return err;
    128   }
    129 
    130   if (err == ERR_NONE) {
    131     if (is_constructor) {
    132       // If we invoked a constructor (which actually returns void), return the receiver,
    133       // unless we threw, in which case we return NULL.
    134       resultTag = JT_OBJECT;
    135       resultValue = (exceptObjId == 0) ? object_id : 0;
    136     }
    137 
    138     size_t width = Dbg::GetTagWidth(resultTag);
    139     expandBufAdd1(pReply, resultTag);
    140     if (width != 0) {
    141       WriteValue(pReply, width, resultValue);
    142     }
    143     expandBufAdd1(pReply, JT_OBJECT);
    144     expandBufAddObjectId(pReply, exceptObjId);
    145 
    146     VLOG(jdwp) << "  --> returned " << resultTag << StringPrintf(" %#llx (except=%#llx)", resultValue, exceptObjId);
    147 
    148     /* show detailed debug output */
    149     if (resultTag == JT_STRING && exceptObjId == 0) {
    150       if (resultValue != 0) {
    151         VLOG(jdwp) << "      string '" << Dbg::StringToUtf8(resultValue) << "'";
    152       } else {
    153         VLOG(jdwp) << "      string (null)";
    154       }
    155     }
    156   }
    157 
    158   return err;
    159 }
    160 
    161 static JdwpError VM_Version(JdwpState*, Request&, ExpandBuf* pReply)
    162     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    163   // Text information on runtime version.
    164   std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
    165   expandBufAddUtf8String(pReply, version);
    166 
    167   // JDWP version numbers, major and minor.
    168   expandBufAdd4BE(pReply, 1);
    169   expandBufAdd4BE(pReply, 6);
    170 
    171   // "java.version".
    172   expandBufAddUtf8String(pReply, "1.6.0");
    173 
    174   // "java.vm.name".
    175   expandBufAddUtf8String(pReply, "Dalvik");
    176 
    177   return ERR_NONE;
    178 }
    179 
    180 /*
    181  * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
    182  * referenceTypeID.  We need to send back more than one if the class has
    183  * been loaded by multiple class loaders.
    184  */
    185 static JdwpError VM_ClassesBySignature(JdwpState*, Request& request, ExpandBuf* pReply)
    186     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    187   std::string classDescriptor(request.ReadUtf8String());
    188 
    189   std::vector<RefTypeId> ids;
    190   Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), ids);
    191 
    192   expandBufAdd4BE(pReply, ids.size());
    193 
    194   for (size_t i = 0; i < ids.size(); ++i) {
    195     // Get class vs. interface and status flags.
    196     JDWP::JdwpTypeTag type_tag;
    197     uint32_t class_status;
    198     JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
    199     if (status != ERR_NONE) {
    200       return status;
    201     }
    202 
    203     expandBufAdd1(pReply, type_tag);
    204     expandBufAddRefTypeId(pReply, ids[i]);
    205     expandBufAdd4BE(pReply, class_status);
    206   }
    207 
    208   return ERR_NONE;
    209 }
    210 
    211 /*
    212  * Handle request for the thread IDs of all running threads.
    213  *
    214  * We exclude ourselves from the list, because we don't allow ourselves
    215  * to be suspended, and that violates some JDWP expectations.
    216  */
    217 static JdwpError VM_AllThreads(JdwpState*, Request&, ExpandBuf* pReply)
    218     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    219   std::vector<ObjectId> thread_ids;
    220   Dbg::GetThreads(0, thread_ids);
    221 
    222   expandBufAdd4BE(pReply, thread_ids.size());
    223   for (uint32_t i = 0; i < thread_ids.size(); ++i) {
    224     expandBufAddObjectId(pReply, thread_ids[i]);
    225   }
    226 
    227   return ERR_NONE;
    228 }
    229 
    230 /*
    231  * List all thread groups that do not have a parent.
    232  */
    233 static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request&, ExpandBuf* pReply)
    234     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    235   /*
    236    * TODO: maintain a list of parentless thread groups in the VM.
    237    *
    238    * For now, just return "system".  Application threads are created
    239    * in "main", which is a child of "system".
    240    */
    241   uint32_t groups = 1;
    242   expandBufAdd4BE(pReply, groups);
    243   ObjectId thread_group_id = Dbg::GetSystemThreadGroupId();
    244   expandBufAddObjectId(pReply, thread_group_id);
    245 
    246   return ERR_NONE;
    247 }
    248 
    249 /*
    250  * Respond with the sizes of the basic debugger types.
    251  *
    252  * All IDs are 8 bytes.
    253  */
    254 static JdwpError VM_IDSizes(JdwpState*, Request&, ExpandBuf* pReply)
    255     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    256   expandBufAdd4BE(pReply, sizeof(FieldId));
    257   expandBufAdd4BE(pReply, sizeof(MethodId));
    258   expandBufAdd4BE(pReply, sizeof(ObjectId));
    259   expandBufAdd4BE(pReply, sizeof(RefTypeId));
    260   expandBufAdd4BE(pReply, sizeof(FrameId));
    261   return ERR_NONE;
    262 }
    263 
    264 static JdwpError VM_Dispose(JdwpState*, Request&, ExpandBuf*)
    265     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    266   Dbg::Disposed();
    267   return ERR_NONE;
    268 }
    269 
    270 /*
    271  * Suspend the execution of the application running in the VM (i.e. suspend
    272  * all threads).
    273  *
    274  * This needs to increment the "suspend count" on all threads.
    275  */
    276 static JdwpError VM_Suspend(JdwpState*, Request&, ExpandBuf*)
    277     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    278   Thread* self = Thread::Current();
    279   self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
    280   Dbg::SuspendVM();
    281   self->TransitionFromSuspendedToRunnable();
    282   return ERR_NONE;
    283 }
    284 
    285 /*
    286  * Resume execution.  Decrements the "suspend count" of all threads.
    287  */
    288 static JdwpError VM_Resume(JdwpState*, Request&, ExpandBuf*)
    289     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    290   Dbg::ResumeVM();
    291   return ERR_NONE;
    292 }
    293 
    294 static JdwpError VM_Exit(JdwpState* state, Request& request, ExpandBuf*)
    295     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    296   uint32_t exit_status = request.ReadUnsigned32("exit_status");
    297   state->ExitAfterReplying(exit_status);
    298   return ERR_NONE;
    299 }
    300 
    301 /*
    302  * Create a new string in the VM and return its ID.
    303  *
    304  * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
    305  * string "java.util.Arrays".)
    306  */
    307 static JdwpError VM_CreateString(JdwpState*, Request& request, ExpandBuf* pReply)
    308     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    309   std::string str(request.ReadUtf8String());
    310   ObjectId stringId = Dbg::CreateString(str);
    311   if (stringId == 0) {
    312     return ERR_OUT_OF_MEMORY;
    313   }
    314   expandBufAddObjectId(pReply, stringId);
    315   return ERR_NONE;
    316 }
    317 
    318 static JdwpError VM_ClassPaths(JdwpState*, Request&, ExpandBuf* pReply)
    319     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    320   expandBufAddUtf8String(pReply, "/");
    321 
    322   std::vector<std::string> class_path;
    323   Split(Runtime::Current()->GetClassPathString(), ':', class_path);
    324   expandBufAdd4BE(pReply, class_path.size());
    325   for (size_t i = 0; i < class_path.size(); ++i) {
    326     expandBufAddUtf8String(pReply, class_path[i]);
    327   }
    328 
    329   std::vector<std::string> boot_class_path;
    330   Split(Runtime::Current()->GetBootClassPathString(), ':', boot_class_path);
    331   expandBufAdd4BE(pReply, boot_class_path.size());
    332   for (size_t i = 0; i < boot_class_path.size(); ++i) {
    333     expandBufAddUtf8String(pReply, boot_class_path[i]);
    334   }
    335 
    336   return ERR_NONE;
    337 }
    338 
    339 static JdwpError VM_DisposeObjects(JdwpState*, Request& request, ExpandBuf*)
    340     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    341   size_t object_count = request.ReadUnsigned32("object_count");
    342   for (size_t i = 0; i < object_count; ++i) {
    343     ObjectId object_id = request.ReadObjectId();
    344     uint32_t reference_count = request.ReadUnsigned32("reference_count");
    345     Dbg::DisposeObject(object_id, reference_count);
    346   }
    347   return ERR_NONE;
    348 }
    349 
    350 static JdwpError VM_Capabilities(JdwpState*, Request&, ExpandBuf* reply)
    351     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    352   expandBufAdd1(reply, false);   // canWatchFieldModification
    353   expandBufAdd1(reply, false);   // canWatchFieldAccess
    354   expandBufAdd1(reply, true);    // canGetBytecodes
    355   expandBufAdd1(reply, true);    // canGetSyntheticAttribute
    356   expandBufAdd1(reply, true);    // canGetOwnedMonitorInfo
    357   expandBufAdd1(reply, true);    // canGetCurrentContendedMonitor
    358   expandBufAdd1(reply, true);    // canGetMonitorInfo
    359   return ERR_NONE;
    360 }
    361 
    362 static JdwpError VM_CapabilitiesNew(JdwpState*, Request& request, ExpandBuf* reply)
    363     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    364   // The first few capabilities are the same as those reported by the older call.
    365   VM_Capabilities(NULL, request, reply);
    366 
    367   expandBufAdd1(reply, false);   // canRedefineClasses
    368   expandBufAdd1(reply, false);   // canAddMethod
    369   expandBufAdd1(reply, false);   // canUnrestrictedlyRedefineClasses
    370   expandBufAdd1(reply, false);   // canPopFrames
    371   expandBufAdd1(reply, false);   // canUseInstanceFilters
    372   expandBufAdd1(reply, false);   // canGetSourceDebugExtension
    373   expandBufAdd1(reply, false);   // canRequestVMDeathEvent
    374   expandBufAdd1(reply, false);   // canSetDefaultStratum
    375   expandBufAdd1(reply, true);    // 1.6: canGetInstanceInfo
    376   expandBufAdd1(reply, false);   // 1.6: canRequestMonitorEvents
    377   expandBufAdd1(reply, true);    // 1.6: canGetMonitorFrameInfo
    378   expandBufAdd1(reply, false);   // 1.6: canUseSourceNameFilters
    379   expandBufAdd1(reply, false);   // 1.6: canGetConstantPool
    380   expandBufAdd1(reply, false);   // 1.6: canForceEarlyReturn
    381 
    382   // Fill in reserved22 through reserved32; note count started at 1.
    383   for (size_t i = 22; i <= 32; ++i) {
    384     expandBufAdd1(reply, false);
    385   }
    386   return ERR_NONE;
    387 }
    388 
    389 static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
    390     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    391   std::vector<JDWP::RefTypeId> classes;
    392   Dbg::GetClassList(classes);
    393 
    394   expandBufAdd4BE(pReply, classes.size());
    395 
    396   for (size_t i = 0; i < classes.size(); ++i) {
    397     static const char genericSignature[1] = "";
    398     JDWP::JdwpTypeTag type_tag;
    399     std::string descriptor;
    400     uint32_t class_status;
    401     JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
    402     if (status != ERR_NONE) {
    403       return status;
    404     }
    405 
    406     expandBufAdd1(pReply, type_tag);
    407     expandBufAddRefTypeId(pReply, classes[i]);
    408     if (descriptor_and_status) {
    409       expandBufAddUtf8String(pReply, descriptor);
    410       if (generic) {
    411         expandBufAddUtf8String(pReply, genericSignature);
    412       }
    413       expandBufAdd4BE(pReply, class_status);
    414     }
    415   }
    416 
    417   return ERR_NONE;
    418 }
    419 
    420 static JdwpError VM_AllClasses(JdwpState*, Request&, ExpandBuf* pReply)
    421     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    422   return VM_AllClassesImpl(pReply, true, false);
    423 }
    424 
    425 static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request&, ExpandBuf* pReply)
    426     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    427   return VM_AllClassesImpl(pReply, true, true);
    428 }
    429 
    430 static JdwpError VM_InstanceCounts(JdwpState*, Request& request, ExpandBuf* pReply)
    431     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    432   int32_t class_count = request.ReadSigned32("class count");
    433   if (class_count < 0) {
    434     return ERR_ILLEGAL_ARGUMENT;
    435   }
    436   std::vector<RefTypeId> class_ids;
    437   for (int32_t i = 0; i < class_count; ++i) {
    438     class_ids.push_back(request.ReadRefTypeId());
    439   }
    440 
    441   std::vector<uint64_t> counts;
    442   JdwpError rc = Dbg::GetInstanceCounts(class_ids, counts);
    443   if (rc != ERR_NONE) {
    444     return rc;
    445   }
    446 
    447   expandBufAdd4BE(pReply, counts.size());
    448   for (size_t i = 0; i < counts.size(); ++i) {
    449     expandBufAdd8BE(pReply, counts[i]);
    450   }
    451   return ERR_NONE;
    452 }
    453 
    454 static JdwpError RT_Modifiers(JdwpState*, Request& request, ExpandBuf* pReply)
    455     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    456   RefTypeId refTypeId = request.ReadRefTypeId();
    457   return Dbg::GetModifiers(refTypeId, pReply);
    458 }
    459 
    460 /*
    461  * Get values from static fields in a reference type.
    462  */
    463 static JdwpError RT_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
    464     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    465   RefTypeId refTypeId = request.ReadRefTypeId();
    466   int32_t field_count = request.ReadSigned32("field count");
    467   expandBufAdd4BE(pReply, field_count);
    468   for (int32_t i = 0; i < field_count; ++i) {
    469     FieldId fieldId = request.ReadFieldId();
    470     JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
    471     if (status != ERR_NONE) {
    472       return status;
    473     }
    474   }
    475   return ERR_NONE;
    476 }
    477 
    478 /*
    479  * Get the name of the source file in which a reference type was declared.
    480  */
    481 static JdwpError RT_SourceFile(JdwpState*, Request& request, ExpandBuf* pReply)
    482     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    483   RefTypeId refTypeId = request.ReadRefTypeId();
    484   std::string source_file;
    485   JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
    486   if (status != ERR_NONE) {
    487     return status;
    488   }
    489   expandBufAddUtf8String(pReply, source_file);
    490   return ERR_NONE;
    491 }
    492 
    493 /*
    494  * Return the current status of the reference type.
    495  */
    496 static JdwpError RT_Status(JdwpState*, Request& request, ExpandBuf* pReply)
    497     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    498   RefTypeId refTypeId = request.ReadRefTypeId();
    499   JDWP::JdwpTypeTag type_tag;
    500   uint32_t class_status;
    501   JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
    502   if (status != ERR_NONE) {
    503     return status;
    504   }
    505   expandBufAdd4BE(pReply, class_status);
    506   return ERR_NONE;
    507 }
    508 
    509 /*
    510  * Return interfaces implemented directly by this class.
    511  */
    512 static JdwpError RT_Interfaces(JdwpState*, Request& request, ExpandBuf* pReply)
    513     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    514   RefTypeId refTypeId = request.ReadRefTypeId();
    515   return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
    516 }
    517 
    518 /*
    519  * Return the class object corresponding to this type.
    520  */
    521 static JdwpError RT_ClassObject(JdwpState*, Request& request, ExpandBuf* pReply)
    522     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    523   RefTypeId refTypeId = request.ReadRefTypeId();
    524   ObjectId class_object_id;
    525   JdwpError status = Dbg::GetClassObject(refTypeId, class_object_id);
    526   if (status != ERR_NONE) {
    527     return status;
    528   }
    529   VLOG(jdwp) << StringPrintf("    --> ObjectId %#llx", class_object_id);
    530   expandBufAddObjectId(pReply, class_object_id);
    531   return ERR_NONE;
    532 }
    533 
    534 /*
    535  * Returns the value of the SourceDebugExtension attribute.
    536  *
    537  * JDB seems interested, but DEX files don't currently support this.
    538  */
    539 static JdwpError RT_SourceDebugExtension(JdwpState*, Request&, ExpandBuf*)
    540     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    541   /* referenceTypeId in, string out */
    542   return ERR_ABSENT_INFORMATION;
    543 }
    544 
    545 static JdwpError RT_Signature(JdwpState*, Request& request, ExpandBuf* pReply, bool with_generic)
    546     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    547   RefTypeId refTypeId = request.ReadRefTypeId();
    548 
    549   std::string signature;
    550   JdwpError status = Dbg::GetSignature(refTypeId, signature);
    551   if (status != ERR_NONE) {
    552     return status;
    553   }
    554   expandBufAddUtf8String(pReply, signature);
    555   if (with_generic) {
    556     expandBufAddUtf8String(pReply, "");
    557   }
    558   return ERR_NONE;
    559 }
    560 
    561 static JdwpError RT_Signature(JdwpState* state, Request& request, ExpandBuf* pReply)
    562     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    563   return RT_Signature(state, request, pReply, false);
    564 }
    565 
    566 static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request& request, ExpandBuf* pReply)
    567     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    568   return RT_Signature(state, request, pReply, true);
    569 }
    570 
    571 /*
    572  * Return the instance of java.lang.ClassLoader that loaded the specified
    573  * reference type, or null if it was loaded by the system loader.
    574  */
    575 static JdwpError RT_ClassLoader(JdwpState*, Request& request, ExpandBuf* pReply)
    576     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    577   RefTypeId refTypeId = request.ReadRefTypeId();
    578   return Dbg::GetClassLoader(refTypeId, pReply);
    579 }
    580 
    581 /*
    582  * Given a referenceTypeId, return a block of stuff that describes the
    583  * fields declared by a class.
    584  */
    585 static JdwpError RT_FieldsWithGeneric(JdwpState*, Request& request, ExpandBuf* pReply)
    586     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    587   RefTypeId refTypeId = request.ReadRefTypeId();
    588   return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
    589 }
    590 
    591 // Obsolete equivalent of FieldsWithGeneric, without the generic type information.
    592 static JdwpError RT_Fields(JdwpState*, Request& request, ExpandBuf* pReply)
    593     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    594   RefTypeId refTypeId = request.ReadRefTypeId();
    595   return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
    596 }
    597 
    598 /*
    599  * Given a referenceTypeID, return a block of goodies describing the
    600  * methods declared by a class.
    601  */
    602 static JdwpError RT_MethodsWithGeneric(JdwpState*, Request& request, ExpandBuf* pReply)
    603     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    604   RefTypeId refTypeId = request.ReadRefTypeId();
    605   return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
    606 }
    607 
    608 // Obsolete equivalent of MethodsWithGeneric, without the generic type information.
    609 static JdwpError RT_Methods(JdwpState*, Request& request, ExpandBuf* pReply)
    610     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    611   RefTypeId refTypeId = request.ReadRefTypeId();
    612   return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
    613 }
    614 
    615 static JdwpError RT_Instances(JdwpState*, Request& request, ExpandBuf* reply)
    616     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    617   RefTypeId class_id = request.ReadRefTypeId();
    618   int32_t max_count = request.ReadSigned32("max count");
    619   if (max_count < 0) {
    620     return ERR_ILLEGAL_ARGUMENT;
    621   }
    622 
    623   std::vector<ObjectId> instances;
    624   JdwpError rc = Dbg::GetInstances(class_id, max_count, instances);
    625   if (rc != ERR_NONE) {
    626     return rc;
    627   }
    628 
    629   return WriteTaggedObjectList(reply, instances);
    630 }
    631 
    632 /*
    633  * Return the immediate superclass of a class.
    634  */
    635 static JdwpError CT_Superclass(JdwpState*, Request& request, ExpandBuf* pReply)
    636     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    637   RefTypeId class_id = request.ReadRefTypeId();
    638   RefTypeId superClassId;
    639   JdwpError status = Dbg::GetSuperclass(class_id, superClassId);
    640   if (status != ERR_NONE) {
    641     return status;
    642   }
    643   expandBufAddRefTypeId(pReply, superClassId);
    644   return ERR_NONE;
    645 }
    646 
    647 /*
    648  * Set static class values.
    649  */
    650 static JdwpError CT_SetValues(JdwpState* , Request& request, ExpandBuf*)
    651     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    652   RefTypeId class_id = request.ReadRefTypeId();
    653   int32_t values_count = request.ReadSigned32("values count");
    654 
    655   UNUSED(class_id);
    656 
    657   for (int32_t i = 0; i < values_count; ++i) {
    658     FieldId fieldId = request.ReadFieldId();
    659     JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
    660     size_t width = Dbg::GetTagWidth(fieldTag);
    661     uint64_t value = request.ReadValue(width);
    662 
    663     VLOG(jdwp) << "    --> field=" << fieldId << " tag=" << fieldTag << " --> " << value;
    664     JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
    665     if (status != ERR_NONE) {
    666       return status;
    667     }
    668   }
    669 
    670   return ERR_NONE;
    671 }
    672 
    673 /*
    674  * Invoke a static method.
    675  *
    676  * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
    677  * values in the "variables" display.
    678  */
    679 static JdwpError CT_InvokeMethod(JdwpState* state, Request& request, ExpandBuf* pReply)
    680     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    681   RefTypeId class_id = request.ReadRefTypeId();
    682   ObjectId thread_id = request.ReadThreadId();
    683   MethodId method_id = request.ReadMethodId();
    684 
    685   return FinishInvoke(state, request, pReply, thread_id, 0, class_id, method_id, false);
    686 }
    687 
    688 /*
    689  * Create a new object of the requested type, and invoke the specified
    690  * constructor.
    691  *
    692  * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
    693  * see the contents of a byte[] as a string.
    694  */
    695 static JdwpError CT_NewInstance(JdwpState* state, Request& request, ExpandBuf* pReply)
    696     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    697   RefTypeId class_id = request.ReadRefTypeId();
    698   ObjectId thread_id = request.ReadThreadId();
    699   MethodId method_id = request.ReadMethodId();
    700 
    701   ObjectId object_id;
    702   JdwpError status = Dbg::CreateObject(class_id, object_id);
    703   if (status != ERR_NONE) {
    704     return status;
    705   }
    706   if (object_id == 0) {
    707     return ERR_OUT_OF_MEMORY;
    708   }
    709   return FinishInvoke(state, request, pReply, thread_id, object_id, class_id, method_id, true);
    710 }
    711 
    712 /*
    713  * Create a new array object of the requested type and length.
    714  */
    715 static JdwpError AT_newInstance(JdwpState*, Request& request, ExpandBuf* pReply)
    716     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    717   RefTypeId arrayTypeId = request.ReadRefTypeId();
    718   int32_t length = request.ReadSigned32("length");
    719 
    720   ObjectId object_id;
    721   JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, object_id);
    722   if (status != ERR_NONE) {
    723     return status;
    724   }
    725   if (object_id == 0) {
    726     return ERR_OUT_OF_MEMORY;
    727   }
    728   expandBufAdd1(pReply, JT_ARRAY);
    729   expandBufAddObjectId(pReply, object_id);
    730   return ERR_NONE;
    731 }
    732 
    733 /*
    734  * Return line number information for the method, if present.
    735  */
    736 static JdwpError M_LineTable(JdwpState*, Request& request, ExpandBuf* pReply)
    737     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    738   RefTypeId refTypeId = request.ReadRefTypeId();
    739   MethodId method_id = request.ReadMethodId();
    740 
    741   Dbg::OutputLineTable(refTypeId, method_id, pReply);
    742 
    743   return ERR_NONE;
    744 }
    745 
    746 static JdwpError M_VariableTable(JdwpState*, Request& request, ExpandBuf* pReply,
    747                                  bool generic)
    748     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    749   RefTypeId class_id = request.ReadRefTypeId();
    750   MethodId method_id = request.ReadMethodId();
    751 
    752   // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
    753   // information. That will cause Eclipse to make a best-effort attempt at displaying local
    754   // variables anonymously. However, the attempt isn't very good, so we're probably better off just
    755   // not showing anything.
    756   Dbg::OutputVariableTable(class_id, method_id, generic, pReply);
    757   return ERR_NONE;
    758 }
    759 
    760 static JdwpError M_VariableTable(JdwpState* state, Request& request, ExpandBuf* pReply)
    761     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    762   return M_VariableTable(state, request, pReply, false);
    763 }
    764 
    765 static JdwpError M_VariableTableWithGeneric(JdwpState* state, Request& request, ExpandBuf* pReply)
    766     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    767   return M_VariableTable(state, request, pReply, true);
    768 }
    769 
    770 static JdwpError M_Bytecodes(JdwpState*, Request& request, ExpandBuf* reply)
    771     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    772   RefTypeId class_id = request.ReadRefTypeId();
    773   MethodId method_id = request.ReadMethodId();
    774 
    775   std::vector<uint8_t> bytecodes;
    776   JdwpError rc = Dbg::GetBytecodes(class_id, method_id, bytecodes);
    777   if (rc != ERR_NONE) {
    778     return rc;
    779   }
    780 
    781   expandBufAdd4BE(reply, bytecodes.size());
    782   for (size_t i = 0; i < bytecodes.size(); ++i) {
    783     expandBufAdd1(reply, bytecodes[i]);
    784   }
    785 
    786   return ERR_NONE;
    787 }
    788 
    789 /*
    790  * Given an object reference, return the runtime type of the object
    791  * (class or array).
    792  *
    793  * This can get called on different things, e.g. thread_id gets
    794  * passed in here.
    795  */
    796 static JdwpError OR_ReferenceType(JdwpState*, Request& request, ExpandBuf* pReply)
    797     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    798   ObjectId object_id = request.ReadObjectId();
    799   return Dbg::GetReferenceType(object_id, pReply);
    800 }
    801 
    802 /*
    803  * Get values from the fields of an object.
    804  */
    805 static JdwpError OR_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
    806     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    807   ObjectId object_id = request.ReadObjectId();
    808   int32_t field_count = request.ReadSigned32("field count");
    809 
    810   expandBufAdd4BE(pReply, field_count);
    811   for (int32_t i = 0; i < field_count; ++i) {
    812     FieldId fieldId = request.ReadFieldId();
    813     JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
    814     if (status != ERR_NONE) {
    815       return status;
    816     }
    817   }
    818 
    819   return ERR_NONE;
    820 }
    821 
    822 /*
    823  * Set values in the fields of an object.
    824  */
    825 static JdwpError OR_SetValues(JdwpState*, Request& request, ExpandBuf*)
    826     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    827   ObjectId object_id = request.ReadObjectId();
    828   int32_t field_count = request.ReadSigned32("field count");
    829 
    830   for (int32_t i = 0; i < field_count; ++i) {
    831     FieldId fieldId = request.ReadFieldId();
    832 
    833     JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
    834     size_t width = Dbg::GetTagWidth(fieldTag);
    835     uint64_t value = request.ReadValue(width);
    836 
    837     VLOG(jdwp) << "    --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
    838     JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
    839     if (status != ERR_NONE) {
    840       return status;
    841     }
    842   }
    843 
    844   return ERR_NONE;
    845 }
    846 
    847 static JdwpError OR_MonitorInfo(JdwpState*, Request& request, ExpandBuf* reply)
    848     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    849   ObjectId object_id = request.ReadObjectId();
    850   return Dbg::GetMonitorInfo(object_id, reply);
    851 }
    852 
    853 /*
    854  * Invoke an instance method.  The invocation must occur in the specified
    855  * thread, which must have been suspended by an event.
    856  *
    857  * The call is synchronous.  All threads in the VM are resumed, unless the
    858  * SINGLE_THREADED flag is set.
    859  *
    860  * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
    861  * object), it will try to invoke the object's toString() function.  This
    862  * feature becomes crucial when examining ArrayLists with Eclipse.
    863  */
    864 static JdwpError OR_InvokeMethod(JdwpState* state, Request& request, ExpandBuf* pReply)
    865     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    866   ObjectId object_id = request.ReadObjectId();
    867   ObjectId thread_id = request.ReadThreadId();
    868   RefTypeId class_id = request.ReadRefTypeId();
    869   MethodId method_id = request.ReadMethodId();
    870 
    871   return FinishInvoke(state, request, pReply, thread_id, object_id, class_id, method_id, false);
    872 }
    873 
    874 static JdwpError OR_DisableCollection(JdwpState*, Request& request, ExpandBuf*)
    875     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    876   ObjectId object_id = request.ReadObjectId();
    877   return Dbg::DisableCollection(object_id);
    878 }
    879 
    880 static JdwpError OR_EnableCollection(JdwpState*, Request& request, ExpandBuf*)
    881     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    882   ObjectId object_id = request.ReadObjectId();
    883   return Dbg::EnableCollection(object_id);
    884 }
    885 
    886 static JdwpError OR_IsCollected(JdwpState*, Request& request, ExpandBuf* pReply)
    887     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    888   ObjectId object_id = request.ReadObjectId();
    889   bool is_collected;
    890   JdwpError rc = Dbg::IsCollected(object_id, is_collected);
    891   expandBufAdd1(pReply, is_collected ? 1 : 0);
    892   return rc;
    893 }
    894 
    895 static JdwpError OR_ReferringObjects(JdwpState*, Request& request, ExpandBuf* reply)
    896     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    897   ObjectId object_id = request.ReadObjectId();
    898   int32_t max_count = request.ReadSigned32("max count");
    899   if (max_count < 0) {
    900     return ERR_ILLEGAL_ARGUMENT;
    901   }
    902 
    903   std::vector<ObjectId> referring_objects;
    904   JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, referring_objects);
    905   if (rc != ERR_NONE) {
    906     return rc;
    907   }
    908 
    909   return WriteTaggedObjectList(reply, referring_objects);
    910 }
    911 
    912 /*
    913  * Return the string value in a string object.
    914  */
    915 static JdwpError SR_Value(JdwpState*, Request& request, ExpandBuf* pReply)
    916     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    917   ObjectId stringObject = request.ReadObjectId();
    918   std::string str(Dbg::StringToUtf8(stringObject));
    919 
    920   VLOG(jdwp) << StringPrintf("    --> %s", PrintableString(str).c_str());
    921 
    922   expandBufAddUtf8String(pReply, str);
    923 
    924   return ERR_NONE;
    925 }
    926 
    927 /*
    928  * Return a thread's name.
    929  */
    930 static JdwpError TR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
    931     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    932   ObjectId thread_id = request.ReadThreadId();
    933 
    934   std::string name;
    935   JdwpError error = Dbg::GetThreadName(thread_id, name);
    936   if (error != ERR_NONE) {
    937     return error;
    938   }
    939   VLOG(jdwp) << StringPrintf("  Name of thread %#llx is \"%s\"", thread_id, name.c_str());
    940   expandBufAddUtf8String(pReply, name);
    941 
    942   return ERR_NONE;
    943 }
    944 
    945 /*
    946  * Suspend the specified thread.
    947  *
    948  * It's supposed to remain suspended even if interpreted code wants to
    949  * resume it; only the JDI is allowed to resume it.
    950  */
    951 static JdwpError TR_Suspend(JdwpState*, Request& request, ExpandBuf*)
    952     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    953   ObjectId thread_id = request.ReadThreadId();
    954 
    955   if (thread_id == Dbg::GetThreadSelfId()) {
    956     LOG(INFO) << "  Warning: ignoring request to suspend self";
    957     return ERR_THREAD_NOT_SUSPENDED;
    958   }
    959 
    960   Thread* self = Thread::Current();
    961   self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
    962   JdwpError result = Dbg::SuspendThread(thread_id);
    963   self->TransitionFromSuspendedToRunnable();
    964   return result;
    965 }
    966 
    967 /*
    968  * Resume the specified thread.
    969  */
    970 static JdwpError TR_Resume(JdwpState*, Request& request, ExpandBuf*)
    971     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    972   ObjectId thread_id = request.ReadThreadId();
    973 
    974   if (thread_id == Dbg::GetThreadSelfId()) {
    975     LOG(INFO) << "  Warning: ignoring request to resume self";
    976     return ERR_NONE;
    977   }
    978 
    979   Dbg::ResumeThread(thread_id);
    980   return ERR_NONE;
    981 }
    982 
    983 /*
    984  * Return status of specified thread.
    985  */
    986 static JdwpError TR_Status(JdwpState*, Request& request, ExpandBuf* pReply)
    987     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    988   ObjectId thread_id = request.ReadThreadId();
    989 
    990   JDWP::JdwpThreadStatus threadStatus;
    991   JDWP::JdwpSuspendStatus suspendStatus;
    992   JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
    993   if (error != ERR_NONE) {
    994     return error;
    995   }
    996 
    997   VLOG(jdwp) << "    --> " << threadStatus << ", " << suspendStatus;
    998 
    999   expandBufAdd4BE(pReply, threadStatus);
   1000   expandBufAdd4BE(pReply, suspendStatus);
   1001 
   1002   return ERR_NONE;
   1003 }
   1004 
   1005 /*
   1006  * Return the thread group that the specified thread is a member of.
   1007  */
   1008 static JdwpError TR_ThreadGroup(JdwpState*, Request& request, ExpandBuf* pReply)
   1009     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1010   ObjectId thread_id = request.ReadThreadId();
   1011   return Dbg::GetThreadGroup(thread_id, pReply);
   1012 }
   1013 
   1014 /*
   1015  * Return the current call stack of a suspended thread.
   1016  *
   1017  * If the thread isn't suspended, the error code isn't defined, but should
   1018  * be THREAD_NOT_SUSPENDED.
   1019  */
   1020 static JdwpError TR_Frames(JdwpState*, Request& request, ExpandBuf* pReply)
   1021     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1022   ObjectId thread_id = request.ReadThreadId();
   1023   uint32_t start_frame = request.ReadUnsigned32("start frame");
   1024   uint32_t length = request.ReadUnsigned32("length");
   1025 
   1026   size_t actual_frame_count;
   1027   JdwpError error = Dbg::GetThreadFrameCount(thread_id, actual_frame_count);
   1028   if (error != ERR_NONE) {
   1029     return error;
   1030   }
   1031 
   1032   if (actual_frame_count <= 0) {
   1033     return ERR_THREAD_NOT_SUSPENDED;  // 0 means no managed frames (which means "in native").
   1034   }
   1035 
   1036   if (start_frame > actual_frame_count) {
   1037     return ERR_INVALID_INDEX;
   1038   }
   1039   if (length == static_cast<uint32_t>(-1)) {
   1040     length = actual_frame_count - start_frame;
   1041   }
   1042   if (start_frame + length > actual_frame_count) {
   1043     return ERR_INVALID_LENGTH;
   1044   }
   1045 
   1046   return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply);
   1047 }
   1048 
   1049 /*
   1050  * Returns the #of frames on the specified thread, which must be suspended.
   1051  */
   1052 static JdwpError TR_FrameCount(JdwpState*, Request& request, ExpandBuf* pReply)
   1053     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1054   ObjectId thread_id = request.ReadThreadId();
   1055 
   1056   size_t frame_count;
   1057   JdwpError rc = Dbg::GetThreadFrameCount(thread_id, frame_count);
   1058   if (rc != ERR_NONE) {
   1059     return rc;
   1060   }
   1061   expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));
   1062 
   1063   return ERR_NONE;
   1064 }
   1065 
   1066 static JdwpError TR_OwnedMonitors(Request& request, ExpandBuf* reply, bool with_stack_depths)
   1067     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1068   ObjectId thread_id = request.ReadThreadId();
   1069 
   1070   std::vector<ObjectId> monitors;
   1071   std::vector<uint32_t> stack_depths;
   1072   JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors, stack_depths);
   1073   if (rc != ERR_NONE) {
   1074     return rc;
   1075   }
   1076 
   1077   expandBufAdd4BE(reply, monitors.size());
   1078   for (size_t i = 0; i < monitors.size(); ++i) {
   1079     rc = WriteTaggedObject(reply, monitors[i]);
   1080     if (rc != ERR_NONE) {
   1081       return rc;
   1082     }
   1083     if (with_stack_depths) {
   1084       expandBufAdd4BE(reply, stack_depths[i]);
   1085     }
   1086   }
   1087   return ERR_NONE;
   1088 }
   1089 
   1090 static JdwpError TR_OwnedMonitors(JdwpState*, Request& request, ExpandBuf* reply)
   1091     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1092   return TR_OwnedMonitors(request, reply, false);
   1093 }
   1094 
   1095 static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request& request, ExpandBuf* reply)
   1096     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1097   return TR_OwnedMonitors(request, reply, true);
   1098 }
   1099 
   1100 static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request& request, ExpandBuf* reply)
   1101     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1102   ObjectId thread_id = request.ReadThreadId();
   1103 
   1104   ObjectId contended_monitor;
   1105   JdwpError rc = Dbg::GetContendedMonitor(thread_id, contended_monitor);
   1106   if (rc != ERR_NONE) {
   1107     return rc;
   1108   }
   1109   return WriteTaggedObject(reply, contended_monitor);
   1110 }
   1111 
   1112 static JdwpError TR_Interrupt(JdwpState*, Request& request, ExpandBuf* reply)
   1113     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1114   ObjectId thread_id = request.ReadThreadId();
   1115   return Dbg::Interrupt(thread_id);
   1116 }
   1117 
   1118 /*
   1119  * Return the debug suspend count for the specified thread.
   1120  *
   1121  * (The thread *might* still be running -- it might not have examined
   1122  * its suspend count recently.)
   1123  */
   1124 static JdwpError TR_DebugSuspendCount(JdwpState*, Request& request, ExpandBuf* pReply)
   1125     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1126   ObjectId thread_id = request.ReadThreadId();
   1127   return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
   1128 }
   1129 
   1130 /*
   1131  * Return the name of a thread group.
   1132  *
   1133  * The Eclipse debugger recognizes "main" and "system" as special.
   1134  */
   1135 static JdwpError TGR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
   1136     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1137   ObjectId thread_group_id = request.ReadThreadGroupId();
   1138 
   1139   expandBufAddUtf8String(pReply, Dbg::GetThreadGroupName(thread_group_id));
   1140 
   1141   return ERR_NONE;
   1142 }
   1143 
   1144 /*
   1145  * Returns the thread group -- if any -- that contains the specified
   1146  * thread group.
   1147  */
   1148 static JdwpError TGR_Parent(JdwpState*, Request& request, ExpandBuf* pReply)
   1149     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1150   ObjectId thread_group_id = request.ReadThreadGroupId();
   1151 
   1152   ObjectId parentGroup = Dbg::GetThreadGroupParent(thread_group_id);
   1153   expandBufAddObjectId(pReply, parentGroup);
   1154 
   1155   return ERR_NONE;
   1156 }
   1157 
   1158 /*
   1159  * Return the active threads and thread groups that are part of the
   1160  * specified thread group.
   1161  */
   1162 static JdwpError TGR_Children(JdwpState*, Request& request, ExpandBuf* pReply)
   1163     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1164   ObjectId thread_group_id = request.ReadThreadGroupId();
   1165 
   1166   std::vector<ObjectId> thread_ids;
   1167   Dbg::GetThreads(thread_group_id, thread_ids);
   1168   expandBufAdd4BE(pReply, thread_ids.size());
   1169   for (uint32_t i = 0; i < thread_ids.size(); ++i) {
   1170     expandBufAddObjectId(pReply, thread_ids[i]);
   1171   }
   1172 
   1173   std::vector<ObjectId> child_thread_groups_ids;
   1174   Dbg::GetChildThreadGroups(thread_group_id, child_thread_groups_ids);
   1175   expandBufAdd4BE(pReply, child_thread_groups_ids.size());
   1176   for (uint32_t i = 0; i < child_thread_groups_ids.size(); ++i) {
   1177     expandBufAddObjectId(pReply, child_thread_groups_ids[i]);
   1178   }
   1179 
   1180   return ERR_NONE;
   1181 }
   1182 
   1183 /*
   1184  * Return the #of components in the array.
   1185  */
   1186 static JdwpError AR_Length(JdwpState*, Request& request, ExpandBuf* pReply)
   1187     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1188   ObjectId array_id = request.ReadArrayId();
   1189 
   1190   int length;
   1191   JdwpError status = Dbg::GetArrayLength(array_id, length);
   1192   if (status != ERR_NONE) {
   1193     return status;
   1194   }
   1195   VLOG(jdwp) << "    --> " << length;
   1196 
   1197   expandBufAdd4BE(pReply, length);
   1198 
   1199   return ERR_NONE;
   1200 }
   1201 
   1202 /*
   1203  * Return the values from an array.
   1204  */
   1205 static JdwpError AR_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
   1206     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1207   ObjectId array_id = request.ReadArrayId();
   1208   uint32_t offset = request.ReadUnsigned32("offset");
   1209   uint32_t length = request.ReadUnsigned32("length");
   1210   return Dbg::OutputArray(array_id, offset, length, pReply);
   1211 }
   1212 
   1213 /*
   1214  * Set values in an array.
   1215  */
   1216 static JdwpError AR_SetValues(JdwpState*, Request& request, ExpandBuf*)
   1217     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1218   ObjectId array_id = request.ReadArrayId();
   1219   uint32_t offset = request.ReadUnsigned32("offset");
   1220   uint32_t count = request.ReadUnsigned32("count");
   1221   return Dbg::SetArrayElements(array_id, offset, count, request);
   1222 }
   1223 
   1224 static JdwpError CLR_VisibleClasses(JdwpState*, Request& request, ExpandBuf* pReply)
   1225     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1226   request.ReadObjectId();  // classLoaderObject
   1227   // TODO: we should only return classes which have the given class loader as a defining or
   1228   // initiating loader. The former would be easy; the latter is hard, because we don't have
   1229   // any such notion.
   1230   return VM_AllClassesImpl(pReply, false, false);
   1231 }
   1232 
   1233 /*
   1234  * Set an event trigger.
   1235  *
   1236  * Reply with a requestID.
   1237  */
   1238 static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
   1239     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1240   JdwpEventKind event_kind = request.ReadEnum1<JdwpEventKind>("event kind");
   1241   JdwpSuspendPolicy suspend_policy = request.ReadEnum1<JdwpSuspendPolicy>("suspend policy");
   1242   int32_t modifier_count = request.ReadSigned32("modifier count");
   1243 
   1244   CHECK_LT(modifier_count, 256);    /* reasonableness check */
   1245 
   1246   JdwpEvent* pEvent = EventAlloc(modifier_count);
   1247   pEvent->eventKind = event_kind;
   1248   pEvent->suspend_policy = suspend_policy;
   1249   pEvent->modCount = modifier_count;
   1250 
   1251   /*
   1252    * Read modifiers.  Ordering may be significant (see explanation of Count
   1253    * mods in JDWP doc).
   1254    */
   1255   for (int32_t i = 0; i < modifier_count; ++i) {
   1256     JdwpEventMod& mod = pEvent->mods[i];
   1257     mod.modKind = request.ReadModKind();
   1258     switch (mod.modKind) {
   1259     case MK_COUNT:
   1260       {
   1261         // Report once, when "--count" reaches 0.
   1262         uint32_t count = request.ReadUnsigned32("count");
   1263         if (count == 0) {
   1264           return ERR_INVALID_COUNT;
   1265         }
   1266         mod.count.count = count;
   1267       }
   1268       break;
   1269     case MK_CONDITIONAL:
   1270       {
   1271         // Conditional on expression.
   1272         uint32_t exprId = request.ReadUnsigned32("expr id");
   1273         mod.conditional.exprId = exprId;
   1274       }
   1275       break;
   1276     case MK_THREAD_ONLY:
   1277       {
   1278         // Only report events in specified thread.
   1279         ObjectId thread_id = request.ReadThreadId();
   1280         mod.threadOnly.threadId = thread_id;
   1281       }
   1282       break;
   1283     case MK_CLASS_ONLY:
   1284       {
   1285         // For ClassPrepare, MethodEntry.
   1286         RefTypeId class_id = request.ReadRefTypeId();
   1287         mod.classOnly.refTypeId = class_id;
   1288       }
   1289       break;
   1290     case MK_CLASS_MATCH:
   1291       {
   1292         // Restrict events to matching classes.
   1293         // pattern is "java.foo.*", we want "java/foo/*".
   1294         std::string pattern(request.ReadUtf8String());
   1295         std::replace(pattern.begin(), pattern.end(), '.', '/');
   1296         mod.classMatch.classPattern = strdup(pattern.c_str());
   1297       }
   1298       break;
   1299     case MK_CLASS_EXCLUDE:
   1300       {
   1301         // Restrict events to non-matching classes.
   1302         // pattern is "java.foo.*", we want "java/foo/*".
   1303         std::string pattern(request.ReadUtf8String());
   1304         std::replace(pattern.begin(), pattern.end(), '.', '/');
   1305         mod.classExclude.classPattern = strdup(pattern.c_str());
   1306       }
   1307       break;
   1308     case MK_LOCATION_ONLY:
   1309       {
   1310         // Restrict certain events based on location.
   1311         JdwpLocation location = request.ReadLocation();
   1312         mod.locationOnly.loc = location;
   1313       }
   1314       break;
   1315     case MK_EXCEPTION_ONLY:
   1316       {
   1317         // Modifies EK_EXCEPTION events,
   1318         mod.exceptionOnly.refTypeId = request.ReadRefTypeId();  // null => all exceptions.
   1319         mod.exceptionOnly.caught = request.ReadEnum1<uint8_t>("caught");
   1320         mod.exceptionOnly.uncaught = request.ReadEnum1<uint8_t>("uncaught");
   1321       }
   1322       break;
   1323     case MK_FIELD_ONLY:
   1324       {
   1325         // For field access/modification events.
   1326         RefTypeId declaring = request.ReadRefTypeId();
   1327         FieldId fieldId = request.ReadFieldId();
   1328         mod.fieldOnly.refTypeId = declaring;
   1329         mod.fieldOnly.fieldId = fieldId;
   1330       }
   1331       break;
   1332     case MK_STEP:
   1333       {
   1334         // For use with EK_SINGLE_STEP.
   1335         ObjectId thread_id = request.ReadThreadId();
   1336         uint32_t size = request.ReadUnsigned32("step size");
   1337         uint32_t depth = request.ReadUnsigned32("step depth");
   1338         VLOG(jdwp) << StringPrintf("    Step: thread=%#llx", thread_id)
   1339                      << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
   1340 
   1341         mod.step.threadId = thread_id;
   1342         mod.step.size = size;
   1343         mod.step.depth = depth;
   1344       }
   1345       break;
   1346     case MK_INSTANCE_ONLY:
   1347       {
   1348         // Report events related to a specific object.
   1349         ObjectId instance = request.ReadObjectId();
   1350         mod.instanceOnly.objectId = instance;
   1351       }
   1352       break;
   1353     default:
   1354       LOG(WARNING) << "GLITCH: unsupported modKind=" << mod.modKind;
   1355       break;
   1356     }
   1357   }
   1358 
   1359   /*
   1360    * We reply with an integer "requestID".
   1361    */
   1362   uint32_t requestId = state->NextEventSerial();
   1363   expandBufAdd4BE(pReply, requestId);
   1364 
   1365   pEvent->requestId = requestId;
   1366 
   1367   VLOG(jdwp) << StringPrintf("    --> event requestId=%#x", requestId);
   1368 
   1369   /* add it to the list */
   1370   JdwpError err = state->RegisterEvent(pEvent);
   1371   if (err != ERR_NONE) {
   1372     /* registration failed, probably because event is bogus */
   1373     EventFree(pEvent);
   1374     LOG(WARNING) << "WARNING: event request rejected";
   1375   }
   1376   return err;
   1377 }
   1378 
   1379 static JdwpError ER_Clear(JdwpState* state, Request& request, ExpandBuf*)
   1380     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1381   request.ReadEnum1<JdwpEventKind>("event kind");
   1382   uint32_t requestId = request.ReadUnsigned32("request id");
   1383 
   1384   // Failure to find an event with a matching ID is a no-op
   1385   // and does not return an error.
   1386   state->UnregisterEventById(requestId);
   1387   return ERR_NONE;
   1388 }
   1389 
   1390 /*
   1391  * Return the values of arguments and local variables.
   1392  */
   1393 static JdwpError SF_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
   1394     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1395   ObjectId thread_id = request.ReadThreadId();
   1396   FrameId frame_id = request.ReadFrameId();
   1397   int32_t slot_count = request.ReadSigned32("slot count");
   1398 
   1399   expandBufAdd4BE(pReply, slot_count);     /* "int values" */
   1400   for (int32_t i = 0; i < slot_count; ++i) {
   1401     uint32_t slot = request.ReadUnsigned32("slot");
   1402     JDWP::JdwpTag reqSigByte = request.ReadTag();
   1403 
   1404     VLOG(jdwp) << "    --> slot " << slot << " " << reqSigByte;
   1405 
   1406     size_t width = Dbg::GetTagWidth(reqSigByte);
   1407     uint8_t* ptr = expandBufAddSpace(pReply, width+1);
   1408     Dbg::GetLocalValue(thread_id, frame_id, slot, reqSigByte, ptr, width);
   1409   }
   1410 
   1411   return ERR_NONE;
   1412 }
   1413 
   1414 /*
   1415  * Set the values of arguments and local variables.
   1416  */
   1417 static JdwpError SF_SetValues(JdwpState*, Request& request, ExpandBuf*)
   1418     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1419   ObjectId thread_id = request.ReadThreadId();
   1420   FrameId frame_id = request.ReadFrameId();
   1421   int32_t slot_count = request.ReadSigned32("slot count");
   1422 
   1423   for (int32_t i = 0; i < slot_count; ++i) {
   1424     uint32_t slot = request.ReadUnsigned32("slot");
   1425     JDWP::JdwpTag sigByte = request.ReadTag();
   1426     size_t width = Dbg::GetTagWidth(sigByte);
   1427     uint64_t value = request.ReadValue(width);
   1428 
   1429     VLOG(jdwp) << "    --> slot " << slot << " " << sigByte << " " << value;
   1430     Dbg::SetLocalValue(thread_id, frame_id, slot, sigByte, value, width);
   1431   }
   1432 
   1433   return ERR_NONE;
   1434 }
   1435 
   1436 static JdwpError SF_ThisObject(JdwpState*, Request& request, ExpandBuf* reply)
   1437     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1438   ObjectId thread_id = request.ReadThreadId();
   1439   FrameId frame_id = request.ReadFrameId();
   1440 
   1441   ObjectId object_id;
   1442   JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
   1443   if (rc != ERR_NONE) {
   1444     return rc;
   1445   }
   1446 
   1447   return WriteTaggedObject(reply, object_id);
   1448 }
   1449 
   1450 /*
   1451  * Return the reference type reflected by this class object.
   1452  *
   1453  * This appears to be required because ReferenceTypeId values are NEVER
   1454  * reused, whereas ClassIds can be recycled like any other object.  (Either
   1455  * that, or I have no idea what this is for.)
   1456  */
   1457 static JdwpError COR_ReflectedType(JdwpState*, Request& request, ExpandBuf* pReply)
   1458     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1459   RefTypeId class_object_id = request.ReadRefTypeId();
   1460   return Dbg::GetReflectedType(class_object_id, pReply);
   1461 }
   1462 
   1463 /*
   1464  * Handle a DDM packet with a single chunk in it.
   1465  */
   1466 static JdwpError DDM_Chunk(JdwpState* state, Request& request, ExpandBuf* pReply)
   1467     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1468   state->NotifyDdmsActive();
   1469   uint8_t* replyBuf = NULL;
   1470   int replyLen = -1;
   1471   if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) {
   1472     // If they want to send something back, we copy it into the buffer.
   1473     // TODO: consider altering the JDWP stuff to hold the packet header
   1474     // in a separate buffer.  That would allow us to writev() DDM traffic
   1475     // instead of copying it into the expanding buffer.  The reduction in
   1476     // heap requirements is probably more valuable than the efficiency.
   1477     CHECK_GT(replyLen, 0);
   1478     memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
   1479     free(replyBuf);
   1480   }
   1481   return ERR_NONE;
   1482 }
   1483 
   1484 /*
   1485  * Handler map decl.
   1486  */
   1487 typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request& request, ExpandBuf* reply);
   1488 
   1489 struct JdwpHandlerMap {
   1490   uint8_t cmdSet;
   1491   uint8_t cmd;
   1492   JdwpRequestHandler func;
   1493   const char* name;
   1494 };
   1495 
   1496 /*
   1497  * Map commands to functions.
   1498  *
   1499  * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
   1500  * and 128-256 are vendor-defined.
   1501  */
   1502 static const JdwpHandlerMap gHandlers[] = {
   1503   /* VirtualMachine command set (1) */
   1504   { 1,    1,  VM_Version,               "VirtualMachine.Version" },
   1505   { 1,    2,  VM_ClassesBySignature,    "VirtualMachine.ClassesBySignature" },
   1506   { 1,    3,  VM_AllClasses,            "VirtualMachine.AllClasses" },
   1507   { 1,    4,  VM_AllThreads,            "VirtualMachine.AllThreads" },
   1508   { 1,    5,  VM_TopLevelThreadGroups,  "VirtualMachine.TopLevelThreadGroups" },
   1509   { 1,    6,  VM_Dispose,               "VirtualMachine.Dispose" },
   1510   { 1,    7,  VM_IDSizes,               "VirtualMachine.IDSizes" },
   1511   { 1,    8,  VM_Suspend,               "VirtualMachine.Suspend" },
   1512   { 1,    9,  VM_Resume,                "VirtualMachine.Resume" },
   1513   { 1,    10, VM_Exit,                  "VirtualMachine.Exit" },
   1514   { 1,    11, VM_CreateString,          "VirtualMachine.CreateString" },
   1515   { 1,    12, VM_Capabilities,          "VirtualMachine.Capabilities" },
   1516   { 1,    13, VM_ClassPaths,            "VirtualMachine.ClassPaths" },
   1517   { 1,    14, VM_DisposeObjects,        "VirtualMachine.DisposeObjects" },
   1518   { 1,    15, NULL,                     "VirtualMachine.HoldEvents" },
   1519   { 1,    16, NULL,                     "VirtualMachine.ReleaseEvents" },
   1520   { 1,    17, VM_CapabilitiesNew,       "VirtualMachine.CapabilitiesNew" },
   1521   { 1,    18, NULL,                     "VirtualMachine.RedefineClasses" },
   1522   { 1,    19, NULL,                     "VirtualMachine.SetDefaultStratum" },
   1523   { 1,    20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
   1524   { 1,    21, VM_InstanceCounts,        "VirtualMachine.InstanceCounts" },
   1525 
   1526   /* ReferenceType command set (2) */
   1527   { 2,    1,  RT_Signature,            "ReferenceType.Signature" },
   1528   { 2,    2,  RT_ClassLoader,          "ReferenceType.ClassLoader" },
   1529   { 2,    3,  RT_Modifiers,            "ReferenceType.Modifiers" },
   1530   { 2,    4,  RT_Fields,               "ReferenceType.Fields" },
   1531   { 2,    5,  RT_Methods,              "ReferenceType.Methods" },
   1532   { 2,    6,  RT_GetValues,            "ReferenceType.GetValues" },
   1533   { 2,    7,  RT_SourceFile,           "ReferenceType.SourceFile" },
   1534   { 2,    8,  NULL,                    "ReferenceType.NestedTypes" },
   1535   { 2,    9,  RT_Status,               "ReferenceType.Status" },
   1536   { 2,    10, RT_Interfaces,           "ReferenceType.Interfaces" },
   1537   { 2,    11, RT_ClassObject,          "ReferenceType.ClassObject" },
   1538   { 2,    12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
   1539   { 2,    13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
   1540   { 2,    14, RT_FieldsWithGeneric,    "ReferenceType.FieldsWithGeneric" },
   1541   { 2,    15, RT_MethodsWithGeneric,   "ReferenceType.MethodsWithGeneric" },
   1542   { 2,    16, RT_Instances,            "ReferenceType.Instances" },
   1543   { 2,    17, NULL,                    "ReferenceType.ClassFileVersion" },
   1544   { 2,    18, NULL,                    "ReferenceType.ConstantPool" },
   1545 
   1546   /* ClassType command set (3) */
   1547   { 3,    1,  CT_Superclass,    "ClassType.Superclass" },
   1548   { 3,    2,  CT_SetValues,     "ClassType.SetValues" },
   1549   { 3,    3,  CT_InvokeMethod,  "ClassType.InvokeMethod" },
   1550   { 3,    4,  CT_NewInstance,   "ClassType.NewInstance" },
   1551 
   1552   /* ArrayType command set (4) */
   1553   { 4,    1,  AT_newInstance,   "ArrayType.NewInstance" },
   1554 
   1555   /* InterfaceType command set (5) */
   1556 
   1557   /* Method command set (6) */
   1558   { 6,    1,  M_LineTable,                "Method.LineTable" },
   1559   { 6,    2,  M_VariableTable,            "Method.VariableTable" },
   1560   { 6,    3,  M_Bytecodes,                "Method.Bytecodes" },
   1561   { 6,    4,  NULL,                       "Method.IsObsolete" },
   1562   { 6,    5,  M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
   1563 
   1564   /* Field command set (8) */
   1565 
   1566   /* ObjectReference command set (9) */
   1567   { 9,    1,  OR_ReferenceType,     "ObjectReference.ReferenceType" },
   1568   { 9,    2,  OR_GetValues,         "ObjectReference.GetValues" },
   1569   { 9,    3,  OR_SetValues,         "ObjectReference.SetValues" },
   1570   { 9,    4,  NULL,                 "ObjectReference.UNUSED" },
   1571   { 9,    5,  OR_MonitorInfo,       "ObjectReference.MonitorInfo" },
   1572   { 9,    6,  OR_InvokeMethod,      "ObjectReference.InvokeMethod" },
   1573   { 9,    7,  OR_DisableCollection, "ObjectReference.DisableCollection" },
   1574   { 9,    8,  OR_EnableCollection,  "ObjectReference.EnableCollection" },
   1575   { 9,    9,  OR_IsCollected,       "ObjectReference.IsCollected" },
   1576   { 9,    10, OR_ReferringObjects,  "ObjectReference.ReferringObjects" },
   1577 
   1578   /* StringReference command set (10) */
   1579   { 10,   1,  SR_Value,         "StringReference.Value" },
   1580 
   1581   /* ThreadReference command set (11) */
   1582   { 11,   1,  TR_Name,                        "ThreadReference.Name" },
   1583   { 11,   2,  TR_Suspend,                     "ThreadReference.Suspend" },
   1584   { 11,   3,  TR_Resume,                      "ThreadReference.Resume" },
   1585   { 11,   4,  TR_Status,                      "ThreadReference.Status" },
   1586   { 11,   5,  TR_ThreadGroup,                 "ThreadReference.ThreadGroup" },
   1587   { 11,   6,  TR_Frames,                      "ThreadReference.Frames" },
   1588   { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
   1589   { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
   1590   { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
   1591   { 11,   10, NULL,                           "ThreadReference.Stop" },
   1592   { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
   1593   { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
   1594   { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
   1595   { 11,   14, NULL,                           "ThreadReference.ForceEarlyReturn" },
   1596 
   1597   /* ThreadGroupReference command set (12) */
   1598   { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },
   1599   { 12,   2,  TGR_Parent,       "ThreadGroupReference.Parent" },
   1600   { 12,   3,  TGR_Children,     "ThreadGroupReference.Children" },
   1601 
   1602   /* ArrayReference command set (13) */
   1603   { 13,   1,  AR_Length,        "ArrayReference.Length" },
   1604   { 13,   2,  AR_GetValues,     "ArrayReference.GetValues" },
   1605   { 13,   3,  AR_SetValues,     "ArrayReference.SetValues" },
   1606 
   1607   /* ClassLoaderReference command set (14) */
   1608   { 14,   1,  CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
   1609 
   1610   /* EventRequest command set (15) */
   1611   { 15,   1,  ER_Set,           "EventRequest.Set" },
   1612   { 15,   2,  ER_Clear,         "EventRequest.Clear" },
   1613   { 15,   3,  NULL,             "EventRequest.ClearAllBreakpoints" },
   1614 
   1615   /* StackFrame command set (16) */
   1616   { 16,   1,  SF_GetValues,     "StackFrame.GetValues" },
   1617   { 16,   2,  SF_SetValues,     "StackFrame.SetValues" },
   1618   { 16,   3,  SF_ThisObject,    "StackFrame.ThisObject" },
   1619   { 16,   4,  NULL,             "StackFrame.PopFrames" },
   1620 
   1621   /* ClassObjectReference command set (17) */
   1622   { 17,   1,  COR_ReflectedType, "ClassObjectReference.ReflectedType" },
   1623 
   1624   /* Event command set (64) */
   1625   { 64, 100,  NULL, "Event.Composite" },  // sent from VM to debugger, never received by VM
   1626 
   1627   { 199,  1,  DDM_Chunk,        "DDM.Chunk" },
   1628 };
   1629 
   1630 static const char* GetCommandName(Request& request) {
   1631   for (size_t i = 0; i < arraysize(gHandlers); ++i) {
   1632     if (gHandlers[i].cmdSet == request.GetCommandSet() && gHandlers[i].cmd == request.GetCommand()) {
   1633       return gHandlers[i].name;
   1634     }
   1635   }
   1636   return "?UNKNOWN?";
   1637 }
   1638 
   1639 static std::string DescribeCommand(Request& request) {
   1640   std::string result;
   1641   result += "REQUEST: ";
   1642   result += GetCommandName(request);
   1643   result += StringPrintf(" (length=%d id=0x%06x)", request.GetLength(), request.GetId());
   1644   return result;
   1645 }
   1646 
   1647 /*
   1648  * Process a request from the debugger.
   1649  *
   1650  * On entry, the JDWP thread is in VMWAIT.
   1651  */
   1652 void JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
   1653   JdwpError result = ERR_NONE;
   1654 
   1655   if (request.GetCommandSet() != kJDWPDdmCmdSet) {
   1656     /*
   1657      * Activity from a debugger, not merely ddms.  Mark us as having an
   1658      * active debugger session, and zero out the last-activity timestamp
   1659      * so waitForDebugger() doesn't return if we stall for a bit here.
   1660      */
   1661     Dbg::GoActive();
   1662     QuasiAtomic::Write64(&last_activity_time_ms_, 0);
   1663   }
   1664 
   1665   /*
   1666    * If a debugger event has fired in another thread, wait until the
   1667    * initiating thread has suspended itself before processing messages
   1668    * from the debugger.  Otherwise we (the JDWP thread) could be told to
   1669    * resume the thread before it has suspended.
   1670    *
   1671    * We call with an argument of zero to wait for the current event
   1672    * thread to finish, and then clear the block.  Depending on the thread
   1673    * suspend policy, this may allow events in other threads to fire,
   1674    * but those events have no bearing on what the debugger has sent us
   1675    * in the current request.
   1676    *
   1677    * Note that we MUST clear the event token before waking the event
   1678    * thread up, or risk waiting for the thread to suspend after we've
   1679    * told it to resume.
   1680    */
   1681   SetWaitForEventThread(0);
   1682 
   1683   /*
   1684    * Tell the VM that we're running and shouldn't be interrupted by GC.
   1685    * Do this after anything that can stall indefinitely.
   1686    */
   1687   Thread* self = Thread::Current();
   1688   ThreadState old_state = self->TransitionFromSuspendedToRunnable();
   1689 
   1690   expandBufAddSpace(pReply, kJDWPHeaderLen);
   1691 
   1692   size_t i;
   1693   for (i = 0; i < arraysize(gHandlers); ++i) {
   1694     if (gHandlers[i].cmdSet == request.GetCommandSet() && gHandlers[i].cmd == request.GetCommand() && gHandlers[i].func != NULL) {
   1695       VLOG(jdwp) << DescribeCommand(request);
   1696       result = (*gHandlers[i].func)(this, request, pReply);
   1697       if (result == ERR_NONE) {
   1698         request.CheckConsumed();
   1699       }
   1700       break;
   1701     }
   1702   }
   1703   if (i == arraysize(gHandlers)) {
   1704     LOG(ERROR) << "Command not implemented: " << DescribeCommand(request);
   1705     LOG(ERROR) << HexDump(request.data(), request.size());
   1706     result = ERR_NOT_IMPLEMENTED;
   1707   }
   1708 
   1709   /*
   1710    * Set up the reply header.
   1711    *
   1712    * If we encountered an error, only send the header back.
   1713    */
   1714   uint8_t* replyBuf = expandBufGetBuffer(pReply);
   1715   Set4BE(replyBuf + 4, request.GetId());
   1716   Set1(replyBuf + 8, kJDWPFlagReply);
   1717   Set2BE(replyBuf + 9, result);
   1718   if (result == ERR_NONE) {
   1719     Set4BE(replyBuf + 0, expandBufGetLength(pReply));
   1720   } else {
   1721     Set4BE(replyBuf + 0, kJDWPHeaderLen);
   1722   }
   1723 
   1724   CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request.GetId();
   1725 
   1726   size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
   1727   VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")";
   1728   if (false) {
   1729     VLOG(jdwp) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
   1730   }
   1731 
   1732   VLOG(jdwp) << "----------";
   1733 
   1734   /*
   1735    * Update last-activity timestamp.  We really only need this during
   1736    * the initial setup.  Only update if this is a non-DDMS packet.
   1737    */
   1738   if (request.GetCommandSet() != kJDWPDdmCmdSet) {
   1739     QuasiAtomic::Write64(&last_activity_time_ms_, MilliTime());
   1740   }
   1741 
   1742   /* tell the VM that GC is okay again */
   1743   self->TransitionFromRunnableToSuspended(old_state);
   1744 }
   1745 
   1746 }  // namespace JDWP
   1747 
   1748 }  // namespace art
   1749