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