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