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 
DescribeField(const FieldId & field_id)42 std::string DescribeField(const FieldId& field_id) {
43   return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
44 }
45 
DescribeMethod(const MethodId & method_id)46 std::string DescribeMethod(const MethodId& method_id) {
47   return StringPrintf("%#" PRIx64 " (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
48 }
49 
DescribeRefTypeId(const RefTypeId & ref_type_id)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 
WriteTaggedObject(ExpandBuf * reply,ObjectId object_id)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 
WriteTaggedObjectList(ExpandBuf * reply,const std::vector<ObjectId> & objects)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  */
RequestInvoke(JdwpState *,Request * request,ObjectId thread_id,ObjectId object_id,RefTypeId class_id,MethodId method_id,bool is_constructor)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 
VM_Version(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_ClassesBySignature(JdwpState *,Request * request,ExpandBuf * pReply)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  */
VM_AllThreads(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_TopLevelThreadGroups(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_IDSizes(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_Dispose(JdwpState *,Request *,ExpandBuf *)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  */
VM_Suspend(JdwpState *,Request *,ExpandBuf *)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  */
VM_Resume(JdwpState *,Request *,ExpandBuf *)250 static JdwpError VM_Resume(JdwpState*, Request*, ExpandBuf*)
251     SHARED_REQUIRES(Locks::mutator_lock_) {
252   Dbg::ResumeVM();
253   return ERR_NONE;
254 }
255 
VM_Exit(JdwpState * state,Request * request,ExpandBuf *)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  */
VM_CreateString(JdwpState *,Request * request,ExpandBuf * pReply)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 
VM_ClassPaths(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_DisposeObjects(JdwpState *,Request * request,ExpandBuf *)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 
VM_Capabilities(JdwpState *,Request *,ExpandBuf * reply)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 
VM_CapabilitiesNew(JdwpState *,Request * request,ExpandBuf * reply)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 
VM_AllClassesImpl(ExpandBuf * pReply,bool descriptor_and_status,bool generic)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 
VM_AllClasses(JdwpState *,Request *,ExpandBuf * pReply)383 static JdwpError VM_AllClasses(JdwpState*, Request*, ExpandBuf* pReply)
384     SHARED_REQUIRES(Locks::mutator_lock_) {
385   return VM_AllClassesImpl(pReply, true, false);
386 }
387 
VM_AllClassesWithGeneric(JdwpState *,Request *,ExpandBuf * pReply)388 static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply)
389     SHARED_REQUIRES(Locks::mutator_lock_) {
390   return VM_AllClassesImpl(pReply, true, true);
391 }
392 
VM_InstanceCounts(JdwpState *,Request * request,ExpandBuf * pReply)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 
RT_Modifiers(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_SourceFile(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_Status(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_Interfaces(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_ClassObject(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_SourceDebugExtension(JdwpState *,Request *,ExpandBuf *)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 
RT_Signature(JdwpState *,Request * request,ExpandBuf * pReply,bool with_generic)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 
RT_Signature(JdwpState * state,Request * request,ExpandBuf * pReply)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 
RT_SignatureWithGeneric(JdwpState * state,Request * request,ExpandBuf * pReply)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  */
RT_ClassLoader(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_FieldsWithGeneric(JdwpState *,Request * request,ExpandBuf * pReply)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.
RT_Fields(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_MethodsWithGeneric(JdwpState *,Request * request,ExpandBuf * pReply)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.
RT_Methods(JdwpState *,Request * request,ExpandBuf * pReply)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 
RT_Instances(JdwpState *,Request * request,ExpandBuf * reply)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  */
CT_Superclass(JdwpState *,Request * request,ExpandBuf * pReply)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  */
CT_SetValues(JdwpState *,Request * request,ExpandBuf *)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  */
CT_InvokeMethod(JdwpState * state,Request * request,ExpandBuf * pReply ATTRIBUTE_UNUSED)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  */
CT_NewInstance(JdwpState * state,Request * request,ExpandBuf * pReply ATTRIBUTE_UNUSED)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  */
AT_newInstance(JdwpState *,Request * request,ExpandBuf * pReply)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  */
IT_InvokeMethod(JdwpState * state,Request * request,ExpandBuf * pReply ATTRIBUTE_UNUSED)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  */
M_LineTable(JdwpState *,Request * request,ExpandBuf * pReply)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 
M_VariableTable(JdwpState *,Request * request,ExpandBuf * pReply,bool generic)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 
M_VariableTable(JdwpState * state,Request * request,ExpandBuf * pReply)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 
M_VariableTableWithGeneric(JdwpState * state,Request * request,ExpandBuf * pReply)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 
M_Bytecodes(JdwpState *,Request * request,ExpandBuf * reply)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.
M_IsObsolete(JdwpState *,Request * request,ExpandBuf * reply)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  */
OR_ReferenceType(JdwpState *,Request * request,ExpandBuf * pReply)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  */
OR_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
OR_SetValues(JdwpState *,Request * request,ExpandBuf *)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 
OR_MonitorInfo(JdwpState *,Request * request,ExpandBuf * reply)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  */
OR_InvokeMethod(JdwpState * state,Request * request,ExpandBuf * pReply ATTRIBUTE_UNUSED)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 
OR_DisableCollection(JdwpState *,Request * request,ExpandBuf *)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 
OR_EnableCollection(JdwpState *,Request * request,ExpandBuf *)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 
OR_IsCollected(JdwpState *,Request * request,ExpandBuf * pReply)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 
OR_ReferringObjects(JdwpState *,Request * request,ExpandBuf * reply)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  */
SR_Value(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Name(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Suspend(JdwpState *,Request * request,ExpandBuf *)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  */
TR_Resume(JdwpState *,Request * request,ExpandBuf *)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  */
TR_Status(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_ThreadGroup(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Frames(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_FrameCount(JdwpState *,Request * request,ExpandBuf * pReply)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 
TR_OwnedMonitors(Request * request,ExpandBuf * reply,bool with_stack_depths)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 
TR_OwnedMonitors(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_OwnedMonitorsStackDepthInfo(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_CurrentContendedMonitor(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_Interrupt(JdwpState *,Request * request,ExpandBuf * reply ATTRIBUTE_UNUSED)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  */
TR_DebugSuspendCount(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Name(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Parent(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Children(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_Length(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_SetValues(JdwpState *,Request * request,ExpandBuf *)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 
CLR_VisibleClasses(JdwpState *,Request * request,ExpandBuf * pReply)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 {
operator ()art::JDWP::JdwpEventDeleter1198   void operator()(JdwpEvent* event) {
1199     EventFree(event);
1200   }
1201 };
1202 
1203 /*
1204  * Set an event trigger.
1205  *
1206  * Reply with a requestID.
1207  */
ER_Set(JdwpState * state,Request * request,ExpandBuf * pReply)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 
ER_Clear(JdwpState * state,Request * request,ExpandBuf *)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  */
SF_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
SF_SetValues(JdwpState *,Request * request,ExpandBuf *)1372 static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
1373     SHARED_REQUIRES(Locks::mutator_lock_) {
1374   return Dbg::SetLocalValues(request);
1375 }
1376 
SF_ThisObject(JdwpState *,Request * request,ExpandBuf * reply)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  */
COR_ReflectedType(JdwpState *,Request * request,ExpandBuf * pReply)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  */
DDM_Chunk(JdwpState * state,Request * request,ExpandBuf * pReply)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 
GetCommandName(Request * request)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 
DescribeCommand(Request * request)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.
IsInvokeCommand(uint8_t command_set,uint8_t 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  */
ProcessRequest(Request * request,ExpandBuf * pReply,bool * skip_reply)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