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