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 "thread-inl.h"
     35 #include "utils.h"
     36 
     37 namespace art {
     38 
     39 namespace JDWP {
     40 
     41 std::string DescribeField(const FieldId& field_id) {
     42   return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
     43 }
     44 
     45 std::string DescribeMethod(const MethodId& method_id) {
     46   return StringPrintf("%#" PRIx64 " (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
     47 }
     48 
     49 std::string DescribeRefTypeId(const RefTypeId& ref_type_id) {
     50   std::string signature("unknown");
     51   Dbg::GetSignature(ref_type_id, &signature);
     52   return StringPrintf("%#" PRIx64 " (%s)", ref_type_id, signature.c_str());
     53 }
     54 
     55 static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
     56     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     57   uint8_t tag;
     58   JdwpError rc = Dbg::GetObjectTag(object_id, &tag);
     59   if (rc == ERR_NONE) {
     60     expandBufAdd1(reply, tag);
     61     expandBufAddObjectId(reply, object_id);
     62   }
     63   return rc;
     64 }
     65 
     66 static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<ObjectId>& objects)
     67     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     68   expandBufAdd4BE(reply, objects.size());
     69   for (size_t i = 0; i < objects.size(); ++i) {
     70     JdwpError rc = WriteTaggedObject(reply, objects[i]);
     71     if (rc != ERR_NONE) {
     72       return rc;
     73     }
     74   }
     75   return ERR_NONE;
     76 }
     77 
     78 /*
     79  * Common code for *_InvokeMethod requests.
     80  *
     81  * If "is_constructor" is set, this returns "object_id" rather than the
     82  * expected-to-be-void return value of the called function.
     83  */
     84 static JdwpError RequestInvoke(JdwpState*, Request* request,
     85                                ObjectId thread_id, ObjectId object_id,
     86                                RefTypeId class_id, MethodId method_id, bool is_constructor)
     87     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     88   CHECK(!is_constructor || object_id != 0);
     89 
     90   int32_t arg_count = request->ReadSigned32("argument count");
     91 
     92   VLOG(jdwp) << StringPrintf("    --> thread_id=%#" PRIx64 " object_id=%#" PRIx64,
     93                              thread_id, object_id);
     94   VLOG(jdwp) << StringPrintf("        class_id=%#" PRIx64 " method_id=%#" PRIx64 " %s.%s",
     95                              class_id, method_id, Dbg::GetClassName(class_id).c_str(),
     96                              Dbg::GetMethodName(method_id).c_str());
     97   VLOG(jdwp) << StringPrintf("        %d args:", arg_count);
     98 
     99   std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : nullptr);
    100   std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : nullptr);
    101   for (int32_t i = 0; i < arg_count; ++i) {
    102     argTypes[i] = request->ReadTag();
    103     size_t width = Dbg::GetTagWidth(argTypes[i]);
    104     argValues[i] = request->ReadValue(width);
    105     VLOG(jdwp) << "          " << argTypes[i] << StringPrintf("(%zd): %#" PRIx64, width,
    106                                                               argValues[i]);
    107   }
    108 
    109   uint32_t options = request->ReadUnsigned32("InvokeOptions bit flags");
    110   VLOG(jdwp) << StringPrintf("        options=0x%04x%s%s", options,
    111                              (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
    112                              (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
    113 
    114   JDWP::JdwpError error =  Dbg::PrepareInvokeMethod(request->GetId(), thread_id, object_id,
    115                                                     class_id, method_id, arg_count,
    116                                                     argValues.get(), argTypes.get(), options);
    117   if (error == JDWP::ERR_NONE) {
    118     // We successfully requested the invoke. The event thread now owns the arguments array in its
    119     // DebugInvokeReq mailbox.
    120     argValues.release();
    121   }
    122   return error;
    123 }
    124 
    125 static JdwpError VM_Version(JdwpState*, Request*, ExpandBuf* pReply)
    126     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    127   // Text information on runtime version.
    128   std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
    129   expandBufAddUtf8String(pReply, version);
    130 
    131   // JDWP version numbers, major and minor.
    132   expandBufAdd4BE(pReply, 1);
    133   expandBufAdd4BE(pReply, 6);
    134 
    135   // "java.version".
    136   expandBufAddUtf8String(pReply, "1.6.0");
    137 
    138   // "java.vm.name".
    139   expandBufAddUtf8String(pReply, "Dalvik");
    140 
    141   return ERR_NONE;
    142 }
    143 
    144 /*
    145  * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
    146  * referenceTypeID.  We need to send back more than one if the class has
    147  * been loaded by multiple class loaders.
    148  */
    149 static JdwpError VM_ClassesBySignature(JdwpState*, Request* request, ExpandBuf* pReply)
    150     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    151   std::string classDescriptor(request->ReadUtf8String());
    152 
    153   std::vector<RefTypeId> ids;
    154   Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), &ids);
    155 
    156   expandBufAdd4BE(pReply, ids.size());
    157 
    158   for (size_t i = 0; i < ids.size(); ++i) {
    159     // Get class vs. interface and status flags.
    160     JDWP::JdwpTypeTag type_tag;
    161     uint32_t class_status;
    162     JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, nullptr);
    163     if (status != ERR_NONE) {
    164       return status;
    165     }
    166 
    167     expandBufAdd1(pReply, type_tag);
    168     expandBufAddRefTypeId(pReply, ids[i]);
    169     expandBufAdd4BE(pReply, class_status);
    170   }
    171 
    172   return ERR_NONE;
    173 }
    174 
    175 /*
    176  * Handle request for the thread IDs of all running threads.
    177  *
    178  * We exclude ourselves from the list, because we don't allow ourselves
    179  * to be suspended, and that violates some JDWP expectations.
    180  */
    181 static JdwpError VM_AllThreads(JdwpState*, Request*, ExpandBuf* pReply)
    182     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    183   std::vector<ObjectId> thread_ids;
    184   Dbg::GetThreads(nullptr /* all thread groups */, &thread_ids);
    185 
    186   expandBufAdd4BE(pReply, thread_ids.size());
    187   for (uint32_t i = 0; i < thread_ids.size(); ++i) {
    188     expandBufAddObjectId(pReply, thread_ids[i]);
    189   }
    190 
    191   return ERR_NONE;
    192 }
    193 
    194 /*
    195  * List all thread groups that do not have a parent.
    196  */
    197 static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request*, ExpandBuf* pReply)
    198     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    199   /*
    200    * TODO: maintain a list of parentless thread groups in the VM.
    201    *
    202    * For now, just return "system".  Application threads are created
    203    * in "main", which is a child of "system".
    204    */
    205   uint32_t groups = 1;
    206   expandBufAdd4BE(pReply, groups);
    207   ObjectId thread_group_id = Dbg::GetSystemThreadGroupId();
    208   expandBufAddObjectId(pReply, thread_group_id);
    209 
    210   return ERR_NONE;
    211 }
    212 
    213 /*
    214  * Respond with the sizes of the basic debugger types.
    215  */
    216 static JdwpError VM_IDSizes(JdwpState*, Request*, ExpandBuf* pReply)
    217     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    218   expandBufAdd4BE(pReply, sizeof(FieldId));
    219   expandBufAdd4BE(pReply, sizeof(MethodId));
    220   expandBufAdd4BE(pReply, sizeof(ObjectId));
    221   expandBufAdd4BE(pReply, sizeof(RefTypeId));
    222   expandBufAdd4BE(pReply, sizeof(FrameId));
    223   return ERR_NONE;
    224 }
    225 
    226 static JdwpError VM_Dispose(JdwpState*, Request*, ExpandBuf*)
    227     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    228   Dbg::Dispose();
    229   return ERR_NONE;
    230 }
    231 
    232 /*
    233  * Suspend the execution of the application running in the VM (i.e. suspend
    234  * all threads).
    235  *
    236  * This needs to increment the "suspend count" on all threads.
    237  */
    238 static JdwpError VM_Suspend(JdwpState*, Request*, ExpandBuf*)
    239     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    240   Thread* self = Thread::Current();
    241   self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
    242   Dbg::SuspendVM();
    243   self->TransitionFromSuspendedToRunnable();
    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_LOCKS_REQUIRED(Locks::mutator_lock_) {
    252   Dbg::ResumeVM();
    253   return ERR_NONE;
    254 }
    255 
    256 static JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*)
    257     SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_) {
    385   return VM_AllClassesImpl(pReply, true, false);
    386 }
    387 
    388 static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply)
    389     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    390   return VM_AllClassesImpl(pReply, true, true);
    391 }
    392 
    393 static JdwpError VM_InstanceCounts(JdwpState*, Request* request, ExpandBuf* pReply)
    394     SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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  * Return line number information for the method, if present.
    694  */
    695 static JdwpError M_LineTable(JdwpState*, Request* request, ExpandBuf* pReply)
    696     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    697   RefTypeId refTypeId = request->ReadRefTypeId();
    698   MethodId method_id = request->ReadMethodId();
    699 
    700   Dbg::OutputLineTable(refTypeId, method_id, pReply);
    701 
    702   return ERR_NONE;
    703 }
    704 
    705 static JdwpError M_VariableTable(JdwpState*, Request* request, ExpandBuf* pReply,
    706                                  bool generic)
    707     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    708   RefTypeId class_id = request->ReadRefTypeId();
    709   MethodId method_id = request->ReadMethodId();
    710 
    711   // We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
    712   // information. That will cause Eclipse to make a best-effort attempt at displaying local
    713   // variables anonymously. However, the attempt isn't very good, so we're probably better off just
    714   // not showing anything.
    715   Dbg::OutputVariableTable(class_id, method_id, generic, pReply);
    716   return ERR_NONE;
    717 }
    718 
    719 static JdwpError M_VariableTable(JdwpState* state, Request* request, ExpandBuf* pReply)
    720     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    721   return M_VariableTable(state, request, pReply, false);
    722 }
    723 
    724 static JdwpError M_VariableTableWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
    725     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    726   return M_VariableTable(state, request, pReply, true);
    727 }
    728 
    729 static JdwpError M_Bytecodes(JdwpState*, Request* request, ExpandBuf* reply)
    730     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    731   RefTypeId class_id = request->ReadRefTypeId();
    732   MethodId method_id = request->ReadMethodId();
    733 
    734   std::vector<uint8_t> bytecodes;
    735   JdwpError rc = Dbg::GetBytecodes(class_id, method_id, &bytecodes);
    736   if (rc != ERR_NONE) {
    737     return rc;
    738   }
    739 
    740   expandBufAdd4BE(reply, bytecodes.size());
    741   for (size_t i = 0; i < bytecodes.size(); ++i) {
    742     expandBufAdd1(reply, bytecodes[i]);
    743   }
    744 
    745   return ERR_NONE;
    746 }
    747 
    748 /*
    749  * Given an object reference, return the runtime type of the object
    750  * (class or array).
    751  *
    752  * This can get called on different things, e.g. thread_id gets
    753  * passed in here.
    754  */
    755 static JdwpError OR_ReferenceType(JdwpState*, Request* request, ExpandBuf* pReply)
    756     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    757   ObjectId object_id = request->ReadObjectId();
    758   return Dbg::GetReferenceType(object_id, pReply);
    759 }
    760 
    761 /*
    762  * Get values from the fields of an object.
    763  */
    764 static JdwpError OR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
    765     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    766   ObjectId object_id = request->ReadObjectId();
    767   int32_t field_count = request->ReadSigned32("field count");
    768 
    769   expandBufAdd4BE(pReply, field_count);
    770   for (int32_t i = 0; i < field_count; ++i) {
    771     FieldId fieldId = request->ReadFieldId();
    772     JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
    773     if (status != ERR_NONE) {
    774       return status;
    775     }
    776   }
    777 
    778   return ERR_NONE;
    779 }
    780 
    781 /*
    782  * Set values in the fields of an object.
    783  */
    784 static JdwpError OR_SetValues(JdwpState*, Request* request, ExpandBuf*)
    785     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    786   ObjectId object_id = request->ReadObjectId();
    787   int32_t field_count = request->ReadSigned32("field count");
    788 
    789   for (int32_t i = 0; i < field_count; ++i) {
    790     FieldId fieldId = request->ReadFieldId();
    791 
    792     JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
    793     size_t width = Dbg::GetTagWidth(fieldTag);
    794     uint64_t value = request->ReadValue(width);
    795 
    796     VLOG(jdwp) << "    --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
    797     JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
    798     if (status != ERR_NONE) {
    799       return status;
    800     }
    801   }
    802 
    803   return ERR_NONE;
    804 }
    805 
    806 static JdwpError OR_MonitorInfo(JdwpState*, Request* request, ExpandBuf* reply)
    807     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    808   ObjectId object_id = request->ReadObjectId();
    809   return Dbg::GetMonitorInfo(object_id, reply);
    810 }
    811 
    812 /*
    813  * Invoke an instance method.  The invocation must occur in the specified
    814  * thread, which must have been suspended by an event.
    815  *
    816  * The call is synchronous.  All threads in the VM are resumed, unless the
    817  * SINGLE_THREADED flag is set.
    818  *
    819  * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
    820  * object), it will try to invoke the object's toString() function.  This
    821  * feature becomes crucial when examining ArrayLists with Eclipse.
    822  */
    823 static JdwpError OR_InvokeMethod(JdwpState* state, Request* request,
    824                                  ExpandBuf* pReply ATTRIBUTE_UNUSED)
    825     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    826   ObjectId object_id = request->ReadObjectId();
    827   ObjectId thread_id = request->ReadThreadId();
    828   RefTypeId class_id = request->ReadRefTypeId();
    829   MethodId method_id = request->ReadMethodId();
    830 
    831   return RequestInvoke(state, request, thread_id, object_id, class_id, method_id, false);
    832 }
    833 
    834 static JdwpError OR_DisableCollection(JdwpState*, Request* request, ExpandBuf*)
    835     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    836   ObjectId object_id = request->ReadObjectId();
    837   return Dbg::DisableCollection(object_id);
    838 }
    839 
    840 static JdwpError OR_EnableCollection(JdwpState*, Request* request, ExpandBuf*)
    841     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    842   ObjectId object_id = request->ReadObjectId();
    843   return Dbg::EnableCollection(object_id);
    844 }
    845 
    846 static JdwpError OR_IsCollected(JdwpState*, Request* request, ExpandBuf* pReply)
    847     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    848   ObjectId object_id = request->ReadObjectId();
    849   bool is_collected;
    850   JdwpError rc = Dbg::IsCollected(object_id, &is_collected);
    851   expandBufAdd1(pReply, is_collected ? 1 : 0);
    852   return rc;
    853 }
    854 
    855 static JdwpError OR_ReferringObjects(JdwpState*, Request* request, ExpandBuf* reply)
    856     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    857   ObjectId object_id = request->ReadObjectId();
    858   int32_t max_count = request->ReadSigned32("max count");
    859   if (max_count < 0) {
    860     return ERR_ILLEGAL_ARGUMENT;
    861   }
    862 
    863   std::vector<ObjectId> referring_objects;
    864   JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, &referring_objects);
    865   if (rc != ERR_NONE) {
    866     return rc;
    867   }
    868 
    869   return WriteTaggedObjectList(reply, referring_objects);
    870 }
    871 
    872 /*
    873  * Return the string value in a string object.
    874  */
    875 static JdwpError SR_Value(JdwpState*, Request* request, ExpandBuf* pReply)
    876     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    877   ObjectId stringObject = request->ReadObjectId();
    878   std::string str;
    879   JDWP::JdwpError error = Dbg::StringToUtf8(stringObject, &str);
    880   if (error != JDWP::ERR_NONE) {
    881     return error;
    882   }
    883 
    884   VLOG(jdwp) << StringPrintf("    --> %s", PrintableString(str.c_str()).c_str());
    885 
    886   expandBufAddUtf8String(pReply, str);
    887 
    888   return ERR_NONE;
    889 }
    890 
    891 /*
    892  * Return a thread's name.
    893  */
    894 static JdwpError TR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
    895     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    896   ObjectId thread_id = request->ReadThreadId();
    897 
    898   std::string name;
    899   JdwpError error = Dbg::GetThreadName(thread_id, &name);
    900   if (error != ERR_NONE) {
    901     return error;
    902   }
    903   VLOG(jdwp) << StringPrintf("  Name of thread %#" PRIx64 " is \"%s\"", thread_id, name.c_str());
    904   expandBufAddUtf8String(pReply, name);
    905 
    906   return ERR_NONE;
    907 }
    908 
    909 /*
    910  * Suspend the specified thread.
    911  *
    912  * It's supposed to remain suspended even if interpreted code wants to
    913  * resume it; only the JDI is allowed to resume it.
    914  */
    915 static JdwpError TR_Suspend(JdwpState*, Request* request, ExpandBuf*)
    916     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    917   ObjectId thread_id = request->ReadThreadId();
    918 
    919   if (thread_id == Dbg::GetThreadSelfId()) {
    920     LOG(INFO) << "  Warning: ignoring request to suspend self";
    921     return ERR_THREAD_NOT_SUSPENDED;
    922   }
    923 
    924   Thread* self = Thread::Current();
    925   self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
    926   JdwpError result = Dbg::SuspendThread(thread_id);
    927   self->TransitionFromSuspendedToRunnable();
    928   return result;
    929 }
    930 
    931 /*
    932  * Resume the specified thread.
    933  */
    934 static JdwpError TR_Resume(JdwpState*, Request* request, ExpandBuf*)
    935     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    936   ObjectId thread_id = request->ReadThreadId();
    937 
    938   if (thread_id == Dbg::GetThreadSelfId()) {
    939     LOG(INFO) << "  Warning: ignoring request to resume self";
    940     return ERR_NONE;
    941   }
    942 
    943   Dbg::ResumeThread(thread_id);
    944   return ERR_NONE;
    945 }
    946 
    947 /*
    948  * Return status of specified thread.
    949  */
    950 static JdwpError TR_Status(JdwpState*, Request* request, ExpandBuf* pReply)
    951     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    952   ObjectId thread_id = request->ReadThreadId();
    953 
    954   JDWP::JdwpThreadStatus threadStatus;
    955   JDWP::JdwpSuspendStatus suspendStatus;
    956   JdwpError error = Dbg::GetThreadStatus(thread_id, &threadStatus, &suspendStatus);
    957   if (error != ERR_NONE) {
    958     return error;
    959   }
    960 
    961   VLOG(jdwp) << "    --> " << threadStatus << ", " << suspendStatus;
    962 
    963   expandBufAdd4BE(pReply, threadStatus);
    964   expandBufAdd4BE(pReply, suspendStatus);
    965 
    966   return ERR_NONE;
    967 }
    968 
    969 /*
    970  * Return the thread group that the specified thread is a member of.
    971  */
    972 static JdwpError TR_ThreadGroup(JdwpState*, Request* request, ExpandBuf* pReply)
    973     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    974   ObjectId thread_id = request->ReadThreadId();
    975   return Dbg::GetThreadGroup(thread_id, pReply);
    976 }
    977 
    978 /*
    979  * Return the current call stack of a suspended thread.
    980  *
    981  * If the thread isn't suspended, the error code isn't defined, but should
    982  * be THREAD_NOT_SUSPENDED.
    983  */
    984 static JdwpError TR_Frames(JdwpState*, Request* request, ExpandBuf* pReply)
    985     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    986   ObjectId thread_id = request->ReadThreadId();
    987   uint32_t start_frame = request->ReadUnsigned32("start frame");
    988   uint32_t length = request->ReadUnsigned32("length");
    989 
    990   size_t actual_frame_count;
    991   JdwpError error = Dbg::GetThreadFrameCount(thread_id, &actual_frame_count);
    992   if (error != ERR_NONE) {
    993     return error;
    994   }
    995 
    996   if (actual_frame_count <= 0) {
    997     return ERR_THREAD_NOT_SUSPENDED;  // 0 means no managed frames (which means "in native").
    998   }
    999 
   1000   if (start_frame > actual_frame_count) {
   1001     return ERR_INVALID_INDEX;
   1002   }
   1003   if (length == static_cast<uint32_t>(-1)) {
   1004     length = actual_frame_count - start_frame;
   1005   }
   1006   if (start_frame + length > actual_frame_count) {
   1007     return ERR_INVALID_LENGTH;
   1008   }
   1009 
   1010   return Dbg::GetThreadFrames(thread_id, start_frame, length, pReply);
   1011 }
   1012 
   1013 /*
   1014  * Returns the #of frames on the specified thread, which must be suspended.
   1015  */
   1016 static JdwpError TR_FrameCount(JdwpState*, Request* request, ExpandBuf* pReply)
   1017     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1018   ObjectId thread_id = request->ReadThreadId();
   1019 
   1020   size_t frame_count;
   1021   JdwpError rc = Dbg::GetThreadFrameCount(thread_id, &frame_count);
   1022   if (rc != ERR_NONE) {
   1023     return rc;
   1024   }
   1025   expandBufAdd4BE(pReply, static_cast<uint32_t>(frame_count));
   1026 
   1027   return ERR_NONE;
   1028 }
   1029 
   1030 static JdwpError TR_OwnedMonitors(Request* request, ExpandBuf* reply, bool with_stack_depths)
   1031     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1032   ObjectId thread_id = request->ReadThreadId();
   1033 
   1034   std::vector<ObjectId> monitors;
   1035   std::vector<uint32_t> stack_depths;
   1036   JdwpError rc = Dbg::GetOwnedMonitors(thread_id, &monitors, &stack_depths);
   1037   if (rc != ERR_NONE) {
   1038     return rc;
   1039   }
   1040 
   1041   expandBufAdd4BE(reply, monitors.size());
   1042   for (size_t i = 0; i < monitors.size(); ++i) {
   1043     rc = WriteTaggedObject(reply, monitors[i]);
   1044     if (rc != ERR_NONE) {
   1045       return rc;
   1046     }
   1047     if (with_stack_depths) {
   1048       expandBufAdd4BE(reply, stack_depths[i]);
   1049     }
   1050   }
   1051   return ERR_NONE;
   1052 }
   1053 
   1054 static JdwpError TR_OwnedMonitors(JdwpState*, Request* request, ExpandBuf* reply)
   1055     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1056   return TR_OwnedMonitors(request, reply, false);
   1057 }
   1058 
   1059 static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request* request, ExpandBuf* reply)
   1060     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1061   return TR_OwnedMonitors(request, reply, true);
   1062 }
   1063 
   1064 static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request* request, ExpandBuf* reply)
   1065     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1066   ObjectId thread_id = request->ReadThreadId();
   1067 
   1068   ObjectId contended_monitor;
   1069   JdwpError rc = Dbg::GetContendedMonitor(thread_id, &contended_monitor);
   1070   if (rc != ERR_NONE) {
   1071     return rc;
   1072   }
   1073   return WriteTaggedObject(reply, contended_monitor);
   1074 }
   1075 
   1076 static JdwpError TR_Interrupt(JdwpState*, Request* request, ExpandBuf* reply)
   1077     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1078   UNUSED(reply);
   1079   ObjectId thread_id = request->ReadThreadId();
   1080   return Dbg::Interrupt(thread_id);
   1081 }
   1082 
   1083 /*
   1084  * Return the debug suspend count for the specified thread.
   1085  *
   1086  * (The thread *might* still be running -- it might not have examined
   1087  * its suspend count recently.)
   1088  */
   1089 static JdwpError TR_DebugSuspendCount(JdwpState*, Request* request, ExpandBuf* pReply)
   1090     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1091   ObjectId thread_id = request->ReadThreadId();
   1092   return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
   1093 }
   1094 
   1095 /*
   1096  * Return the name of a thread group.
   1097  *
   1098  * The Eclipse debugger recognizes "main" and "system" as special.
   1099  */
   1100 static JdwpError TGR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
   1101     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1102   ObjectId thread_group_id = request->ReadThreadGroupId();
   1103   return Dbg::GetThreadGroupName(thread_group_id, pReply);
   1104 }
   1105 
   1106 /*
   1107  * Returns the thread group -- if any -- that contains the specified
   1108  * thread group.
   1109  */
   1110 static JdwpError TGR_Parent(JdwpState*, Request* request, ExpandBuf* pReply)
   1111     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1112   ObjectId thread_group_id = request->ReadThreadGroupId();
   1113   return Dbg::GetThreadGroupParent(thread_group_id, pReply);
   1114 }
   1115 
   1116 /*
   1117  * Return the active threads and thread groups that are part of the
   1118  * specified thread group.
   1119  */
   1120 static JdwpError TGR_Children(JdwpState*, Request* request, ExpandBuf* pReply)
   1121     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1122   ObjectId thread_group_id = request->ReadThreadGroupId();
   1123   return Dbg::GetThreadGroupChildren(thread_group_id, pReply);
   1124 }
   1125 
   1126 /*
   1127  * Return the #of components in the array.
   1128  */
   1129 static JdwpError AR_Length(JdwpState*, Request* request, ExpandBuf* pReply)
   1130     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1131   ObjectId array_id = request->ReadArrayId();
   1132 
   1133   int32_t length;
   1134   JdwpError status = Dbg::GetArrayLength(array_id, &length);
   1135   if (status != ERR_NONE) {
   1136     return status;
   1137   }
   1138   VLOG(jdwp) << "    --> " << length;
   1139 
   1140   expandBufAdd4BE(pReply, length);
   1141 
   1142   return ERR_NONE;
   1143 }
   1144 
   1145 /*
   1146  * Return the values from an array.
   1147  */
   1148 static JdwpError AR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
   1149     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1150   ObjectId array_id = request->ReadArrayId();
   1151   uint32_t offset = request->ReadUnsigned32("offset");
   1152   uint32_t length = request->ReadUnsigned32("length");
   1153   return Dbg::OutputArray(array_id, offset, length, pReply);
   1154 }
   1155 
   1156 /*
   1157  * Set values in an array.
   1158  */
   1159 static JdwpError AR_SetValues(JdwpState*, Request* request, ExpandBuf*)
   1160     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1161   ObjectId array_id = request->ReadArrayId();
   1162   uint32_t offset = request->ReadUnsigned32("offset");
   1163   uint32_t count = request->ReadUnsigned32("count");
   1164   return Dbg::SetArrayElements(array_id, offset, count, request);
   1165 }
   1166 
   1167 static JdwpError CLR_VisibleClasses(JdwpState*, Request* request, ExpandBuf* pReply)
   1168     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1169   request->ReadObjectId();  // classLoaderObject
   1170   // TODO: we should only return classes which have the given class loader as a defining or
   1171   // initiating loader. The former would be easy; the latter is hard, because we don't have
   1172   // any such notion.
   1173   return VM_AllClassesImpl(pReply, false, false);
   1174 }
   1175 
   1176 /*
   1177  * Set an event trigger.
   1178  *
   1179  * Reply with a requestID.
   1180  */
   1181 static JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply)
   1182     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1183   JdwpEventKind event_kind = request->ReadEnum1<JdwpEventKind>("event kind");
   1184   JdwpSuspendPolicy suspend_policy = request->ReadEnum1<JdwpSuspendPolicy>("suspend policy");
   1185   int32_t modifier_count = request->ReadSigned32("modifier count");
   1186 
   1187   CHECK_LT(modifier_count, 256);    /* reasonableness check */
   1188 
   1189   JdwpEvent* pEvent = EventAlloc(modifier_count);
   1190   pEvent->eventKind = event_kind;
   1191   pEvent->suspend_policy = suspend_policy;
   1192   pEvent->modCount = modifier_count;
   1193 
   1194   /*
   1195    * Read modifiers.  Ordering may be significant (see explanation of Count
   1196    * mods in JDWP doc).
   1197    */
   1198   for (int32_t i = 0; i < modifier_count; ++i) {
   1199     JdwpEventMod& mod = pEvent->mods[i];
   1200     mod.modKind = request->ReadModKind();
   1201     switch (mod.modKind) {
   1202     case MK_COUNT:
   1203       {
   1204         // Report once, when "--count" reaches 0.
   1205         uint32_t count = request->ReadUnsigned32("count");
   1206         if (count == 0) {
   1207           return ERR_INVALID_COUNT;
   1208         }
   1209         mod.count.count = count;
   1210       }
   1211       break;
   1212     case MK_CONDITIONAL:
   1213       {
   1214         // Conditional on expression.
   1215         uint32_t exprId = request->ReadUnsigned32("expr id");
   1216         mod.conditional.exprId = exprId;
   1217       }
   1218       break;
   1219     case MK_THREAD_ONLY:
   1220       {
   1221         // Only report events in specified thread.
   1222         ObjectId thread_id = request->ReadThreadId();
   1223         mod.threadOnly.threadId = thread_id;
   1224       }
   1225       break;
   1226     case MK_CLASS_ONLY:
   1227       {
   1228         // For ClassPrepare, MethodEntry.
   1229         RefTypeId class_id = request->ReadRefTypeId();
   1230         mod.classOnly.refTypeId = class_id;
   1231       }
   1232       break;
   1233     case MK_CLASS_MATCH:
   1234       {
   1235         // Restrict events to matching classes.
   1236         // pattern is "java.foo.*", we want "java/foo/*".
   1237         std::string pattern(request->ReadUtf8String());
   1238         std::replace(pattern.begin(), pattern.end(), '.', '/');
   1239         mod.classMatch.classPattern = strdup(pattern.c_str());
   1240       }
   1241       break;
   1242     case MK_CLASS_EXCLUDE:
   1243       {
   1244         // Restrict events to non-matching classes.
   1245         // pattern is "java.foo.*", we want "java/foo/*".
   1246         std::string pattern(request->ReadUtf8String());
   1247         std::replace(pattern.begin(), pattern.end(), '.', '/');
   1248         mod.classExclude.classPattern = strdup(pattern.c_str());
   1249       }
   1250       break;
   1251     case MK_LOCATION_ONLY:
   1252       {
   1253         // Restrict certain events based on location.
   1254         JdwpLocation location = request->ReadLocation();
   1255         mod.locationOnly.loc = location;
   1256       }
   1257       break;
   1258     case MK_EXCEPTION_ONLY:
   1259       {
   1260         // Modifies EK_EXCEPTION events,
   1261         mod.exceptionOnly.refTypeId = request->ReadRefTypeId();  // null => all exceptions.
   1262         mod.exceptionOnly.caught = request->ReadEnum1<uint8_t>("caught");
   1263         mod.exceptionOnly.uncaught = request->ReadEnum1<uint8_t>("uncaught");
   1264       }
   1265       break;
   1266     case MK_FIELD_ONLY:
   1267       {
   1268         // For field access/modification events.
   1269         RefTypeId declaring = request->ReadRefTypeId();
   1270         FieldId fieldId = request->ReadFieldId();
   1271         mod.fieldOnly.refTypeId = declaring;
   1272         mod.fieldOnly.fieldId = fieldId;
   1273       }
   1274       break;
   1275     case MK_STEP:
   1276       {
   1277         // For use with EK_SINGLE_STEP.
   1278         ObjectId thread_id = request->ReadThreadId();
   1279         uint32_t size = request->ReadUnsigned32("step size");
   1280         uint32_t depth = request->ReadUnsigned32("step depth");
   1281         VLOG(jdwp) << StringPrintf("    Step: thread=%#" PRIx64, thread_id)
   1282                      << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
   1283 
   1284         mod.step.threadId = thread_id;
   1285         mod.step.size = size;
   1286         mod.step.depth = depth;
   1287       }
   1288       break;
   1289     case MK_INSTANCE_ONLY:
   1290       {
   1291         // Report events related to a specific object.
   1292         ObjectId instance = request->ReadObjectId();
   1293         mod.instanceOnly.objectId = instance;
   1294       }
   1295       break;
   1296     default:
   1297       LOG(WARNING) << "Unsupported modifier " << mod.modKind << " for event " << pEvent->eventKind;
   1298       // Free allocated event to avoid leak before leaving.
   1299       EventFree(pEvent);
   1300       return JDWP::ERR_NOT_IMPLEMENTED;
   1301     }
   1302   }
   1303 
   1304   /*
   1305    * We reply with an integer "requestID".
   1306    */
   1307   uint32_t requestId = state->NextEventSerial();
   1308   expandBufAdd4BE(pReply, requestId);
   1309 
   1310   pEvent->requestId = requestId;
   1311 
   1312   VLOG(jdwp) << StringPrintf("    --> event requestId=%#x", requestId);
   1313 
   1314   /* add it to the list */
   1315   JdwpError err = state->RegisterEvent(pEvent);
   1316   if (err != ERR_NONE) {
   1317     /* registration failed, probably because event is bogus */
   1318     EventFree(pEvent);
   1319     LOG(WARNING) << "WARNING: event request rejected";
   1320   }
   1321   return err;
   1322 }
   1323 
   1324 static JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*)
   1325     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1326   request->ReadEnum1<JdwpEventKind>("event kind");
   1327   uint32_t requestId = request->ReadUnsigned32("request id");
   1328 
   1329   // Failure to find an event with a matching ID is a no-op
   1330   // and does not return an error.
   1331   state->UnregisterEventById(requestId);
   1332   return ERR_NONE;
   1333 }
   1334 
   1335 /*
   1336  * Return the values of arguments and local variables.
   1337  */
   1338 static JdwpError SF_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
   1339     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1340   return Dbg::GetLocalValues(request, pReply);
   1341 }
   1342 
   1343 /*
   1344  * Set the values of arguments and local variables.
   1345  */
   1346 static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
   1347     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1348   return Dbg::SetLocalValues(request);
   1349 }
   1350 
   1351 static JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply)
   1352     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1353   ObjectId thread_id = request->ReadThreadId();
   1354   FrameId frame_id = request->ReadFrameId();
   1355 
   1356   ObjectId object_id;
   1357   JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
   1358   if (rc != ERR_NONE) {
   1359     return rc;
   1360   }
   1361 
   1362   return WriteTaggedObject(reply, object_id);
   1363 }
   1364 
   1365 /*
   1366  * Return the reference type reflected by this class object.
   1367  *
   1368  * This appears to be required because ReferenceTypeId values are NEVER
   1369  * reused, whereas ClassIds can be recycled like any other object.  (Either
   1370  * that, or I have no idea what this is for.)
   1371  */
   1372 static JdwpError COR_ReflectedType(JdwpState*, Request* request, ExpandBuf* pReply)
   1373     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1374   RefTypeId class_object_id = request->ReadRefTypeId();
   1375   return Dbg::GetReflectedType(class_object_id, pReply);
   1376 }
   1377 
   1378 /*
   1379  * Handle a DDM packet with a single chunk in it.
   1380  */
   1381 static JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply)
   1382     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1383   state->NotifyDdmsActive();
   1384   uint8_t* replyBuf = nullptr;
   1385   int replyLen = -1;
   1386   if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) {
   1387     // If they want to send something back, we copy it into the buffer.
   1388     // TODO: consider altering the JDWP stuff to hold the packet header
   1389     // in a separate buffer.  That would allow us to writev() DDM traffic
   1390     // instead of copying it into the expanding buffer.  The reduction in
   1391     // heap requirements is probably more valuable than the efficiency.
   1392     CHECK_GT(replyLen, 0);
   1393     memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
   1394     free(replyBuf);
   1395   }
   1396   return ERR_NONE;
   1397 }
   1398 
   1399 /*
   1400  * Handler map decl.
   1401  */
   1402 typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request* request, ExpandBuf* reply);
   1403 
   1404 struct JdwpHandlerMap {
   1405   uint8_t cmdSet;
   1406   uint8_t cmd;
   1407   JdwpRequestHandler func;
   1408   const char* name;
   1409 };
   1410 
   1411 /*
   1412  * Map commands to functions.
   1413  *
   1414  * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
   1415  * and 128-256 are vendor-defined.
   1416  */
   1417 static const JdwpHandlerMap gHandlers[] = {
   1418   /* VirtualMachine command set (1) */
   1419   { 1,    1,  VM_Version,               "VirtualMachine.Version" },
   1420   { 1,    2,  VM_ClassesBySignature,    "VirtualMachine.ClassesBySignature" },
   1421   { 1,    3,  VM_AllClasses,            "VirtualMachine.AllClasses" },
   1422   { 1,    4,  VM_AllThreads,            "VirtualMachine.AllThreads" },
   1423   { 1,    5,  VM_TopLevelThreadGroups,  "VirtualMachine.TopLevelThreadGroups" },
   1424   { 1,    6,  VM_Dispose,               "VirtualMachine.Dispose" },
   1425   { 1,    7,  VM_IDSizes,               "VirtualMachine.IDSizes" },
   1426   { 1,    8,  VM_Suspend,               "VirtualMachine.Suspend" },
   1427   { 1,    9,  VM_Resume,                "VirtualMachine.Resume" },
   1428   { 1,    10, VM_Exit,                  "VirtualMachine.Exit" },
   1429   { 1,    11, VM_CreateString,          "VirtualMachine.CreateString" },
   1430   { 1,    12, VM_Capabilities,          "VirtualMachine.Capabilities" },
   1431   { 1,    13, VM_ClassPaths,            "VirtualMachine.ClassPaths" },
   1432   { 1,    14, VM_DisposeObjects,        "VirtualMachine.DisposeObjects" },
   1433   { 1,    15, nullptr,                  "VirtualMachine.HoldEvents" },
   1434   { 1,    16, nullptr,                  "VirtualMachine.ReleaseEvents" },
   1435   { 1,    17, VM_CapabilitiesNew,       "VirtualMachine.CapabilitiesNew" },
   1436   { 1,    18, nullptr,                  "VirtualMachine.RedefineClasses" },
   1437   { 1,    19, nullptr,                  "VirtualMachine.SetDefaultStratum" },
   1438   { 1,    20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
   1439   { 1,    21, VM_InstanceCounts,        "VirtualMachine.InstanceCounts" },
   1440 
   1441   /* ReferenceType command set (2) */
   1442   { 2,    1,  RT_Signature,            "ReferenceType.Signature" },
   1443   { 2,    2,  RT_ClassLoader,          "ReferenceType.ClassLoader" },
   1444   { 2,    3,  RT_Modifiers,            "ReferenceType.Modifiers" },
   1445   { 2,    4,  RT_Fields,               "ReferenceType.Fields" },
   1446   { 2,    5,  RT_Methods,              "ReferenceType.Methods" },
   1447   { 2,    6,  RT_GetValues,            "ReferenceType.GetValues" },
   1448   { 2,    7,  RT_SourceFile,           "ReferenceType.SourceFile" },
   1449   { 2,    8,  nullptr,                 "ReferenceType.NestedTypes" },
   1450   { 2,    9,  RT_Status,               "ReferenceType.Status" },
   1451   { 2,    10, RT_Interfaces,           "ReferenceType.Interfaces" },
   1452   { 2,    11, RT_ClassObject,          "ReferenceType.ClassObject" },
   1453   { 2,    12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
   1454   { 2,    13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
   1455   { 2,    14, RT_FieldsWithGeneric,    "ReferenceType.FieldsWithGeneric" },
   1456   { 2,    15, RT_MethodsWithGeneric,   "ReferenceType.MethodsWithGeneric" },
   1457   { 2,    16, RT_Instances,            "ReferenceType.Instances" },
   1458   { 2,    17, nullptr,                 "ReferenceType.ClassFileVersion" },
   1459   { 2,    18, nullptr,                 "ReferenceType.ConstantPool" },
   1460 
   1461   /* ClassType command set (3) */
   1462   { 3,    1,  CT_Superclass,    "ClassType.Superclass" },
   1463   { 3,    2,  CT_SetValues,     "ClassType.SetValues" },
   1464   { 3,    3,  CT_InvokeMethod,  "ClassType.InvokeMethod" },
   1465   { 3,    4,  CT_NewInstance,   "ClassType.NewInstance" },
   1466 
   1467   /* ArrayType command set (4) */
   1468   { 4,    1,  AT_newInstance,   "ArrayType.NewInstance" },
   1469 
   1470   /* InterfaceType command set (5) */
   1471 
   1472   /* Method command set (6) */
   1473   { 6,    1,  M_LineTable,                "Method.LineTable" },
   1474   { 6,    2,  M_VariableTable,            "Method.VariableTable" },
   1475   { 6,    3,  M_Bytecodes,                "Method.Bytecodes" },
   1476   { 6,    4,  nullptr,                    "Method.IsObsolete" },
   1477   { 6,    5,  M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
   1478 
   1479   /* Field command set (8) */
   1480 
   1481   /* ObjectReference command set (9) */
   1482   { 9,    1,  OR_ReferenceType,     "ObjectReference.ReferenceType" },
   1483   { 9,    2,  OR_GetValues,         "ObjectReference.GetValues" },
   1484   { 9,    3,  OR_SetValues,         "ObjectReference.SetValues" },
   1485   { 9,    4,  nullptr,              "ObjectReference.UNUSED" },
   1486   { 9,    5,  OR_MonitorInfo,       "ObjectReference.MonitorInfo" },
   1487   { 9,    6,  OR_InvokeMethod,      "ObjectReference.InvokeMethod" },
   1488   { 9,    7,  OR_DisableCollection, "ObjectReference.DisableCollection" },
   1489   { 9,    8,  OR_EnableCollection,  "ObjectReference.EnableCollection" },
   1490   { 9,    9,  OR_IsCollected,       "ObjectReference.IsCollected" },
   1491   { 9,    10, OR_ReferringObjects,  "ObjectReference.ReferringObjects" },
   1492 
   1493   /* StringReference command set (10) */
   1494   { 10,   1,  SR_Value,         "StringReference.Value" },
   1495 
   1496   /* ThreadReference command set (11) */
   1497   { 11,   1,  TR_Name,                        "ThreadReference.Name" },
   1498   { 11,   2,  TR_Suspend,                     "ThreadReference.Suspend" },
   1499   { 11,   3,  TR_Resume,                      "ThreadReference.Resume" },
   1500   { 11,   4,  TR_Status,                      "ThreadReference.Status" },
   1501   { 11,   5,  TR_ThreadGroup,                 "ThreadReference.ThreadGroup" },
   1502   { 11,   6,  TR_Frames,                      "ThreadReference.Frames" },
   1503   { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
   1504   { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
   1505   { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
   1506   { 11,   10, nullptr,                        "ThreadReference.Stop" },
   1507   { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
   1508   { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
   1509   { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
   1510   { 11,   14, nullptr,                        "ThreadReference.ForceEarlyReturn" },
   1511 
   1512   /* ThreadGroupReference command set (12) */
   1513   { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },
   1514   { 12,   2,  TGR_Parent,       "ThreadGroupReference.Parent" },
   1515   { 12,   3,  TGR_Children,     "ThreadGroupReference.Children" },
   1516 
   1517   /* ArrayReference command set (13) */
   1518   { 13,   1,  AR_Length,        "ArrayReference.Length" },
   1519   { 13,   2,  AR_GetValues,     "ArrayReference.GetValues" },
   1520   { 13,   3,  AR_SetValues,     "ArrayReference.SetValues" },
   1521 
   1522   /* ClassLoaderReference command set (14) */
   1523   { 14,   1,  CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
   1524 
   1525   /* EventRequest command set (15) */
   1526   { 15,   1,  ER_Set,           "EventRequest.Set" },
   1527   { 15,   2,  ER_Clear,         "EventRequest.Clear" },
   1528   { 15,   3,  nullptr,          "EventRequest.ClearAllBreakpoints" },
   1529 
   1530   /* StackFrame command set (16) */
   1531   { 16,   1,  SF_GetValues,     "StackFrame.GetValues" },
   1532   { 16,   2,  SF_SetValues,     "StackFrame.SetValues" },
   1533   { 16,   3,  SF_ThisObject,    "StackFrame.ThisObject" },
   1534   { 16,   4,  nullptr,          "StackFrame.PopFrames" },
   1535 
   1536   /* ClassObjectReference command set (17) */
   1537   { 17,   1,  COR_ReflectedType, "ClassObjectReference.ReflectedType" },
   1538 
   1539   /* Event command set (64) */
   1540   { 64, 100,  nullptr, "Event.Composite" },  // sent from VM to debugger, never received by VM
   1541 
   1542   { 199,  1,  DDM_Chunk,        "DDM.Chunk" },
   1543 };
   1544 
   1545 static const char* GetCommandName(Request* request) {
   1546   for (size_t i = 0; i < arraysize(gHandlers); ++i) {
   1547     if (gHandlers[i].cmdSet == request->GetCommandSet() &&
   1548         gHandlers[i].cmd == request->GetCommand()) {
   1549       return gHandlers[i].name;
   1550     }
   1551   }
   1552   return "?UNKNOWN?";
   1553 }
   1554 
   1555 static std::string DescribeCommand(Request* request) {
   1556   std::string result;
   1557   result += "REQUEST: ";
   1558   result += GetCommandName(request);
   1559   result += StringPrintf(" (length=%zu id=0x%06x)", request->GetLength(), request->GetId());
   1560   return result;
   1561 }
   1562 
   1563 // Returns true if the given command_set and command identify an "invoke" command.
   1564 static bool IsInvokeCommand(uint8_t command_set, uint8_t command) {
   1565   if (command_set == kJDWPClassTypeCmdSet) {
   1566     return command == kJDWPClassTypeInvokeMethodCmd || command == kJDWPClassTypeNewInstanceCmd;
   1567   } else if (command_set == kJDWPObjectReferenceCmdSet) {
   1568     return command == kJDWPObjectReferenceInvokeCmd;
   1569   } else {
   1570     return false;
   1571   }
   1572 }
   1573 
   1574 /*
   1575  * Process a request from the debugger. The skip_reply flag is set to true to indicate to the
   1576  * caller the reply must not be sent to the debugger. This is used for invoke commands where the
   1577  * reply is sent by the event thread after completing the invoke.
   1578  *
   1579  * On entry, the JDWP thread is in VMWAIT.
   1580  */
   1581 size_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply, bool* skip_reply) {
   1582   JdwpError result = ERR_NONE;
   1583   *skip_reply = false;
   1584 
   1585   if (request->GetCommandSet() != kJDWPDdmCmdSet) {
   1586     /*
   1587      * Activity from a debugger, not merely ddms.  Mark us as having an
   1588      * active debugger session, and zero out the last-activity timestamp
   1589      * so waitForDebugger() doesn't return if we stall for a bit here.
   1590      */
   1591     Dbg::GoActive();
   1592     last_activity_time_ms_.StoreSequentiallyConsistent(0);
   1593   }
   1594 
   1595   /*
   1596    * If a debugger event has fired in another thread, wait until the
   1597    * initiating thread has suspended itself before processing commands
   1598    * from the debugger.  Otherwise we (the JDWP thread) could be told to
   1599    * resume the thread before it has suspended.
   1600    *
   1601    * Note that we MUST clear the event token before waking the event
   1602    * thread up, or risk waiting for the thread to suspend after we've
   1603    * told it to resume.
   1604    */
   1605   AcquireJdwpTokenForCommand();
   1606 
   1607   /*
   1608    * Tell the VM that we're running and shouldn't be interrupted by GC.
   1609    * Do this after anything that can stall indefinitely.
   1610    */
   1611   Thread* self = Thread::Current();
   1612   ThreadState old_state = self->TransitionFromSuspendedToRunnable();
   1613 
   1614   expandBufAddSpace(pReply, kJDWPHeaderLen);
   1615 
   1616   size_t i;
   1617   for (i = 0; i < arraysize(gHandlers); ++i) {
   1618     if (gHandlers[i].cmdSet == request->GetCommandSet() &&
   1619         gHandlers[i].cmd == request->GetCommand() &&
   1620         gHandlers[i].func != nullptr) {
   1621       VLOG(jdwp) << DescribeCommand(request);
   1622       result = (*gHandlers[i].func)(this, request, pReply);
   1623       if (result == ERR_NONE) {
   1624         request->CheckConsumed();
   1625       }
   1626       self->AssertNoPendingException();
   1627       break;
   1628     }
   1629   }
   1630   if (i == arraysize(gHandlers)) {
   1631     LOG(ERROR) << "Command not implemented: " << DescribeCommand(request);
   1632     LOG(ERROR) << HexDump(request->data(), request->size(), false, "");
   1633     result = ERR_NOT_IMPLEMENTED;
   1634   }
   1635 
   1636   size_t replyLength = 0U;
   1637   if (result == ERR_NONE && IsInvokeCommand(request->GetCommandSet(), request->GetCommand())) {
   1638     // We successfully request an invoke in the event thread. It will send the reply once the
   1639     // invoke completes so we must not send it now.
   1640     *skip_reply = true;
   1641   } else {
   1642     /*
   1643      * Set up the reply header.
   1644      *
   1645      * If we encountered an error, only send the header back.
   1646      */
   1647     uint8_t* replyBuf = expandBufGetBuffer(pReply);
   1648     replyLength = (result == ERR_NONE) ? expandBufGetLength(pReply) : kJDWPHeaderLen;
   1649     Set4BE(replyBuf + kJDWPHeaderSizeOffset, replyLength);
   1650     Set4BE(replyBuf + kJDWPHeaderIdOffset, request->GetId());
   1651     Set1(replyBuf + kJDWPHeaderFlagsOffset, kJDWPFlagReply);
   1652     Set2BE(replyBuf + kJDWPHeaderErrorCodeOffset, result);
   1653 
   1654     CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request->GetId();
   1655 
   1656     size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
   1657     VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")";
   1658     if (false) {
   1659       VLOG(jdwp) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen, false, "");
   1660     }
   1661   }
   1662 
   1663   VLOG(jdwp) << "----------";
   1664 
   1665   /*
   1666    * Update last-activity timestamp.  We really only need this during
   1667    * the initial setup.  Only update if this is a non-DDMS packet.
   1668    */
   1669   if (request->GetCommandSet() != kJDWPDdmCmdSet) {
   1670     last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime());
   1671   }
   1672 
   1673   /* tell the VM that GC is okay again */
   1674   self->TransitionFromRunnableToSuspended(old_state);
   1675 
   1676   return replyLength;
   1677 }
   1678 
   1679 }  // namespace JDWP
   1680 
   1681 }  // namespace art
   1682