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 
DescribeField(const FieldId & field_id)41 std::string DescribeField(const FieldId& field_id) {
42   return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
43 }
44 
DescribeMethod(const MethodId & method_id)45 std::string DescribeMethod(const MethodId& method_id) {
46   return StringPrintf("%#" PRIx64 " (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
47 }
48 
DescribeRefTypeId(const RefTypeId & ref_type_id)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 
WriteTaggedObject(ExpandBuf * reply,ObjectId object_id)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 
WriteTaggedObjectList(ExpandBuf * reply,const std::vector<ObjectId> & objects)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  */
RequestInvoke(JdwpState *,Request * request,ObjectId thread_id,ObjectId object_id,RefTypeId class_id,MethodId method_id,bool is_constructor)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 
VM_Version(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_ClassesBySignature(JdwpState *,Request * request,ExpandBuf * pReply)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  */
VM_AllThreads(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_TopLevelThreadGroups(JdwpState *,Request *,ExpandBuf * pReply)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  */
VM_IDSizes(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_Dispose(JdwpState *,Request *,ExpandBuf *)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  */
VM_Suspend(JdwpState *,Request *,ExpandBuf *)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  */
VM_Resume(JdwpState *,Request *,ExpandBuf *)250 static JdwpError VM_Resume(JdwpState*, Request*, ExpandBuf*)
251     SHARED_LOCKS_REQUIRED(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_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  */
VM_CreateString(JdwpState *,Request * request,ExpandBuf * pReply)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 
VM_ClassPaths(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_DisposeObjects(JdwpState *,Request * request,ExpandBuf *)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 
VM_Capabilities(JdwpState *,Request *,ExpandBuf * reply)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 
VM_CapabilitiesNew(JdwpState *,Request * request,ExpandBuf * reply)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 
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_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 
VM_AllClasses(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_AllClassesWithGeneric(JdwpState *,Request *,ExpandBuf * pReply)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 
VM_InstanceCounts(JdwpState *,Request * request,ExpandBuf * pReply)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 
RT_Modifiers(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_SourceFile(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_Status(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_Interfaces(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_ClassObject(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_SourceDebugExtension(JdwpState *,Request *,ExpandBuf *)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 
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_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 
RT_Signature(JdwpState * state,Request * request,ExpandBuf * pReply)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 
RT_SignatureWithGeneric(JdwpState * state,Request * request,ExpandBuf * pReply)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  */
RT_ClassLoader(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_FieldsWithGeneric(JdwpState *,Request * request,ExpandBuf * pReply)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.
RT_Fields(JdwpState *,Request * request,ExpandBuf * pReply)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  */
RT_MethodsWithGeneric(JdwpState *,Request * request,ExpandBuf * pReply)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.
RT_Methods(JdwpState *,Request * request,ExpandBuf * pReply)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 
RT_Instances(JdwpState *,Request * request,ExpandBuf * reply)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  */
CT_Superclass(JdwpState *,Request * request,ExpandBuf * pReply)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  */
CT_SetValues(JdwpState *,Request * request,ExpandBuf *)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  */
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_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  */
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_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  */
AT_newInstance(JdwpState *,Request * request,ExpandBuf * pReply)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  */
M_LineTable(JdwpState *,Request * request,ExpandBuf * pReply)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 
M_VariableTable(JdwpState *,Request * request,ExpandBuf * pReply,bool generic)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 
M_VariableTable(JdwpState * state,Request * request,ExpandBuf * pReply)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 
M_VariableTableWithGeneric(JdwpState * state,Request * request,ExpandBuf * pReply)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 
M_Bytecodes(JdwpState *,Request * request,ExpandBuf * reply)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  */
OR_ReferenceType(JdwpState *,Request * request,ExpandBuf * pReply)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  */
OR_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
OR_SetValues(JdwpState *,Request * request,ExpandBuf *)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 
OR_MonitorInfo(JdwpState *,Request * request,ExpandBuf * reply)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  */
OR_InvokeMethod(JdwpState * state,Request * request,ExpandBuf * pReply ATTRIBUTE_UNUSED)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 
OR_DisableCollection(JdwpState *,Request * request,ExpandBuf *)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 
OR_EnableCollection(JdwpState *,Request * request,ExpandBuf *)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 
OR_IsCollected(JdwpState *,Request * request,ExpandBuf * pReply)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 
OR_ReferringObjects(JdwpState *,Request * request,ExpandBuf * reply)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  */
SR_Value(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Name(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Suspend(JdwpState *,Request * request,ExpandBuf *)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  */
TR_Resume(JdwpState *,Request * request,ExpandBuf *)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  */
TR_Status(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_ThreadGroup(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_Frames(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TR_FrameCount(JdwpState *,Request * request,ExpandBuf * pReply)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 
TR_OwnedMonitors(Request * request,ExpandBuf * reply,bool with_stack_depths)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 
TR_OwnedMonitors(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_OwnedMonitorsStackDepthInfo(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_CurrentContendedMonitor(JdwpState *,Request * request,ExpandBuf * reply)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 
TR_Interrupt(JdwpState *,Request * request,ExpandBuf * reply)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  */
TR_DebugSuspendCount(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Name(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Parent(JdwpState *,Request * request,ExpandBuf * pReply)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  */
TGR_Children(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_Length(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
AR_SetValues(JdwpState *,Request * request,ExpandBuf *)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 
CLR_VisibleClasses(JdwpState *,Request * request,ExpandBuf * pReply)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  */
ER_Set(JdwpState * state,Request * request,ExpandBuf * pReply)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 
ER_Clear(JdwpState * state,Request * request,ExpandBuf *)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  */
SF_GetValues(JdwpState *,Request * request,ExpandBuf * pReply)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  */
SF_SetValues(JdwpState *,Request * request,ExpandBuf *)1346 static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
1347     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1348   return Dbg::SetLocalValues(request);
1349 }
1350 
SF_ThisObject(JdwpState *,Request * request,ExpandBuf * reply)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  */
COR_ReflectedType(JdwpState *,Request * request,ExpandBuf * pReply)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  */
DDM_Chunk(JdwpState * state,Request * request,ExpandBuf * pReply)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 
GetCommandName(Request * request)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 
DescribeCommand(Request * request)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.
IsInvokeCommand(uint8_t command_set,uint8_t 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  */
ProcessRequest(Request * request,ExpandBuf * pReply,bool * skip_reply)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