jdwp_handler.cc revision 677cd61ad05d993c4d3b22656675874f06d6aabc
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
36namespace art {
37
38namespace JDWP {
39
40std::string DescribeField(const FieldId& field_id) {
41  return StringPrintf("%#x (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
42}
43
44std::string DescribeMethod(const MethodId& method_id) {
45  return StringPrintf("%#x (%s)", method_id, Dbg::GetMethodName(method_id).c_str());
46}
47
48std::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.
55static 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
65static 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
76static 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 */
94static 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
169static 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 */
193static 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 */
225static 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 */
241static 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 */
262static 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
272static 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 */
284static 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 */
296static 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
303static 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 */
316static 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
327static 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
348static 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
359static 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
371static 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
398static 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
429static JdwpError VM_AllClasses(JdwpState*, Request*, ExpandBuf* pReply)
430    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
431  return VM_AllClassesImpl(pReply, true, false);
432}
433
434static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply)
435    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
436  return VM_AllClassesImpl(pReply, true, true);
437}
438
439static 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
463static 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 */
472static 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 */
490static 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 */
505static 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 */
521static 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 */
530static 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 */
548static 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
554static 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
570static 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
575static 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 */
584static 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 */
594static 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.
601static 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 */
611static 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.
618static 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
624static 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 */
644static 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 */
659static 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 */
688static 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 */
704static 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 */
724static 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 */
745static 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
755static 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
769static 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
774static 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
779static 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 */
805static 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 */
814static 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 */
834static 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
856static 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 */
873static 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
883static 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
889static 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
895static 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
904static 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 */
924static 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 */
943static 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 */
964static 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 */
983static 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 */
1001static 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 */
1023static 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 */
1035static 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 */
1067static 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
1081static 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
1105static JdwpError TR_OwnedMonitors(JdwpState*, Request* request, ExpandBuf* reply)
1106    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1107  return TR_OwnedMonitors(request, reply, false);
1108}
1109
1110static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request* request, ExpandBuf* reply)
1111    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1112  return TR_OwnedMonitors(request, reply, true);
1113}
1114
1115static 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
1127static 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 */
1139static 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 */
1150static 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 */
1160static 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 */
1170static 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 */
1179static JdwpError AR_Length(JdwpState*, Request* request, ExpandBuf* pReply)
1180    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1181  ObjectId array_id = request->ReadArrayId();
1182
1183  int32_t 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 */
1198static 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 */
1209static 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
1217static 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 */
1231static 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) << "GLITCH: unsupported modKind=" << mod.modKind;
1348      break;
1349    }
1350  }
1351
1352  /*
1353   * We reply with an integer "requestID".
1354   */
1355  uint32_t requestId = state->NextEventSerial();
1356  expandBufAdd4BE(pReply, requestId);
1357
1358  pEvent->requestId = requestId;
1359
1360  VLOG(jdwp) << StringPrintf("    --> event requestId=%#x", requestId);
1361
1362  /* add it to the list */
1363  JdwpError err = state->RegisterEvent(pEvent);
1364  if (err != ERR_NONE) {
1365    /* registration failed, probably because event is bogus */
1366    EventFree(pEvent);
1367    LOG(WARNING) << "WARNING: event request rejected";
1368  }
1369  return err;
1370}
1371
1372static JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*)
1373    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1374  request->ReadEnum1<JdwpEventKind>("event kind");
1375  uint32_t requestId = request->ReadUnsigned32("request id");
1376
1377  // Failure to find an event with a matching ID is a no-op
1378  // and does not return an error.
1379  state->UnregisterEventById(requestId);
1380  return ERR_NONE;
1381}
1382
1383/*
1384 * Return the values of arguments and local variables.
1385 */
1386static JdwpError SF_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
1387    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1388  return Dbg::GetLocalValues(request, pReply);
1389}
1390
1391/*
1392 * Set the values of arguments and local variables.
1393 */
1394static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
1395    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1396  return Dbg::SetLocalValues(request);
1397}
1398
1399static JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply)
1400    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1401  ObjectId thread_id = request->ReadThreadId();
1402  FrameId frame_id = request->ReadFrameId();
1403
1404  ObjectId object_id;
1405  JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
1406  if (rc != ERR_NONE) {
1407    return rc;
1408  }
1409
1410  return WriteTaggedObject(reply, object_id);
1411}
1412
1413/*
1414 * Return the reference type reflected by this class object.
1415 *
1416 * This appears to be required because ReferenceTypeId values are NEVER
1417 * reused, whereas ClassIds can be recycled like any other object.  (Either
1418 * that, or I have no idea what this is for.)
1419 */
1420static JdwpError COR_ReflectedType(JdwpState*, Request* request, ExpandBuf* pReply)
1421    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1422  RefTypeId class_object_id = request->ReadRefTypeId();
1423  return Dbg::GetReflectedType(class_object_id, pReply);
1424}
1425
1426/*
1427 * Handle a DDM packet with a single chunk in it.
1428 */
1429static JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply)
1430    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1431  state->NotifyDdmsActive();
1432  uint8_t* replyBuf = NULL;
1433  int replyLen = -1;
1434  if (Dbg::DdmHandlePacket(request, &replyBuf, &replyLen)) {
1435    // If they want to send something back, we copy it into the buffer.
1436    // TODO: consider altering the JDWP stuff to hold the packet header
1437    // in a separate buffer.  That would allow us to writev() DDM traffic
1438    // instead of copying it into the expanding buffer.  The reduction in
1439    // heap requirements is probably more valuable than the efficiency.
1440    CHECK_GT(replyLen, 0);
1441    memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
1442    free(replyBuf);
1443  }
1444  return ERR_NONE;
1445}
1446
1447/*
1448 * Handler map decl.
1449 */
1450typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request* request, ExpandBuf* reply);
1451
1452struct JdwpHandlerMap {
1453  uint8_t cmdSet;
1454  uint8_t cmd;
1455  JdwpRequestHandler func;
1456  const char* name;
1457};
1458
1459/*
1460 * Map commands to functions.
1461 *
1462 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
1463 * and 128-256 are vendor-defined.
1464 */
1465static const JdwpHandlerMap gHandlers[] = {
1466  /* VirtualMachine command set (1) */
1467  { 1,    1,  VM_Version,               "VirtualMachine.Version" },
1468  { 1,    2,  VM_ClassesBySignature,    "VirtualMachine.ClassesBySignature" },
1469  { 1,    3,  VM_AllClasses,            "VirtualMachine.AllClasses" },
1470  { 1,    4,  VM_AllThreads,            "VirtualMachine.AllThreads" },
1471  { 1,    5,  VM_TopLevelThreadGroups,  "VirtualMachine.TopLevelThreadGroups" },
1472  { 1,    6,  VM_Dispose,               "VirtualMachine.Dispose" },
1473  { 1,    7,  VM_IDSizes,               "VirtualMachine.IDSizes" },
1474  { 1,    8,  VM_Suspend,               "VirtualMachine.Suspend" },
1475  { 1,    9,  VM_Resume,                "VirtualMachine.Resume" },
1476  { 1,    10, VM_Exit,                  "VirtualMachine.Exit" },
1477  { 1,    11, VM_CreateString,          "VirtualMachine.CreateString" },
1478  { 1,    12, VM_Capabilities,          "VirtualMachine.Capabilities" },
1479  { 1,    13, VM_ClassPaths,            "VirtualMachine.ClassPaths" },
1480  { 1,    14, VM_DisposeObjects,        "VirtualMachine.DisposeObjects" },
1481  { 1,    15, NULL,                     "VirtualMachine.HoldEvents" },
1482  { 1,    16, NULL,                     "VirtualMachine.ReleaseEvents" },
1483  { 1,    17, VM_CapabilitiesNew,       "VirtualMachine.CapabilitiesNew" },
1484  { 1,    18, NULL,                     "VirtualMachine.RedefineClasses" },
1485  { 1,    19, NULL,                     "VirtualMachine.SetDefaultStratum" },
1486  { 1,    20, VM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric" },
1487  { 1,    21, VM_InstanceCounts,        "VirtualMachine.InstanceCounts" },
1488
1489  /* ReferenceType command set (2) */
1490  { 2,    1,  RT_Signature,            "ReferenceType.Signature" },
1491  { 2,    2,  RT_ClassLoader,          "ReferenceType.ClassLoader" },
1492  { 2,    3,  RT_Modifiers,            "ReferenceType.Modifiers" },
1493  { 2,    4,  RT_Fields,               "ReferenceType.Fields" },
1494  { 2,    5,  RT_Methods,              "ReferenceType.Methods" },
1495  { 2,    6,  RT_GetValues,            "ReferenceType.GetValues" },
1496  { 2,    7,  RT_SourceFile,           "ReferenceType.SourceFile" },
1497  { 2,    8,  NULL,                    "ReferenceType.NestedTypes" },
1498  { 2,    9,  RT_Status,               "ReferenceType.Status" },
1499  { 2,    10, RT_Interfaces,           "ReferenceType.Interfaces" },
1500  { 2,    11, RT_ClassObject,          "ReferenceType.ClassObject" },
1501  { 2,    12, RT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
1502  { 2,    13, RT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
1503  { 2,    14, RT_FieldsWithGeneric,    "ReferenceType.FieldsWithGeneric" },
1504  { 2,    15, RT_MethodsWithGeneric,   "ReferenceType.MethodsWithGeneric" },
1505  { 2,    16, RT_Instances,            "ReferenceType.Instances" },
1506  { 2,    17, NULL,                    "ReferenceType.ClassFileVersion" },
1507  { 2,    18, NULL,                    "ReferenceType.ConstantPool" },
1508
1509  /* ClassType command set (3) */
1510  { 3,    1,  CT_Superclass,    "ClassType.Superclass" },
1511  { 3,    2,  CT_SetValues,     "ClassType.SetValues" },
1512  { 3,    3,  CT_InvokeMethod,  "ClassType.InvokeMethod" },
1513  { 3,    4,  CT_NewInstance,   "ClassType.NewInstance" },
1514
1515  /* ArrayType command set (4) */
1516  { 4,    1,  AT_newInstance,   "ArrayType.NewInstance" },
1517
1518  /* InterfaceType command set (5) */
1519
1520  /* Method command set (6) */
1521  { 6,    1,  M_LineTable,                "Method.LineTable" },
1522  { 6,    2,  M_VariableTable,            "Method.VariableTable" },
1523  { 6,    3,  M_Bytecodes,                "Method.Bytecodes" },
1524  { 6,    4,  NULL,                       "Method.IsObsolete" },
1525  { 6,    5,  M_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
1526
1527  /* Field command set (8) */
1528
1529  /* ObjectReference command set (9) */
1530  { 9,    1,  OR_ReferenceType,     "ObjectReference.ReferenceType" },
1531  { 9,    2,  OR_GetValues,         "ObjectReference.GetValues" },
1532  { 9,    3,  OR_SetValues,         "ObjectReference.SetValues" },
1533  { 9,    4,  NULL,                 "ObjectReference.UNUSED" },
1534  { 9,    5,  OR_MonitorInfo,       "ObjectReference.MonitorInfo" },
1535  { 9,    6,  OR_InvokeMethod,      "ObjectReference.InvokeMethod" },
1536  { 9,    7,  OR_DisableCollection, "ObjectReference.DisableCollection" },
1537  { 9,    8,  OR_EnableCollection,  "ObjectReference.EnableCollection" },
1538  { 9,    9,  OR_IsCollected,       "ObjectReference.IsCollected" },
1539  { 9,    10, OR_ReferringObjects,  "ObjectReference.ReferringObjects" },
1540
1541  /* StringReference command set (10) */
1542  { 10,   1,  SR_Value,         "StringReference.Value" },
1543
1544  /* ThreadReference command set (11) */
1545  { 11,   1,  TR_Name,                        "ThreadReference.Name" },
1546  { 11,   2,  TR_Suspend,                     "ThreadReference.Suspend" },
1547  { 11,   3,  TR_Resume,                      "ThreadReference.Resume" },
1548  { 11,   4,  TR_Status,                      "ThreadReference.Status" },
1549  { 11,   5,  TR_ThreadGroup,                 "ThreadReference.ThreadGroup" },
1550  { 11,   6,  TR_Frames,                      "ThreadReference.Frames" },
1551  { 11,   7,  TR_FrameCount,                  "ThreadReference.FrameCount" },
1552  { 11,   8,  TR_OwnedMonitors,               "ThreadReference.OwnedMonitors" },
1553  { 11,   9,  TR_CurrentContendedMonitor,     "ThreadReference.CurrentContendedMonitor" },
1554  { 11,   10, NULL,                           "ThreadReference.Stop" },
1555  { 11,   11, TR_Interrupt,                   "ThreadReference.Interrupt" },
1556  { 11,   12, TR_DebugSuspendCount,           "ThreadReference.SuspendCount" },
1557  { 11,   13, TR_OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo" },
1558  { 11,   14, NULL,                           "ThreadReference.ForceEarlyReturn" },
1559
1560  /* ThreadGroupReference command set (12) */
1561  { 12,   1,  TGR_Name,         "ThreadGroupReference.Name" },
1562  { 12,   2,  TGR_Parent,       "ThreadGroupReference.Parent" },
1563  { 12,   3,  TGR_Children,     "ThreadGroupReference.Children" },
1564
1565  /* ArrayReference command set (13) */
1566  { 13,   1,  AR_Length,        "ArrayReference.Length" },
1567  { 13,   2,  AR_GetValues,     "ArrayReference.GetValues" },
1568  { 13,   3,  AR_SetValues,     "ArrayReference.SetValues" },
1569
1570  /* ClassLoaderReference command set (14) */
1571  { 14,   1,  CLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
1572
1573  /* EventRequest command set (15) */
1574  { 15,   1,  ER_Set,           "EventRequest.Set" },
1575  { 15,   2,  ER_Clear,         "EventRequest.Clear" },
1576  { 15,   3,  NULL,             "EventRequest.ClearAllBreakpoints" },
1577
1578  /* StackFrame command set (16) */
1579  { 16,   1,  SF_GetValues,     "StackFrame.GetValues" },
1580  { 16,   2,  SF_SetValues,     "StackFrame.SetValues" },
1581  { 16,   3,  SF_ThisObject,    "StackFrame.ThisObject" },
1582  { 16,   4,  NULL,             "StackFrame.PopFrames" },
1583
1584  /* ClassObjectReference command set (17) */
1585  { 17,   1,  COR_ReflectedType, "ClassObjectReference.ReflectedType" },
1586
1587  /* Event command set (64) */
1588  { 64, 100,  NULL, "Event.Composite" },  // sent from VM to debugger, never received by VM
1589
1590  { 199,  1,  DDM_Chunk,        "DDM.Chunk" },
1591};
1592
1593static const char* GetCommandName(Request* request) {
1594  for (size_t i = 0; i < arraysize(gHandlers); ++i) {
1595    if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand()) {
1596      return gHandlers[i].name;
1597    }
1598  }
1599  return "?UNKNOWN?";
1600}
1601
1602static std::string DescribeCommand(Request* request) {
1603  std::string result;
1604  result += "REQUEST: ";
1605  result += GetCommandName(request);
1606  result += StringPrintf(" (length=%zu id=0x%06x)", request->GetLength(), request->GetId());
1607  return result;
1608}
1609
1610/*
1611 * Process a request from the debugger.
1612 *
1613 * On entry, the JDWP thread is in VMWAIT.
1614 */
1615size_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply) {
1616  JdwpError result = ERR_NONE;
1617
1618  if (request->GetCommandSet() != kJDWPDdmCmdSet) {
1619    /*
1620     * Activity from a debugger, not merely ddms.  Mark us as having an
1621     * active debugger session, and zero out the last-activity timestamp
1622     * so waitForDebugger() doesn't return if we stall for a bit here.
1623     */
1624    Dbg::GoActive();
1625    last_activity_time_ms_.StoreSequentiallyConsistent(0);
1626  }
1627
1628  /*
1629   * If a debugger event has fired in another thread, wait until the
1630   * initiating thread has suspended itself before processing messages
1631   * from the debugger.  Otherwise we (the JDWP thread) could be told to
1632   * resume the thread before it has suspended.
1633   *
1634   * We call with an argument of zero to wait for the current event
1635   * thread to finish, and then clear the block.  Depending on the thread
1636   * suspend policy, this may allow events in other threads to fire,
1637   * but those events have no bearing on what the debugger has sent us
1638   * in the current request->
1639   *
1640   * Note that we MUST clear the event token before waking the event
1641   * thread up, or risk waiting for the thread to suspend after we've
1642   * told it to resume.
1643   */
1644  SetWaitForEventThread(0);
1645
1646  /*
1647   * We do not want events to be sent while we process a request-> Indicate the JDWP thread starts
1648   * to process a request so other threads wait for it to finish before sending an event.
1649   */
1650  StartProcessingRequest();
1651
1652  /*
1653   * Tell the VM that we're running and shouldn't be interrupted by GC.
1654   * Do this after anything that can stall indefinitely.
1655   */
1656  Thread* self = Thread::Current();
1657  ThreadState old_state = self->TransitionFromSuspendedToRunnable();
1658
1659  expandBufAddSpace(pReply, kJDWPHeaderLen);
1660
1661  size_t i;
1662  for (i = 0; i < arraysize(gHandlers); ++i) {
1663    if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand() && gHandlers[i].func != NULL) {
1664      VLOG(jdwp) << DescribeCommand(request);
1665      result = (*gHandlers[i].func)(this, request, pReply);
1666      if (result == ERR_NONE) {
1667        request->CheckConsumed();
1668      }
1669      break;
1670    }
1671  }
1672  if (i == arraysize(gHandlers)) {
1673    LOG(ERROR) << "Command not implemented: " << DescribeCommand(request);
1674    LOG(ERROR) << HexDump(request->data(), request->size(), false, "");
1675    result = ERR_NOT_IMPLEMENTED;
1676  }
1677
1678  /*
1679   * Set up the reply header.
1680   *
1681   * If we encountered an error, only send the header back.
1682   */
1683  uint8_t* replyBuf = expandBufGetBuffer(pReply);
1684  size_t replyLength = (result == ERR_NONE) ? expandBufGetLength(pReply) : kJDWPHeaderLen;
1685  Set4BE(replyBuf + 0, replyLength);
1686  Set4BE(replyBuf + 4, request->GetId());
1687  Set1(replyBuf + 8, kJDWPFlagReply);
1688  Set2BE(replyBuf + 9, result);
1689
1690  CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request->GetId();
1691
1692  size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
1693  VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")";
1694  if (false) {
1695    VLOG(jdwp) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen, false, "");
1696  }
1697
1698  VLOG(jdwp) << "----------";
1699
1700  /*
1701   * Update last-activity timestamp.  We really only need this during
1702   * the initial setup.  Only update if this is a non-DDMS packet.
1703   */
1704  if (request->GetCommandSet() != kJDWPDdmCmdSet) {
1705    last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime());
1706  }
1707
1708  /* tell the VM that GC is okay again */
1709  self->TransitionFromRunnableToSuspended(old_state);
1710
1711  return replyLength;
1712}
1713
1714/*
1715 * Indicates a request is about to be processed. If a thread wants to send an event in the meantime,
1716 * it will need to wait until we processed this request (see EndProcessingRequest).
1717 */
1718void JdwpState::StartProcessingRequest() {
1719  Thread* self = Thread::Current();
1720  CHECK_EQ(self, GetDebugThread()) << "Requests are only processed by debug thread";
1721  MutexLock mu(self, process_request_lock_);
1722  CHECK_EQ(processing_request_, false);
1723  processing_request_ = true;
1724}
1725
1726/*
1727 * Indicates a request has been processed (and we sent its reply). All threads waiting for us (see
1728 * WaitForProcessingRequest) are waken up so they can send events again.
1729 */
1730void JdwpState::EndProcessingRequest() {
1731  Thread* self = Thread::Current();
1732  CHECK_EQ(self, GetDebugThread()) << "Requests are only processed by debug thread";
1733  MutexLock mu(self, process_request_lock_);
1734  CHECK_EQ(processing_request_, true);
1735  processing_request_ = false;
1736  process_request_cond_.Broadcast(self);
1737}
1738
1739/*
1740 * Waits for any request being processed so we do not send an event in the meantime.
1741 */
1742void JdwpState::WaitForProcessingRequest() {
1743  Thread* self = Thread::Current();
1744  CHECK_NE(self, GetDebugThread()) << "Events should not be posted by debug thread";
1745  MutexLock mu(self, process_request_lock_);
1746  bool waited = false;
1747  while (processing_request_) {
1748    VLOG(jdwp) << StringPrintf("wait for processing request");
1749    waited = true;
1750    process_request_cond_.Wait(self);
1751  }
1752  if (waited) {
1753    VLOG(jdwp) << StringPrintf("finished waiting for processing request");
1754  }
1755  CHECK_EQ(processing_request_, false);
1756}
1757
1758}  // namespace JDWP
1759
1760}  // namespace art
1761