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