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