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 "jdwp/jdwp_event.h" 18 19#include <stddef.h> /* for offsetof() */ 20#include <stdlib.h> 21#include <string.h> 22#include <unistd.h> 23 24#include "android-base/stringprintf.h" 25 26#include "art_field-inl.h" 27#include "art_method-inl.h" 28#include "base/logging.h" 29#include "debugger.h" 30#include "jdwp/jdwp_constants.h" 31#include "jdwp/jdwp_expand_buf.h" 32#include "jdwp/jdwp_priv.h" 33#include "jdwp/object_registry.h" 34#include "scoped_thread_state_change-inl.h" 35#include "thread-inl.h" 36 37#include "handle_scope-inl.h" 38 39/* 40General notes: 41 42The event add/remove stuff usually happens from the debugger thread, 43in response to requests from the debugger, but can also happen as the 44result of an event in an arbitrary thread (e.g. an event with a "count" 45mod expires). It's important to keep the event list locked when processing 46events. 47 48Event posting can happen from any thread. The JDWP thread will not usually 49post anything but VM start/death, but if a JDWP request causes a class 50to be loaded, the ClassPrepare event will come from the JDWP thread. 51 52 53We can have serialization issues when we post an event to the debugger. 54For example, a thread could send an "I hit a breakpoint and am suspending 55myself" message to the debugger. Before it manages to suspend itself, the 56debugger's response ("not interested, resume thread") arrives and is 57processed. We try to resume a thread that hasn't yet suspended. 58 59This means that, after posting an event to the debugger, we need to wait 60for the event thread to suspend itself (and, potentially, all other threads) 61before processing any additional requests from the debugger. While doing 62so we need to be aware that multiple threads may be hitting breakpoints 63or other events simultaneously, so we either need to wait for all of them 64or serialize the events with each other. 65 66The current mechanism works like this: 67 Event thread: 68 - If I'm going to suspend, grab the "I am posting an event" token. Wait 69 for it if it's not currently available. 70 - Post the event to the debugger. 71 - If appropriate, suspend others and then myself. As part of suspending 72 myself, release the "I am posting" token. 73 JDWP thread: 74 - When an event arrives, see if somebody is posting an event. If so, 75 sleep until we can acquire the "I am posting an event" token. Release 76 it immediately and continue processing -- the event we have already 77 received should not interfere with other events that haven't yet 78 been posted. 79 80Some care must be taken to avoid deadlock: 81 82 - thread A and thread B exit near-simultaneously, and post thread-death 83 events with a "suspend all" clause 84 - thread A gets the event token, thread B sits and waits for it 85 - thread A wants to suspend all other threads, but thread B is waiting 86 for the token and can't be suspended 87 88So we need to mark thread B in such a way that thread A doesn't wait for it. 89 90If we just bracket the "grab event token" call with a change to VMWAIT 91before sleeping, the switch back to RUNNING state when we get the token 92will cause thread B to suspend (remember, thread A's global suspend is 93still in force, even after it releases the token). Suspending while 94holding the event token is very bad, because it prevents the JDWP thread 95from processing incoming messages. 96 97We need to change to VMWAIT state at the *start* of posting an event, 98and stay there until we either finish posting the event or decide to 99put ourselves to sleep. That way we don't interfere with anyone else and 100don't allow anyone else to interfere with us. 101*/ 102 103namespace art { 104 105namespace JDWP { 106 107using android::base::StringPrintf; 108 109/* 110 * Stuff to compare against when deciding if a mod matches. Only the 111 * values for mods valid for the event being evaluated will be filled in. 112 * The rest will be zeroed. 113 * Must be allocated on the stack only. This is enforced by removing the 114 * operator new. 115 */ 116struct ModBasket { 117 explicit ModBasket(Thread* self) 118 : hs(self), pLoc(nullptr), thread(self), 119 locationClass(hs.NewHandle<mirror::Class>(nullptr)), 120 exceptionClass(hs.NewHandle<mirror::Class>(nullptr)), 121 caught(false), 122 field(nullptr), 123 thisPtr(hs.NewHandle<mirror::Object>(nullptr)) { } 124 125 StackHandleScope<3> hs; 126 const EventLocation* pLoc; /* LocationOnly */ 127 std::string className; /* ClassMatch/ClassExclude */ 128 Thread* const thread; /* ThreadOnly */ 129 MutableHandle<mirror::Class> locationClass; /* ClassOnly */ 130 MutableHandle<mirror::Class> exceptionClass; /* ExceptionOnly */ 131 bool caught; /* ExceptionOnly */ 132 ArtField* field; /* FieldOnly */ 133 MutableHandle<mirror::Object> thisPtr; /* InstanceOnly */ 134 /* nothing for StepOnly -- handled differently */ 135 136 private: 137 DISALLOW_ALLOCATION(); // forbids allocation on the heap. 138 DISALLOW_IMPLICIT_CONSTRUCTORS(ModBasket); 139}; 140 141static bool NeedsFullDeoptimization(JdwpEventKind eventKind) { 142 if (!Dbg::RequiresDeoptimization()) { 143 // We don't need deoptimization for debugging. 144 return false; 145 } 146 switch (eventKind) { 147 case EK_METHOD_ENTRY: 148 case EK_METHOD_EXIT: 149 case EK_METHOD_EXIT_WITH_RETURN_VALUE: 150 case EK_FIELD_ACCESS: 151 case EK_FIELD_MODIFICATION: 152 return true; 153 default: 154 return false; 155 } 156} 157 158// Returns the instrumentation event the DebugInstrumentationListener must 159// listen to in order to properly report the given JDWP event to the debugger. 160static uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) { 161 switch (eventKind) { 162 case EK_BREAKPOINT: 163 case EK_SINGLE_STEP: 164 return instrumentation::Instrumentation::kDexPcMoved; 165 case EK_EXCEPTION: 166 case EK_EXCEPTION_CATCH: 167 return instrumentation::Instrumentation::kExceptionCaught; 168 case EK_METHOD_ENTRY: 169 return instrumentation::Instrumentation::kMethodEntered; 170 case EK_METHOD_EXIT: 171 case EK_METHOD_EXIT_WITH_RETURN_VALUE: 172 return instrumentation::Instrumentation::kMethodExited; 173 case EK_FIELD_ACCESS: 174 return instrumentation::Instrumentation::kFieldRead; 175 case EK_FIELD_MODIFICATION: 176 return instrumentation::Instrumentation::kFieldWritten; 177 default: 178 return 0; 179 } 180} 181 182/* 183 * Add an event to the list. Ordering is not important. 184 * 185 * If something prevents the event from being registered, e.g. it's a 186 * single-step request on a thread that doesn't exist, the event will 187 * not be added to the list, and an appropriate error will be returned. 188 */ 189JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) { 190 CHECK(pEvent != nullptr); 191 CHECK(pEvent->prev == nullptr); 192 CHECK(pEvent->next == nullptr); 193 194 { 195 /* 196 * If one or more "break"-type mods are used, register them with 197 * the interpreter. 198 */ 199 DeoptimizationRequest req; 200 for (int i = 0; i < pEvent->modCount; i++) { 201 const JdwpEventMod* pMod = &pEvent->mods[i]; 202 if (pMod->modKind == MK_LOCATION_ONLY) { 203 // Should only concern breakpoint, field access, field modification, step, and exception 204 // events. 205 // However breakpoint requires specific handling. Field access, field modification and step 206 // events need full deoptimization to be reported while exception event is reported during 207 // exception handling. 208 if (pEvent->eventKind == EK_BREAKPOINT) { 209 Dbg::WatchLocation(&pMod->locationOnly.loc, &req); 210 } 211 } else if (pMod->modKind == MK_STEP) { 212 /* should only be for EK_SINGLE_STEP; should only be one */ 213 JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size); 214 JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth); 215 JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth); 216 if (status != ERR_NONE) { 217 return status; 218 } 219 } 220 } 221 if (NeedsFullDeoptimization(pEvent->eventKind)) { 222 CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing); 223 CHECK(req.Method() == nullptr); 224 req.SetKind(DeoptimizationRequest::kFullDeoptimization); 225 } 226 Dbg::RequestDeoptimization(req); 227 } 228 uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind); 229 if (instrumentation_event != 0) { 230 DeoptimizationRequest req; 231 req.SetKind(DeoptimizationRequest::kRegisterForEvent); 232 req.SetInstrumentationEvent(instrumentation_event); 233 Dbg::RequestDeoptimization(req); 234 } 235 236 { 237 /* 238 * Add to list. 239 */ 240 MutexLock mu(Thread::Current(), event_list_lock_); 241 if (event_list_ != nullptr) { 242 pEvent->next = event_list_; 243 event_list_->prev = pEvent; 244 } 245 event_list_ = pEvent; 246 ++event_list_size_; 247 } 248 249 Dbg::ManageDeoptimization(); 250 251 return ERR_NONE; 252} 253 254void JdwpState::UnregisterLocationEventsOnClass(ObjPtr<mirror::Class> klass) { 255 VLOG(jdwp) << "Removing events within " << klass->PrettyClass(); 256 StackHandleScope<1> hs(Thread::Current()); 257 Handle<mirror::Class> h_klass(hs.NewHandle(klass)); 258 std::vector<JdwpEvent*> to_remove; 259 MutexLock mu(Thread::Current(), event_list_lock_); 260 for (JdwpEvent* cur_event = event_list_; cur_event != nullptr; cur_event = cur_event->next) { 261 // Fill in the to_remove list 262 bool found_event = false; 263 for (int i = 0; i < cur_event->modCount && !found_event; i++) { 264 JdwpEventMod& mod = cur_event->mods[i]; 265 switch (mod.modKind) { 266 case MK_LOCATION_ONLY: { 267 JdwpLocation& loc = mod.locationOnly.loc; 268 JdwpError error; 269 ObjPtr<mirror::Class> breakpoint_class( 270 Dbg::GetObjectRegistry()->Get<art::mirror::Class*>(loc.class_id, &error)); 271 DCHECK_EQ(error, ERR_NONE); 272 if (breakpoint_class == h_klass.Get()) { 273 to_remove.push_back(cur_event); 274 found_event = true; 275 } 276 break; 277 } 278 default: 279 // TODO Investigate how we should handle non-locationOnly events. 280 break; 281 } 282 } 283 } 284 285 for (JdwpEvent* event : to_remove) { 286 UnregisterEvent(event); 287 EventFree(event); 288 } 289} 290 291/* 292 * Remove an event from the list. This will also remove the event from 293 * any optimization tables, e.g. breakpoints. 294 * 295 * Does not free the JdwpEvent. 296 * 297 * Grab the eventLock before calling here. 298 */ 299void JdwpState::UnregisterEvent(JdwpEvent* pEvent) { 300 if (pEvent->prev == nullptr) { 301 /* head of the list */ 302 CHECK(event_list_ == pEvent); 303 304 event_list_ = pEvent->next; 305 } else { 306 pEvent->prev->next = pEvent->next; 307 } 308 309 if (pEvent->next != nullptr) { 310 pEvent->next->prev = pEvent->prev; 311 pEvent->next = nullptr; 312 } 313 pEvent->prev = nullptr; 314 315 { 316 /* 317 * Unhook us from the interpreter, if necessary. 318 */ 319 DeoptimizationRequest req; 320 for (int i = 0; i < pEvent->modCount; i++) { 321 JdwpEventMod* pMod = &pEvent->mods[i]; 322 if (pMod->modKind == MK_LOCATION_ONLY) { 323 // Like in RegisterEvent, we need specific handling for breakpoint only. 324 if (pEvent->eventKind == EK_BREAKPOINT) { 325 Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req); 326 } 327 } 328 if (pMod->modKind == MK_STEP) { 329 /* should only be for EK_SINGLE_STEP; should only be one */ 330 Dbg::UnconfigureStep(pMod->step.threadId); 331 } 332 } 333 if (NeedsFullDeoptimization(pEvent->eventKind)) { 334 CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing); 335 CHECK(req.Method() == nullptr); 336 req.SetKind(DeoptimizationRequest::kFullUndeoptimization); 337 } 338 Dbg::RequestDeoptimization(req); 339 } 340 uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind); 341 if (instrumentation_event != 0) { 342 DeoptimizationRequest req; 343 req.SetKind(DeoptimizationRequest::kUnregisterForEvent); 344 req.SetInstrumentationEvent(instrumentation_event); 345 Dbg::RequestDeoptimization(req); 346 } 347 348 --event_list_size_; 349 CHECK(event_list_size_ != 0 || event_list_ == nullptr); 350} 351 352/* 353 * Remove the event with the given ID from the list. 354 * 355 */ 356void JdwpState::UnregisterEventById(uint32_t requestId) { 357 bool found = false; 358 { 359 MutexLock mu(Thread::Current(), event_list_lock_); 360 361 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) { 362 if (pEvent->requestId == requestId) { 363 found = true; 364 UnregisterEvent(pEvent); 365 EventFree(pEvent); 366 break; /* there can be only one with a given ID */ 367 } 368 } 369 } 370 371 if (found) { 372 Dbg::ManageDeoptimization(); 373 } else { 374 // Failure to find the event isn't really an error. For instance, it looks like Eclipse will 375 // try to be extra careful and will explicitly remove one-off single-step events (using a 376 // 'count' event modifier of 1). So the event may have already been removed as part of the 377 // event notification (see JdwpState::CleanupMatchList). 378 VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId); 379 } 380} 381 382/* 383 * Remove all entries from the event list. 384 */ 385void JdwpState::UnregisterAll() { 386 MutexLock mu(Thread::Current(), event_list_lock_); 387 388 JdwpEvent* pEvent = event_list_; 389 while (pEvent != nullptr) { 390 JdwpEvent* pNextEvent = pEvent->next; 391 392 UnregisterEvent(pEvent); 393 EventFree(pEvent); 394 pEvent = pNextEvent; 395 } 396 397 event_list_ = nullptr; 398} 399 400/* 401 * Allocate a JdwpEvent struct with enough space to hold the specified 402 * number of mod records. 403 */ 404JdwpEvent* EventAlloc(int numMods) { 405 JdwpEvent* newEvent; 406 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]); 407 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize)); 408 memset(newEvent, 0, allocSize); 409 return newEvent; 410} 411 412/* 413 * Free a JdwpEvent. 414 * 415 * Do not call this until the event has been removed from the list. 416 */ 417void EventFree(JdwpEvent* pEvent) { 418 if (pEvent == nullptr) { 419 return; 420 } 421 422 /* make sure it was removed from the list */ 423 CHECK(pEvent->prev == nullptr); 424 CHECK(pEvent->next == nullptr); 425 /* want to check state->event_list_ != pEvent */ 426 427 /* 428 * Free any hairy bits in the mods. 429 */ 430 for (int i = 0; i < pEvent->modCount; i++) { 431 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) { 432 free(pEvent->mods[i].classMatch.classPattern); 433 pEvent->mods[i].classMatch.classPattern = nullptr; 434 } 435 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) { 436 free(pEvent->mods[i].classExclude.classPattern); 437 pEvent->mods[i].classExclude.classPattern = nullptr; 438 } 439 } 440 441 free(pEvent); 442} 443 444/* 445 * Run through the list and remove any entries with an expired "count" mod 446 * from the event list. 447 */ 448void JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) { 449 for (JdwpEvent* pEvent : match_list) { 450 for (int i = 0; i < pEvent->modCount; ++i) { 451 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) { 452 VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")", 453 pEvent->requestId); 454 UnregisterEvent(pEvent); 455 EventFree(pEvent); 456 break; 457 } 458 } 459 } 460} 461 462/* 463 * Match a string against a "restricted regular expression", which is just 464 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*"). 465 * 466 * ("Restricted name globbing" might have been a better term.) 467 */ 468static bool PatternMatch(const char* pattern, const std::string& target) { 469 size_t patLen = strlen(pattern); 470 if (pattern[0] == '*') { 471 patLen--; 472 if (target.size() < patLen) { 473 return false; 474 } 475 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0; 476 } else if (pattern[patLen-1] == '*') { 477 return strncmp(pattern, target.c_str(), patLen-1) == 0; 478 } else { 479 return strcmp(pattern, target.c_str()) == 0; 480 } 481} 482 483/* 484 * See if the event's mods match up with the contents of "basket". 485 * 486 * If we find a Count mod before rejecting an event, we decrement it. We 487 * need to do this even if later mods cause us to ignore the event. 488 */ 489static bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket) 490 REQUIRES_SHARED(Locks::mutator_lock_) { 491 JdwpEventMod* pMod = pEvent->mods; 492 493 for (int i = pEvent->modCount; i > 0; i--, pMod++) { 494 switch (pMod->modKind) { 495 case MK_COUNT: 496 CHECK_GT(pMod->count.count, 0); 497 pMod->count.count--; 498 if (pMod->count.count > 0) { 499 return false; 500 } 501 break; 502 case MK_CONDITIONAL: 503 CHECK(false); // should not be getting these 504 break; 505 case MK_THREAD_ONLY: 506 if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) { 507 return false; 508 } 509 break; 510 case MK_CLASS_ONLY: 511 if (!Dbg::MatchType(basket.locationClass.Get(), pMod->classOnly.refTypeId)) { 512 return false; 513 } 514 break; 515 case MK_CLASS_MATCH: 516 if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) { 517 return false; 518 } 519 break; 520 case MK_CLASS_EXCLUDE: 521 if (PatternMatch(pMod->classMatch.classPattern, basket.className)) { 522 return false; 523 } 524 break; 525 case MK_LOCATION_ONLY: 526 if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) { 527 return false; 528 } 529 break; 530 case MK_EXCEPTION_ONLY: 531 if (pMod->exceptionOnly.refTypeId != 0 && 532 !Dbg::MatchType(basket.exceptionClass.Get(), pMod->exceptionOnly.refTypeId)) { 533 return false; 534 } 535 if ((basket.caught && !pMod->exceptionOnly.caught) || 536 (!basket.caught && !pMod->exceptionOnly.uncaught)) { 537 return false; 538 } 539 break; 540 case MK_FIELD_ONLY: 541 if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) { 542 return false; 543 } 544 break; 545 case MK_STEP: 546 if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) { 547 return false; 548 } 549 break; 550 case MK_INSTANCE_ONLY: 551 if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr.Get())) { 552 return false; 553 } 554 break; 555 default: 556 LOG(FATAL) << "unknown mod kind " << pMod->modKind; 557 break; 558 } 559 } 560 return true; 561} 562 563/* 564 * Find all events of type "event_kind" with mods that match up with the 565 * rest of the arguments while holding the event list lock. This method 566 * is used by FindMatchingEvents below. 567 * 568 * Found events are appended to "match_list" so this may be called multiple times for grouped 569 * events. 570 * 571 * DO NOT call this multiple times for the same eventKind, as Count mods are 572 * decremented during the scan. 573 */ 574void JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket, 575 std::vector<JdwpEvent*>* match_list) { 576 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) { 577 if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) { 578 match_list->push_back(pEvent); 579 } 580 } 581} 582 583/* 584 * Find all events of type "event_kind" with mods that match up with the 585 * rest of the arguments and return true if at least one event matches, 586 * false otherwise. 587 * 588 * Found events are appended to "match_list" so this may be called multiple 589 * times for grouped events. 590 * 591 * DO NOT call this multiple times for the same eventKind, as Count mods are 592 * decremented during the scan. 593 */ 594bool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket, 595 std::vector<JdwpEvent*>* match_list) { 596 MutexLock mu(Thread::Current(), event_list_lock_); 597 match_list->reserve(event_list_size_); 598 FindMatchingEventsLocked(event_kind, basket, match_list); 599 return !match_list->empty(); 600} 601 602/* 603 * Scan through the list of matches and determine the most severe 604 * suspension policy. 605 */ 606static JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) { 607 JdwpSuspendPolicy policy = SP_NONE; 608 609 for (JdwpEvent* pEvent : match_list) { 610 if (pEvent->suspend_policy > policy) { 611 policy = pEvent->suspend_policy; 612 } 613 } 614 615 return policy; 616} 617 618/* 619 * Three possibilities: 620 * SP_NONE - do nothing 621 * SP_EVENT_THREAD - suspend ourselves 622 * SP_ALL - suspend everybody except JDWP support thread 623 */ 624void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) { 625 VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")"; 626 if (suspend_policy == SP_NONE) { 627 return; 628 } 629 630 if (suspend_policy == SP_ALL) { 631 Dbg::SuspendVM(); 632 } else { 633 CHECK_EQ(suspend_policy, SP_EVENT_THREAD); 634 } 635 636 /* this is rare but possible -- see CLASS_PREPARE handling */ 637 if (thread_self_id == debug_thread_id_) { 638 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread"; 639 return; 640 } 641 642 while (true) { 643 Dbg::SuspendSelf(); 644 645 /* 646 * The JDWP thread has told us (and possibly all other threads) to 647 * resume. See if it has left anything in our DebugInvokeReq mailbox. 648 */ 649 DebugInvokeReq* const pReq = Dbg::GetInvokeReq(); 650 if (pReq == nullptr) { 651 break; 652 } 653 654 // Execute method. 655 Dbg::ExecuteMethod(pReq); 656 } 657} 658 659void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy, 660 ObjectId threadId) { 661 Thread* const self = Thread::Current(); 662 self->AssertThreadSuspensionIsAllowable(); 663 CHECK(pReq != nullptr); 664 CHECK_EQ(threadId, Dbg::GetThreadSelfId()) << "Only the current thread can suspend itself"; 665 /* send request and possibly suspend ourselves */ 666 ScopedThreadSuspension sts(self, kWaitingForDebuggerSend); 667 if (suspend_policy != SP_NONE) { 668 AcquireJdwpTokenForEvent(threadId); 669 } 670 EventFinish(pReq); 671 { 672 // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING. 673 ScopedThreadStateChange stsc(self, kSuspended); 674 SuspendByPolicy(suspend_policy, threadId); 675 } 676} 677 678/* 679 * Determine if there is a method invocation in progress in the current 680 * thread. 681 * 682 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq 683 * state. If set, we're in the process of invoking a method. 684 */ 685bool JdwpState::InvokeInProgress() { 686 DebugInvokeReq* pReq = Dbg::GetInvokeReq(); 687 return pReq != nullptr; 688} 689 690void JdwpState::AcquireJdwpTokenForCommand() { 691 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread"; 692 SetWaitForJdwpToken(debug_thread_id_); 693} 694 695void JdwpState::ReleaseJdwpTokenForCommand() { 696 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread"; 697 ClearWaitForJdwpToken(); 698} 699 700void JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) { 701 SetWaitForJdwpToken(threadId); 702} 703 704void JdwpState::ReleaseJdwpTokenForEvent() { 705 ClearWaitForJdwpToken(); 706} 707 708/* 709 * We need the JDWP thread to hold off on doing stuff while we post an 710 * event and then suspend ourselves. 711 * 712 * This could go to sleep waiting for another thread, so it's important 713 * that the thread be marked as VMWAIT before calling here. 714 */ 715void JdwpState::SetWaitForJdwpToken(ObjectId threadId) { 716 bool waited = false; 717 Thread* const self = Thread::Current(); 718 CHECK_NE(threadId, 0u); 719 CHECK_NE(self->GetState(), kRunnable); 720 Locks::mutator_lock_->AssertNotHeld(self); 721 722 /* this is held for very brief periods; contention is unlikely */ 723 MutexLock mu(self, jdwp_token_lock_); 724 725 if (jdwp_token_owner_thread_id_ == threadId) { 726 // Only the debugger thread may already hold the event token. For instance, it may trigger 727 // a CLASS_PREPARE event while processing a command that initializes a class. 728 CHECK_EQ(threadId, debug_thread_id_) << "Non-debugger thread is already holding event token"; 729 } else { 730 /* 731 * If another thread is already doing stuff, wait for it. This can 732 * go to sleep indefinitely. 733 */ 734 735 while (jdwp_token_owner_thread_id_ != 0) { 736 VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping", 737 jdwp_token_owner_thread_id_, threadId); 738 waited = true; 739 jdwp_token_cond_.Wait(self); 740 } 741 742 if (waited || threadId != debug_thread_id_) { 743 VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId); 744 } 745 jdwp_token_owner_thread_id_ = threadId; 746 } 747} 748 749/* 750 * Clear the threadId and signal anybody waiting. 751 */ 752void JdwpState::ClearWaitForJdwpToken() { 753 /* 754 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this 755 * function is called by Dbg::SuspendSelf(), and the transition back 756 * to RUNNING would confuse it. 757 */ 758 Thread* const self = Thread::Current(); 759 MutexLock mu(self, jdwp_token_lock_); 760 761 CHECK_NE(jdwp_token_owner_thread_id_, 0U); 762 VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_); 763 764 jdwp_token_owner_thread_id_ = 0; 765 jdwp_token_cond_.Signal(self); 766} 767 768/* 769 * Prep an event. Allocates storage for the message and leaves space for 770 * the header. 771 */ 772static ExpandBuf* eventPrep() { 773 ExpandBuf* pReq = expandBufAlloc(); 774 expandBufAddSpace(pReq, kJDWPHeaderLen); 775 return pReq; 776} 777 778/* 779 * Write the header into the buffer and send the packet off to the debugger. 780 * 781 * Takes ownership of "pReq" (currently discards it). 782 */ 783void JdwpState::EventFinish(ExpandBuf* pReq) { 784 uint8_t* buf = expandBufGetBuffer(pReq); 785 786 Set4BE(buf + kJDWPHeaderSizeOffset, expandBufGetLength(pReq)); 787 Set4BE(buf + kJDWPHeaderIdOffset, NextRequestSerial()); 788 Set1(buf + kJDWPHeaderFlagsOffset, 0); /* flags */ 789 Set1(buf + kJDWPHeaderCmdSetOffset, kJDWPEventCmdSet); 790 Set1(buf + kJDWPHeaderCmdOffset, kJDWPEventCompositeCmd); 791 792 SendRequest(pReq); 793 794 expandBufFree(pReq); 795} 796 797 798/* 799 * Tell the debugger that we have finished initializing. This is always 800 * sent, even if the debugger hasn't requested it. 801 * 802 * This should be sent "before the main thread is started and before 803 * any application code has been executed". The thread ID in the message 804 * must be for the main thread. 805 */ 806void JdwpState::PostVMStart() { 807 JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE; 808 ObjectId threadId = Dbg::GetThreadSelfId(); 809 810 VLOG(jdwp) << "EVENT: " << EK_VM_START; 811 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 812 813 ExpandBuf* pReq = eventPrep(); 814 expandBufAdd1(pReq, suspend_policy); 815 expandBufAdd4BE(pReq, 1); 816 expandBufAdd1(pReq, EK_VM_START); 817 expandBufAdd4BE(pReq, 0); /* requestId */ 818 expandBufAddObjectId(pReq, threadId); 819 820 Dbg::ManageDeoptimization(); 821 822 /* send request and possibly suspend ourselves */ 823 SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId); 824} 825 826static void LogMatchingEventsAndThread(const std::vector<JdwpEvent*>& match_list, 827 ObjectId thread_id) 828 REQUIRES_SHARED(Locks::mutator_lock_) { 829 for (size_t i = 0, e = match_list.size(); i < e; ++i) { 830 JdwpEvent* pEvent = match_list[i]; 831 VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind 832 << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId); 833 } 834 std::string thread_name; 835 JdwpError error = Dbg::GetThreadName(thread_id, &thread_name); 836 if (error != JDWP::ERR_NONE) { 837 thread_name = "<unknown>"; 838 } 839 VLOG(jdwp) << StringPrintf(" thread=%#" PRIx64, thread_id) << " " << thread_name; 840} 841 842static void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location, 843 JDWP::JdwpLocation* jdwp_location) 844 REQUIRES_SHARED(Locks::mutator_lock_) { 845 DCHECK(event_location != nullptr); 846 DCHECK(jdwp_location != nullptr); 847 Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc); 848} 849 850/* 851 * A location of interest has been reached. This handles: 852 * Breakpoint 853 * SingleStep 854 * MethodEntry 855 * MethodExit 856 * These four types must be grouped together in a single response. The 857 * "eventFlags" indicates the type of event(s) that have happened. 858 * 859 * Valid mods: 860 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly 861 * LocationOnly (for breakpoint/step only) 862 * Step (for step only) 863 * 864 * Interesting test cases: 865 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY 866 * and METHOD_EXIT events with a ClassOnly mod on the method's class. 867 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1. 868 * - Single-step to a line with a breakpoint. Should get a single 869 * event message with both events in it. 870 */ 871void JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr, 872 int eventFlags, const JValue* returnValue) { 873 DCHECK(pLoc != nullptr); 874 DCHECK(pLoc->method != nullptr); 875 DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr); 876 877 ModBasket basket(Thread::Current()); 878 basket.pLoc = pLoc; 879 basket.locationClass.Assign(pLoc->method->GetDeclaringClass()); 880 basket.thisPtr.Assign(thisPtr); 881 basket.className = Dbg::GetClassName(basket.locationClass.Get()); 882 883 /* 884 * On rare occasions we may need to execute interpreted code in the VM 885 * while handling a request from the debugger. Don't fire breakpoints 886 * while doing so. (I don't think we currently do this at all, so 887 * this is mostly paranoia.) 888 */ 889 if (basket.thread == GetDebugThread()) { 890 VLOG(jdwp) << "Ignoring location event in JDWP thread"; 891 return; 892 } 893 894 /* 895 * The debugger variable display tab may invoke the interpreter to format 896 * complex objects. We want to ignore breakpoints and method entry/exit 897 * traps while working on behalf of the debugger. 898 * 899 * If we don't ignore them, the VM will get hung up, because we'll 900 * suspend on a breakpoint while the debugger is still waiting for its 901 * method invocation to complete. 902 */ 903 if (InvokeInProgress()) { 904 VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")"; 905 return; 906 } 907 908 std::vector<JdwpEvent*> match_list; 909 { 910 // We use the locked version because we have multiple possible match events. 911 MutexLock mu(Thread::Current(), event_list_lock_); 912 match_list.reserve(event_list_size_); 913 if ((eventFlags & Dbg::kBreakpoint) != 0) { 914 FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list); 915 } 916 if ((eventFlags & Dbg::kSingleStep) != 0) { 917 FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list); 918 } 919 if ((eventFlags & Dbg::kMethodEntry) != 0) { 920 FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list); 921 } 922 if ((eventFlags & Dbg::kMethodExit) != 0) { 923 FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list); 924 FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list); 925 } 926 } 927 if (match_list.empty()) { 928 // No matching event. 929 return; 930 } 931 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 932 933 ObjectId thread_id = Dbg::GetThreadId(basket.thread); 934 JDWP::JdwpLocation jdwp_location; 935 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location); 936 937 if (VLOG_IS_ON(jdwp)) { 938 LogMatchingEventsAndThread(match_list, thread_id); 939 VLOG(jdwp) << " location=" << jdwp_location; 940 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 941 } 942 943 ExpandBuf* pReq = eventPrep(); 944 expandBufAdd1(pReq, suspend_policy); 945 expandBufAdd4BE(pReq, match_list.size()); 946 947 for (const JdwpEvent* pEvent : match_list) { 948 expandBufAdd1(pReq, pEvent->eventKind); 949 expandBufAdd4BE(pReq, pEvent->requestId); 950 expandBufAddObjectId(pReq, thread_id); 951 expandBufAddLocation(pReq, jdwp_location); 952 if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) { 953 Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq); 954 } 955 } 956 957 { 958 MutexLock mu(Thread::Current(), event_list_lock_); 959 CleanupMatchList(match_list); 960 } 961 962 Dbg::ManageDeoptimization(); 963 964 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 965} 966 967void JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field, 968 mirror::Object* this_object, const JValue* fieldValue, 969 bool is_modification) { 970 DCHECK(pLoc != nullptr); 971 DCHECK(field != nullptr); 972 DCHECK_EQ(fieldValue != nullptr, is_modification); 973 DCHECK_EQ(field->IsStatic(), this_object == nullptr); 974 975 ModBasket basket(Thread::Current()); 976 basket.pLoc = pLoc; 977 basket.locationClass.Assign(pLoc->method->GetDeclaringClass()); 978 basket.thisPtr.Assign(this_object); 979 basket.className = Dbg::GetClassName(basket.locationClass.Get()); 980 basket.field = field; 981 982 if (InvokeInProgress()) { 983 VLOG(jdwp) << "Not posting field event during invoke (" << basket.className << ")"; 984 return; 985 } 986 987 std::vector<JdwpEvent*> match_list; 988 const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS; 989 if (!FindMatchingEvents(match_kind, basket, &match_list)) { 990 // No matching event. 991 return; 992 } 993 994 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 995 ObjectId thread_id = Dbg::GetThreadId(basket.thread); 996 ObjectRegistry* registry = Dbg::GetObjectRegistry(); 997 ObjectId instance_id = registry->Add(basket.thisPtr); 998 RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass()); 999 FieldId field_id = Dbg::ToFieldId(field); 1000 JDWP::JdwpLocation jdwp_location; 1001 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location); 1002 1003 if (VLOG_IS_ON(jdwp)) { 1004 LogMatchingEventsAndThread(match_list, thread_id); 1005 VLOG(jdwp) << " location=" << jdwp_location; 1006 VLOG(jdwp) << StringPrintf(" this=%#" PRIx64, instance_id); 1007 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, field_type_id) << " " 1008 << Dbg::GetClassName(field_id); 1009 VLOG(jdwp) << StringPrintf(" field=%#" PRIx64, field_id) << " " 1010 << Dbg::GetFieldName(field_id); 1011 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 1012 } 1013 1014 ExpandBuf* pReq = eventPrep(); 1015 expandBufAdd1(pReq, suspend_policy); 1016 expandBufAdd4BE(pReq, match_list.size()); 1017 1018 // Get field's reference type tag. 1019 JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass()); 1020 1021 // Get instance type tag. 1022 uint8_t tag; 1023 { 1024 ScopedObjectAccessUnchecked soa(Thread::Current()); 1025 tag = Dbg::TagFromObject(soa, basket.thisPtr.Get()); 1026 } 1027 1028 for (const JdwpEvent* pEvent : match_list) { 1029 expandBufAdd1(pReq, pEvent->eventKind); 1030 expandBufAdd4BE(pReq, pEvent->requestId); 1031 expandBufAddObjectId(pReq, thread_id); 1032 expandBufAddLocation(pReq, jdwp_location); 1033 expandBufAdd1(pReq, type_tag); 1034 expandBufAddRefTypeId(pReq, field_type_id); 1035 expandBufAddFieldId(pReq, field_id); 1036 expandBufAdd1(pReq, tag); 1037 expandBufAddObjectId(pReq, instance_id); 1038 if (is_modification) { 1039 Dbg::OutputFieldValue(field_id, fieldValue, pReq); 1040 } 1041 } 1042 1043 { 1044 MutexLock mu(Thread::Current(), event_list_lock_); 1045 CleanupMatchList(match_list); 1046 } 1047 1048 Dbg::ManageDeoptimization(); 1049 1050 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1051} 1052 1053/* 1054 * A thread is starting or stopping. 1055 * 1056 * Valid mods: 1057 * Count, ThreadOnly 1058 */ 1059void JdwpState::PostThreadChange(Thread* thread, bool start) { 1060 CHECK_EQ(thread, Thread::Current()); 1061 1062 /* 1063 * I don't think this can happen. 1064 */ 1065 if (InvokeInProgress()) { 1066 LOG(WARNING) << "Not posting thread change during invoke"; 1067 return; 1068 } 1069 1070 // We need the java.lang.Thread object associated to the starting/ending 1071 // thread to get its JDWP id. Therefore we can't report event if there 1072 // is no Java peer. This happens when the runtime shuts down and re-attaches 1073 // the current thread without creating a Java peer. 1074 if (thread->GetPeer() == nullptr) { 1075 return; 1076 } 1077 1078 ModBasket basket(thread); 1079 1080 std::vector<JdwpEvent*> match_list; 1081 const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH; 1082 if (!FindMatchingEvents(match_kind, basket, &match_list)) { 1083 // No matching event. 1084 return; 1085 } 1086 1087 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 1088 ObjectId thread_id = Dbg::GetThreadId(basket.thread); 1089 1090 if (VLOG_IS_ON(jdwp)) { 1091 LogMatchingEventsAndThread(match_list, thread_id); 1092 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 1093 } 1094 1095 ExpandBuf* pReq = eventPrep(); 1096 expandBufAdd1(pReq, suspend_policy); 1097 expandBufAdd4BE(pReq, match_list.size()); 1098 1099 for (const JdwpEvent* pEvent : match_list) { 1100 expandBufAdd1(pReq, pEvent->eventKind); 1101 expandBufAdd4BE(pReq, pEvent->requestId); 1102 expandBufAdd8BE(pReq, thread_id); 1103 } 1104 1105 { 1106 MutexLock mu(Thread::Current(), event_list_lock_); 1107 CleanupMatchList(match_list); 1108 } 1109 1110 Dbg::ManageDeoptimization(); 1111 1112 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1113} 1114 1115/* 1116 * Send a polite "VM is dying" message to the debugger. 1117 * 1118 * Skips the usual "event token" stuff. 1119 */ 1120bool JdwpState::PostVMDeath() { 1121 VLOG(jdwp) << "EVENT: " << EK_VM_DEATH; 1122 1123 ExpandBuf* pReq = eventPrep(); 1124 expandBufAdd1(pReq, SP_NONE); 1125 expandBufAdd4BE(pReq, 1); 1126 1127 expandBufAdd1(pReq, EK_VM_DEATH); 1128 expandBufAdd4BE(pReq, 0); 1129 EventFinish(pReq); 1130 return true; 1131} 1132 1133/* 1134 * An exception has been thrown. It may or may not have been caught. 1135 * 1136 * Valid mods: 1137 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly, 1138 * ExceptionOnly, InstanceOnly 1139 * 1140 * The "exceptionId" has not been added to the GC-visible object registry, 1141 * because there's a pretty good chance that we're not going to send it 1142 * up the debugger. 1143 */ 1144void JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object, 1145 const EventLocation* pCatchLoc, mirror::Object* thisPtr) { 1146 DCHECK(exception_object != nullptr); 1147 DCHECK(pThrowLoc != nullptr); 1148 DCHECK(pCatchLoc != nullptr); 1149 if (pThrowLoc->method != nullptr) { 1150 DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr); 1151 } else { 1152 VLOG(jdwp) << "Unexpected: exception event with empty throw location"; 1153 } 1154 1155 ModBasket basket(Thread::Current()); 1156 basket.pLoc = pThrowLoc; 1157 if (pThrowLoc->method != nullptr) { 1158 basket.locationClass.Assign(pThrowLoc->method->GetDeclaringClass()); 1159 } 1160 basket.className = Dbg::GetClassName(basket.locationClass.Get()); 1161 basket.exceptionClass.Assign(exception_object->GetClass()); 1162 basket.caught = (pCatchLoc->method != 0); 1163 basket.thisPtr.Assign(thisPtr); 1164 1165 /* don't try to post an exception caused by the debugger */ 1166 if (InvokeInProgress()) { 1167 VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")"; 1168 return; 1169 } 1170 1171 std::vector<JdwpEvent*> match_list; 1172 if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) { 1173 // No matching event. 1174 return; 1175 } 1176 1177 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 1178 ObjectId thread_id = Dbg::GetThreadId(basket.thread); 1179 ObjectRegistry* registry = Dbg::GetObjectRegistry(); 1180 ObjectId exceptionId = registry->Add(exception_object); 1181 JDWP::JdwpLocation jdwp_throw_location; 1182 JDWP::JdwpLocation jdwp_catch_location; 1183 SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location); 1184 SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location); 1185 1186 if (VLOG_IS_ON(jdwp)) { 1187 std::string exceptionClassName(mirror::Class::PrettyDescriptor(exception_object->GetClass())); 1188 1189 LogMatchingEventsAndThread(match_list, thread_id); 1190 VLOG(jdwp) << " throwLocation=" << jdwp_throw_location; 1191 if (jdwp_catch_location.class_id == 0) { 1192 VLOG(jdwp) << " catchLocation=uncaught"; 1193 } else { 1194 VLOG(jdwp) << " catchLocation=" << jdwp_catch_location; 1195 } 1196 VLOG(jdwp) << StringPrintf(" exception=%#" PRIx64, exceptionId) << " " 1197 << exceptionClassName; 1198 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 1199 } 1200 1201 ExpandBuf* pReq = eventPrep(); 1202 expandBufAdd1(pReq, suspend_policy); 1203 expandBufAdd4BE(pReq, match_list.size()); 1204 1205 for (const JdwpEvent* pEvent : match_list) { 1206 expandBufAdd1(pReq, pEvent->eventKind); 1207 expandBufAdd4BE(pReq, pEvent->requestId); 1208 expandBufAddObjectId(pReq, thread_id); 1209 expandBufAddLocation(pReq, jdwp_throw_location); 1210 expandBufAdd1(pReq, JT_OBJECT); 1211 expandBufAddObjectId(pReq, exceptionId); 1212 expandBufAddLocation(pReq, jdwp_catch_location); 1213 } 1214 1215 { 1216 MutexLock mu(Thread::Current(), event_list_lock_); 1217 CleanupMatchList(match_list); 1218 } 1219 1220 Dbg::ManageDeoptimization(); 1221 1222 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1223} 1224 1225/* 1226 * Announce that a class has been loaded. 1227 * 1228 * Valid mods: 1229 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude 1230 */ 1231void JdwpState::PostClassPrepare(mirror::Class* klass) { 1232 DCHECK(klass != nullptr); 1233 1234 ModBasket basket(Thread::Current()); 1235 basket.locationClass.Assign(klass); 1236 basket.className = Dbg::GetClassName(basket.locationClass.Get()); 1237 1238 /* suppress class prep caused by debugger */ 1239 if (InvokeInProgress()) { 1240 VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")"; 1241 return; 1242 } 1243 1244 std::vector<JdwpEvent*> match_list; 1245 if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) { 1246 // No matching event. 1247 return; 1248 } 1249 1250 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 1251 ObjectId thread_id = Dbg::GetThreadId(basket.thread); 1252 ObjectRegistry* registry = Dbg::GetObjectRegistry(); 1253 RefTypeId class_id = registry->AddRefType(basket.locationClass); 1254 1255 // OLD-TODO - we currently always send both "verified" and "prepared" since 1256 // debuggers seem to like that. There might be some advantage to honesty, 1257 // since the class may not yet be verified. 1258 int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED; 1259 JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass.Get()); 1260 std::string temp; 1261 std::string signature(basket.locationClass->GetDescriptor(&temp)); 1262 1263 if (VLOG_IS_ON(jdwp)) { 1264 LogMatchingEventsAndThread(match_list, thread_id); 1265 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, class_id) << " " << signature; 1266 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 1267 } 1268 1269 ObjectId reported_thread_id = thread_id; 1270 if (reported_thread_id == debug_thread_id_) { 1271 /* 1272 * JDWP says that, for a class prep in the debugger thread, we 1273 * should set thread to null and if any threads were supposed 1274 * to be suspended then we suspend all other threads. 1275 */ 1276 VLOG(jdwp) << " NOTE: class prepare in debugger thread!"; 1277 reported_thread_id = 0; 1278 if (suspend_policy == SP_EVENT_THREAD) { 1279 suspend_policy = SP_ALL; 1280 } 1281 } 1282 1283 ExpandBuf* pReq = eventPrep(); 1284 expandBufAdd1(pReq, suspend_policy); 1285 expandBufAdd4BE(pReq, match_list.size()); 1286 1287 for (const JdwpEvent* pEvent : match_list) { 1288 expandBufAdd1(pReq, pEvent->eventKind); 1289 expandBufAdd4BE(pReq, pEvent->requestId); 1290 expandBufAddObjectId(pReq, reported_thread_id); 1291 expandBufAdd1(pReq, tag); 1292 expandBufAddRefTypeId(pReq, class_id); 1293 expandBufAddUtf8String(pReq, signature); 1294 expandBufAdd4BE(pReq, status); 1295 } 1296 1297 { 1298 MutexLock mu(Thread::Current(), event_list_lock_); 1299 CleanupMatchList(match_list); 1300 } 1301 1302 Dbg::ManageDeoptimization(); 1303 1304 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1305} 1306 1307/* 1308 * Setup the header for a chunk of DDM data. 1309 */ 1310void JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size, 1311 uint8_t* out_header) { 1312 CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8)); 1313 /* form the header (JDWP plus DDMS) */ 1314 Set4BE(out_header, header_size + data_len); 1315 Set4BE(out_header + 4, NextRequestSerial()); 1316 Set1(out_header + 8, 0); /* flags */ 1317 Set1(out_header + 9, kJDWPDdmCmdSet); 1318 Set1(out_header + 10, kJDWPDdmCmd); 1319 Set4BE(out_header + 11, type); 1320 Set4BE(out_header + 15, data_len); 1321} 1322 1323/* 1324 * Send up a chunk of DDM data. 1325 * 1326 * While this takes the form of a JDWP "event", it doesn't interact with 1327 * other debugger traffic, and can't suspend the VM, so we skip all of 1328 * the fun event token gymnastics. 1329 */ 1330void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) { 1331 uint8_t header[kJDWPHeaderLen + 8] = { 0 }; 1332 size_t dataLen = 0; 1333 1334 CHECK(iov != nullptr); 1335 CHECK_GT(iov_count, 0); 1336 CHECK_LT(iov_count, 10); 1337 1338 /* 1339 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do 1340 * this by creating a new copy of the vector with space for the header. 1341 */ 1342 std::vector<iovec> wrapiov; 1343 wrapiov.push_back(iovec()); 1344 for (int i = 0; i < iov_count; i++) { 1345 wrapiov.push_back(iov[i]); 1346 dataLen += iov[i].iov_len; 1347 } 1348 1349 SetupChunkHeader(type, dataLen, sizeof(header), header); 1350 1351 wrapiov[0].iov_base = header; 1352 wrapiov[0].iov_len = sizeof(header); 1353 1354 // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level 1355 // than mutator for lock ordering reasons. 1356 Thread* self = Thread::Current(); 1357 bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self); 1358 if (safe_to_release_mutator_lock_over_send) { 1359 for (size_t i = 0; i < kMutatorLock; ++i) { 1360 if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) { 1361 safe_to_release_mutator_lock_over_send = false; 1362 break; 1363 } 1364 } 1365 } 1366 if (safe_to_release_mutator_lock_over_send) { 1367 // Change state to waiting to allow GC, ... while we're sending. 1368 ScopedThreadSuspension sts(self, kWaitingForDebuggerSend); 1369 SendBufferedRequest(type, wrapiov); 1370 } else { 1371 // Send and possibly block GC... 1372 SendBufferedRequest(type, wrapiov); 1373 } 1374} 1375 1376} // namespace JDWP 1377 1378} // namespace art 1379