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