jdwp_event.cc revision 4d25df3f76f864b7629ac8c0046d46997f293d8d
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 "base/logging.h" 25#include "base/stringprintf.h" 26#include "debugger.h" 27#include "jdwp/jdwp_constants.h" 28#include "jdwp/jdwp_expand_buf.h" 29#include "jdwp/jdwp_priv.h" 30#include "thread-inl.h" 31 32/* 33General notes: 34 35The event add/remove stuff usually happens from the debugger thread, 36in response to requests from the debugger, but can also happen as the 37result of an event in an arbitrary thread (e.g. an event with a "count" 38mod expires). It's important to keep the event list locked when processing 39events. 40 41Event posting can happen from any thread. The JDWP thread will not usually 42post anything but VM start/death, but if a JDWP request causes a class 43to be loaded, the ClassPrepare event will come from the JDWP thread. 44 45 46We can have serialization issues when we post an event to the debugger. 47For example, a thread could send an "I hit a breakpoint and am suspending 48myself" message to the debugger. Before it manages to suspend itself, the 49debugger's response ("not interested, resume thread") arrives and is 50processed. We try to resume a thread that hasn't yet suspended. 51 52This means that, after posting an event to the debugger, we need to wait 53for the event thread to suspend itself (and, potentially, all other threads) 54before processing any additional requests from the debugger. While doing 55so we need to be aware that multiple threads may be hitting breakpoints 56or other events simultaneously, so we either need to wait for all of them 57or serialize the events with each other. 58 59The current mechanism works like this: 60 Event thread: 61 - If I'm going to suspend, grab the "I am posting an event" token. Wait 62 for it if it's not currently available. 63 - Post the event to the debugger. 64 - If appropriate, suspend others and then myself. As part of suspending 65 myself, release the "I am posting" token. 66 JDWP thread: 67 - When an event arrives, see if somebody is posting an event. If so, 68 sleep until we can acquire the "I am posting an event" token. Release 69 it immediately and continue processing -- the event we have already 70 received should not interfere with other events that haven't yet 71 been posted. 72 73Some care must be taken to avoid deadlock: 74 75 - thread A and thread B exit near-simultaneously, and post thread-death 76 events with a "suspend all" clause 77 - thread A gets the event token, thread B sits and waits for it 78 - thread A wants to suspend all other threads, but thread B is waiting 79 for the token and can't be suspended 80 81So we need to mark thread B in such a way that thread A doesn't wait for it. 82 83If we just bracket the "grab event token" call with a change to VMWAIT 84before sleeping, the switch back to RUNNING state when we get the token 85will cause thread B to suspend (remember, thread A's global suspend is 86still in force, even after it releases the token). Suspending while 87holding the event token is very bad, because it prevents the JDWP thread 88from processing incoming messages. 89 90We need to change to VMWAIT state at the *start* of posting an event, 91and stay there until we either finish posting the event or decide to 92put ourselves to sleep. That way we don't interfere with anyone else and 93don't allow anyone else to interfere with us. 94*/ 95 96 97#define kJdwpEventCommandSet 64 98#define kJdwpCompositeCommand 100 99 100namespace art { 101 102namespace JDWP { 103 104/* 105 * Stuff to compare against when deciding if a mod matches. Only the 106 * values for mods valid for the event being evaluated will be filled in. 107 * The rest will be zeroed. 108 */ 109struct ModBasket { 110 ModBasket() : pLoc(NULL), threadId(0), classId(0), excepClassId(0), 111 caught(false), field(0), thisPtr(0) { } 112 113 const JdwpLocation* pLoc; /* LocationOnly */ 114 std::string className; /* ClassMatch/ClassExclude */ 115 ObjectId threadId; /* ThreadOnly */ 116 RefTypeId classId; /* ClassOnly */ 117 RefTypeId excepClassId; /* ExceptionOnly */ 118 bool caught; /* ExceptionOnly */ 119 FieldId field; /* FieldOnly */ 120 ObjectId thisPtr; /* InstanceOnly */ 121 /* nothing for StepOnly -- handled differently */ 122}; 123 124/* 125 * Dump an event to the log file. 126 */ 127static void dumpEvent(const JdwpEvent* pEvent) { 128 LOG(INFO) << StringPrintf("Event id=0x%4x %p (prev=%p next=%p):", pEvent->requestId, pEvent, pEvent->prev, pEvent->next); 129 LOG(INFO) << " kind=" << pEvent->eventKind << " susp=" << pEvent->suspend_policy << " modCount=" << pEvent->modCount; 130 131 for (int i = 0; i < pEvent->modCount; i++) { 132 const JdwpEventMod* pMod = &pEvent->mods[i]; 133 LOG(INFO) << " " << pMod->modKind; 134 /* TODO - show details */ 135 } 136} 137 138static bool NeedsFullDeoptimization(JdwpEventKind eventKind) { 139 switch (eventKind) { 140 case EK_METHOD_ENTRY: 141 case EK_METHOD_EXIT: 142 case EK_METHOD_EXIT_WITH_RETURN_VALUE: 143 case EK_SINGLE_STEP: 144 return true; 145 default: 146 return false; 147 } 148} 149 150/* 151 * Add an event to the list. Ordering is not important. 152 * 153 * If something prevents the event from being registered, e.g. it's a 154 * single-step request on a thread that doesn't exist, the event will 155 * not be added to the list, and an appropriate error will be returned. 156 */ 157JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) { 158 CHECK(pEvent != NULL); 159 CHECK(pEvent->prev == NULL); 160 CHECK(pEvent->next == NULL); 161 162 /* 163 * If one or more "break"-type mods are used, register them with 164 * the interpreter. 165 */ 166 DeoptimizationRequest req; 167 for (int i = 0; i < pEvent->modCount; i++) { 168 const JdwpEventMod* pMod = &pEvent->mods[i]; 169 if (pMod->modKind == MK_LOCATION_ONLY) { 170 /* should only be for Breakpoint, Step, and Exception */ 171 Dbg::WatchLocation(&pMod->locationOnly.loc, &req); 172 } else if (pMod->modKind == MK_STEP) { 173 /* should only be for EK_SINGLE_STEP; should only be one */ 174 JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size); 175 JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth); 176 JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth); 177 if (status != ERR_NONE) { 178 return status; 179 } 180 } else if (pMod->modKind == MK_FIELD_ONLY) { 181 /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */ 182 dumpEvent(pEvent); /* TODO - need for field watches */ 183 } 184 } 185 if (NeedsFullDeoptimization(pEvent->eventKind)) { 186 CHECK_EQ(req.kind, DeoptimizationRequest::kNothing); 187 CHECK(req.method == nullptr); 188 req.kind = DeoptimizationRequest::kFullDeoptimization; 189 } 190 191 { 192 /* 193 * Add to list. 194 */ 195 MutexLock mu(Thread::Current(), event_list_lock_); 196 if (event_list_ != NULL) { 197 pEvent->next = event_list_; 198 event_list_->prev = pEvent; 199 } 200 event_list_ = pEvent; 201 ++event_list_size_; 202 } 203 204 // TODO we can do better job here since we should process only one request: the one we just 205 // created. 206 Dbg::RequestDeoptimization(req); 207 Dbg::ManageDeoptimization(); 208 209 return ERR_NONE; 210} 211 212/* 213 * Remove an event from the list. This will also remove the event from 214 * any optimization tables, e.g. breakpoints. 215 * 216 * Does not free the JdwpEvent. 217 * 218 * Grab the eventLock before calling here. 219 */ 220void JdwpState::UnregisterEvent(JdwpEvent* pEvent) { 221 if (pEvent->prev == NULL) { 222 /* head of the list */ 223 CHECK(event_list_ == pEvent); 224 225 event_list_ = pEvent->next; 226 } else { 227 pEvent->prev->next = pEvent->next; 228 } 229 230 if (pEvent->next != NULL) { 231 pEvent->next->prev = pEvent->prev; 232 pEvent->next = NULL; 233 } 234 pEvent->prev = NULL; 235 236 /* 237 * Unhook us from the interpreter, if necessary. 238 */ 239 DeoptimizationRequest req; 240 for (int i = 0; i < pEvent->modCount; i++) { 241 JdwpEventMod* pMod = &pEvent->mods[i]; 242 if (pMod->modKind == MK_LOCATION_ONLY) { 243 /* should only be for Breakpoint, Step, and Exception */ 244 Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req); 245 } 246 if (pMod->modKind == MK_STEP) { 247 /* should only be for EK_SINGLE_STEP; should only be one */ 248 Dbg::UnconfigureStep(pMod->step.threadId); 249 } 250 } 251 if (NeedsFullDeoptimization(pEvent->eventKind)) { 252 CHECK_EQ(req.kind, DeoptimizationRequest::kNothing); 253 CHECK(req.method == nullptr); 254 req.kind = DeoptimizationRequest::kFullUndeoptimization; 255 } 256 257 --event_list_size_; 258 CHECK(event_list_size_ != 0 || event_list_ == NULL); 259 260 Dbg::RequestDeoptimization(req); 261} 262 263/* 264 * Remove the event with the given ID from the list. 265 * 266 * Failure to find the event isn't really an error, but it is a little 267 * weird. (It looks like Eclipse will try to be extra careful and will 268 * explicitly remove one-off single-step events.) 269 */ 270void JdwpState::UnregisterEventById(uint32_t requestId) { 271 bool found = false; 272 { 273 MutexLock mu(Thread::Current(), event_list_lock_); 274 275 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) { 276 if (pEvent->requestId == requestId) { 277 found = true; 278 UnregisterEvent(pEvent); 279 EventFree(pEvent); 280 break; /* there can be only one with a given ID */ 281 } 282 } 283 } 284 285 if (found) { 286 Dbg::ManageDeoptimization(); 287 } else { 288 LOG(DEBUG) << StringPrintf("Odd: no match when removing event reqId=0x%04x", requestId); 289 } 290} 291 292/* 293 * Remove all entries from the event list. 294 */ 295void JdwpState::UnregisterAll() { 296 MutexLock mu(Thread::Current(), event_list_lock_); 297 298 JdwpEvent* pEvent = event_list_; 299 while (pEvent != NULL) { 300 JdwpEvent* pNextEvent = pEvent->next; 301 302 UnregisterEvent(pEvent); 303 EventFree(pEvent); 304 pEvent = pNextEvent; 305 } 306 307 event_list_ = NULL; 308} 309 310/* 311 * Allocate a JdwpEvent struct with enough space to hold the specified 312 * number of mod records. 313 */ 314JdwpEvent* EventAlloc(int numMods) { 315 JdwpEvent* newEvent; 316 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]); 317 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize)); 318 memset(newEvent, 0, allocSize); 319 return newEvent; 320} 321 322/* 323 * Free a JdwpEvent. 324 * 325 * Do not call this until the event has been removed from the list. 326 */ 327void EventFree(JdwpEvent* pEvent) { 328 if (pEvent == NULL) { 329 return; 330 } 331 332 /* make sure it was removed from the list */ 333 CHECK(pEvent->prev == NULL); 334 CHECK(pEvent->next == NULL); 335 /* want to check state->event_list_ != pEvent */ 336 337 /* 338 * Free any hairy bits in the mods. 339 */ 340 for (int i = 0; i < pEvent->modCount; i++) { 341 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) { 342 free(pEvent->mods[i].classMatch.classPattern); 343 pEvent->mods[i].classMatch.classPattern = NULL; 344 } 345 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) { 346 free(pEvent->mods[i].classExclude.classPattern); 347 pEvent->mods[i].classExclude.classPattern = NULL; 348 } 349 } 350 351 free(pEvent); 352} 353 354/* 355 * Allocate storage for matching events. To keep things simple we 356 * use an array with enough storage for the entire list. 357 * 358 * The state->eventLock should be held before calling. 359 */ 360static JdwpEvent** AllocMatchList(size_t event_count) { 361 return new JdwpEvent*[event_count]; 362} 363 364/* 365 * Run through the list and remove any entries with an expired "count" mod 366 * from the event list, then free the match list. 367 */ 368void JdwpState::CleanupMatchList(JdwpEvent** match_list, int match_count) { 369 JdwpEvent** ppEvent = match_list; 370 371 while (match_count--) { 372 JdwpEvent* pEvent = *ppEvent; 373 374 for (int i = 0; i < pEvent->modCount; i++) { 375 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) { 376 VLOG(jdwp) << "##### Removing expired event"; 377 UnregisterEvent(pEvent); 378 EventFree(pEvent); 379 break; 380 } 381 } 382 383 ppEvent++; 384 } 385 386 delete[] match_list; 387} 388 389/* 390 * Match a string against a "restricted regular expression", which is just 391 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*"). 392 * 393 * ("Restricted name globbing" might have been a better term.) 394 */ 395static bool PatternMatch(const char* pattern, const std::string& target) { 396 size_t patLen = strlen(pattern); 397 if (pattern[0] == '*') { 398 patLen--; 399 if (target.size() < patLen) { 400 return false; 401 } 402 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0; 403 } else if (pattern[patLen-1] == '*') { 404 return strncmp(pattern, target.c_str(), patLen-1) == 0; 405 } else { 406 return strcmp(pattern, target.c_str()) == 0; 407 } 408} 409 410/* 411 * See if the event's mods match up with the contents of "basket". 412 * 413 * If we find a Count mod before rejecting an event, we decrement it. We 414 * need to do this even if later mods cause us to ignore the event. 415 */ 416static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket) 417 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 418 JdwpEventMod* pMod = pEvent->mods; 419 420 for (int i = pEvent->modCount; i > 0; i--, pMod++) { 421 switch (pMod->modKind) { 422 case MK_COUNT: 423 CHECK_GT(pMod->count.count, 0); 424 pMod->count.count--; 425 break; 426 case MK_CONDITIONAL: 427 CHECK(false); // should not be getting these 428 break; 429 case MK_THREAD_ONLY: 430 if (pMod->threadOnly.threadId != basket->threadId) { 431 return false; 432 } 433 break; 434 case MK_CLASS_ONLY: 435 if (!Dbg::MatchType(basket->classId, pMod->classOnly.refTypeId)) { 436 return false; 437 } 438 break; 439 case MK_CLASS_MATCH: 440 if (!PatternMatch(pMod->classMatch.classPattern, basket->className)) { 441 return false; 442 } 443 break; 444 case MK_CLASS_EXCLUDE: 445 if (PatternMatch(pMod->classMatch.classPattern, basket->className)) { 446 return false; 447 } 448 break; 449 case MK_LOCATION_ONLY: 450 if (pMod->locationOnly.loc != *basket->pLoc) { 451 return false; 452 } 453 break; 454 case MK_EXCEPTION_ONLY: 455 if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket->excepClassId, pMod->exceptionOnly.refTypeId)) { 456 return false; 457 } 458 if ((basket->caught && !pMod->exceptionOnly.caught) || (!basket->caught && !pMod->exceptionOnly.uncaught)) { 459 return false; 460 } 461 break; 462 case MK_FIELD_ONLY: 463 if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) { 464 return false; 465 } 466 break; 467 case MK_STEP: 468 if (pMod->step.threadId != basket->threadId) { 469 return false; 470 } 471 break; 472 case MK_INSTANCE_ONLY: 473 if (pMod->instanceOnly.objectId != basket->thisPtr) { 474 return false; 475 } 476 break; 477 default: 478 LOG(FATAL) << "unknown mod kind " << pMod->modKind; 479 break; 480 } 481 } 482 return true; 483} 484 485/* 486 * Find all events of type "eventKind" with mods that match up with the 487 * rest of the arguments. 488 * 489 * Found events are appended to "match_list", and "*pMatchCount" is advanced, 490 * so this may be called multiple times for grouped events. 491 * 492 * DO NOT call this multiple times for the same eventKind, as Count mods are 493 * decremented during the scan. 494 */ 495void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, ModBasket* basket, 496 JdwpEvent** match_list, int* pMatchCount) { 497 /* start after the existing entries */ 498 match_list += *pMatchCount; 499 500 JdwpEvent* pEvent = event_list_; 501 while (pEvent != NULL) { 502 if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) { 503 *match_list++ = pEvent; 504 (*pMatchCount)++; 505 } 506 507 pEvent = pEvent->next; 508 } 509} 510 511/* 512 * Scan through the list of matches and determine the most severe 513 * suspension policy. 514 */ 515static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) { 516 JdwpSuspendPolicy policy = SP_NONE; 517 518 while (match_count--) { 519 if ((*match_list)->suspend_policy > policy) { 520 policy = (*match_list)->suspend_policy; 521 } 522 match_list++; 523 } 524 525 return policy; 526} 527 528/* 529 * Three possibilities: 530 * SP_NONE - do nothing 531 * SP_EVENT_THREAD - suspend ourselves 532 * SP_ALL - suspend everybody except JDWP support thread 533 */ 534void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) { 535 VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")"; 536 if (suspend_policy == SP_NONE) { 537 return; 538 } 539 540 if (suspend_policy == SP_ALL) { 541 Dbg::SuspendVM(); 542 } else { 543 CHECK_EQ(suspend_policy, SP_EVENT_THREAD); 544 } 545 546 /* this is rare but possible -- see CLASS_PREPARE handling */ 547 if (thread_self_id == debug_thread_id_) { 548 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread"; 549 return; 550 } 551 552 DebugInvokeReq* pReq = Dbg::GetInvokeReq(); 553 while (true) { 554 pReq->ready = true; 555 Dbg::SuspendSelf(); 556 pReq->ready = false; 557 558 /* 559 * The JDWP thread has told us (and possibly all other threads) to 560 * resume. See if it has left anything in our DebugInvokeReq mailbox. 561 */ 562 if (!pReq->invoke_needed) { 563 /*LOGD("SuspendByPolicy: no invoke needed");*/ 564 break; 565 } 566 567 /* grab this before posting/suspending again */ 568 SetWaitForEventThread(thread_self_id); 569 570 /* leave pReq->invoke_needed_ raised so we can check reentrancy */ 571 Dbg::ExecuteMethod(pReq); 572 573 pReq->error = ERR_NONE; 574 } 575} 576 577void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy, 578 ObjectId threadId) { 579 Thread* self = Thread::Current(); 580 self->AssertThreadSuspensionIsAllowable(); 581 /* send request and possibly suspend ourselves */ 582 if (pReq != NULL) { 583 JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId(); 584 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend); 585 if (suspend_policy != SP_NONE) { 586 SetWaitForEventThread(threadId); 587 } 588 EventFinish(pReq); 589 SuspendByPolicy(suspend_policy, thread_self_id); 590 self->TransitionFromSuspendedToRunnable(); 591 } 592} 593 594/* 595 * Determine if there is a method invocation in progress in the current 596 * thread. 597 * 598 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq 599 * state. If set, we're in the process of invoking a method. 600 */ 601bool JdwpState::InvokeInProgress() { 602 DebugInvokeReq* pReq = Dbg::GetInvokeReq(); 603 return pReq->invoke_needed; 604} 605 606/* 607 * We need the JDWP thread to hold off on doing stuff while we post an 608 * event and then suspend ourselves. 609 * 610 * Call this with a threadId of zero if you just want to wait for the 611 * current thread operation to complete. 612 * 613 * This could go to sleep waiting for another thread, so it's important 614 * that the thread be marked as VMWAIT before calling here. 615 */ 616void JdwpState::SetWaitForEventThread(ObjectId threadId) { 617 bool waited = false; 618 619 /* this is held for very brief periods; contention is unlikely */ 620 Thread* self = Thread::Current(); 621 MutexLock mu(self, event_thread_lock_); 622 623 /* 624 * If another thread is already doing stuff, wait for it. This can 625 * go to sleep indefinitely. 626 */ 627 while (event_thread_id_ != 0) { 628 VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping", 629 event_thread_id_, threadId); 630 waited = true; 631 event_thread_cond_.Wait(self); 632 } 633 634 if (waited || threadId != 0) { 635 VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId); 636 } 637 if (threadId != 0) { 638 event_thread_id_ = threadId; 639 } 640} 641 642/* 643 * Clear the threadId and signal anybody waiting. 644 */ 645void JdwpState::ClearWaitForEventThread() { 646 /* 647 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this 648 * function is called by dvmSuspendSelf(), and the transition back 649 * to RUNNING would confuse it. 650 */ 651 Thread* self = Thread::Current(); 652 MutexLock mu(self, event_thread_lock_); 653 654 CHECK_NE(event_thread_id_, 0U); 655 VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", event_thread_id_); 656 657 event_thread_id_ = 0; 658 659 event_thread_cond_.Signal(self); 660} 661 662 663/* 664 * Prep an event. Allocates storage for the message and leaves space for 665 * the header. 666 */ 667static ExpandBuf* eventPrep() { 668 ExpandBuf* pReq = expandBufAlloc(); 669 expandBufAddSpace(pReq, kJDWPHeaderLen); 670 return pReq; 671} 672 673/* 674 * Write the header into the buffer and send the packet off to the debugger. 675 * 676 * Takes ownership of "pReq" (currently discards it). 677 */ 678void JdwpState::EventFinish(ExpandBuf* pReq) { 679 uint8_t* buf = expandBufGetBuffer(pReq); 680 681 Set4BE(buf, expandBufGetLength(pReq)); 682 Set4BE(buf+4, NextRequestSerial()); 683 Set1(buf+8, 0); /* flags */ 684 Set1(buf+9, kJdwpEventCommandSet); 685 Set1(buf+10, kJdwpCompositeCommand); 686 687 // Prevents from interleaving commands and events. Otherwise we could end up in sending an event 688 // before sending the reply of the command being processed and would lead to bad synchronization 689 // between the debugger and the debuggee. 690 WaitForProcessingRequest(); 691 692 SendRequest(pReq); 693 694 expandBufFree(pReq); 695} 696 697 698/* 699 * Tell the debugger that we have finished initializing. This is always 700 * sent, even if the debugger hasn't requested it. 701 * 702 * This should be sent "before the main thread is started and before 703 * any application code has been executed". The thread ID in the message 704 * must be for the main thread. 705 */ 706bool JdwpState::PostVMStart() { 707 JdwpSuspendPolicy suspend_policy; 708 ObjectId threadId = Dbg::GetThreadSelfId(); 709 710 if (options_->suspend) { 711 suspend_policy = SP_ALL; 712 } else { 713 suspend_policy = SP_NONE; 714 } 715 716 ExpandBuf* pReq = eventPrep(); 717 { 718 MutexLock mu(Thread::Current(), event_list_lock_); // probably don't need this here 719 720 VLOG(jdwp) << "EVENT: " << EK_VM_START; 721 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 722 723 expandBufAdd1(pReq, suspend_policy); 724 expandBufAdd4BE(pReq, 1); 725 726 expandBufAdd1(pReq, EK_VM_START); 727 expandBufAdd4BE(pReq, 0); /* requestId */ 728 expandBufAdd8BE(pReq, threadId); 729 } 730 731 Dbg::ManageDeoptimization(); 732 733 /* send request and possibly suspend ourselves */ 734 SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId); 735 736 return true; 737} 738 739/* 740 * A location of interest has been reached. This handles: 741 * Breakpoint 742 * SingleStep 743 * MethodEntry 744 * MethodExit 745 * These four types must be grouped together in a single response. The 746 * "eventFlags" indicates the type of event(s) that have happened. 747 * 748 * Valid mods: 749 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly 750 * LocationOnly (for breakpoint/step only) 751 * Step (for step only) 752 * 753 * Interesting test cases: 754 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY 755 * and METHOD_EXIT events with a ClassOnly mod on the method's class. 756 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1. 757 * - Single-step to a line with a breakpoint. Should get a single 758 * event message with both events in it. 759 */ 760bool JdwpState::PostLocationEvent(const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags, 761 const JValue* returnValue) { 762 ModBasket basket; 763 basket.pLoc = pLoc; 764 basket.classId = pLoc->class_id; 765 basket.thisPtr = thisPtr; 766 basket.threadId = Dbg::GetThreadSelfId(); 767 basket.className = Dbg::GetClassName(pLoc->class_id); 768 769 /* 770 * On rare occasions we may need to execute interpreted code in the VM 771 * while handling a request from the debugger. Don't fire breakpoints 772 * while doing so. (I don't think we currently do this at all, so 773 * this is mostly paranoia.) 774 */ 775 if (basket.threadId == debug_thread_id_) { 776 VLOG(jdwp) << "Ignoring location event in JDWP thread"; 777 return false; 778 } 779 780 /* 781 * The debugger variable display tab may invoke the interpreter to format 782 * complex objects. We want to ignore breakpoints and method entry/exit 783 * traps while working on behalf of the debugger. 784 * 785 * If we don't ignore them, the VM will get hung up, because we'll 786 * suspend on a breakpoint while the debugger is still waiting for its 787 * method invocation to complete. 788 */ 789 if (InvokeInProgress()) { 790 VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")"; 791 return false; 792 } 793 794 int match_count = 0; 795 ExpandBuf* pReq = NULL; 796 JdwpSuspendPolicy suspend_policy = SP_NONE; 797 { 798 MutexLock mu(Thread::Current(), event_list_lock_); 799 JdwpEvent** match_list = AllocMatchList(event_list_size_); 800 if ((eventFlags & Dbg::kBreakpoint) != 0) { 801 FindMatchingEvents(EK_BREAKPOINT, &basket, match_list, &match_count); 802 } 803 if ((eventFlags & Dbg::kSingleStep) != 0) { 804 FindMatchingEvents(EK_SINGLE_STEP, &basket, match_list, &match_count); 805 } 806 if ((eventFlags & Dbg::kMethodEntry) != 0) { 807 FindMatchingEvents(EK_METHOD_ENTRY, &basket, match_list, &match_count); 808 } 809 if ((eventFlags & Dbg::kMethodExit) != 0) { 810 FindMatchingEvents(EK_METHOD_EXIT, &basket, match_list, &match_count); 811 FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, &basket, match_list, &match_count); 812 } 813 if (match_count != 0) { 814 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) " 815 << basket.className << "." << Dbg::GetMethodName(pLoc->method_id) 816 << StringPrintf(" thread=%#" PRIx64 " dex_pc=%#" PRIx64 ")", 817 basket.threadId, pLoc->dex_pc); 818 819 suspend_policy = scanSuspendPolicy(match_list, match_count); 820 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 821 822 pReq = eventPrep(); 823 expandBufAdd1(pReq, suspend_policy); 824 expandBufAdd4BE(pReq, match_count); 825 826 for (int i = 0; i < match_count; i++) { 827 expandBufAdd1(pReq, match_list[i]->eventKind); 828 expandBufAdd4BE(pReq, match_list[i]->requestId); 829 expandBufAdd8BE(pReq, basket.threadId); 830 expandBufAddLocation(pReq, *pLoc); 831 if (match_list[i]->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) { 832 Dbg::OutputMethodReturnValue(pLoc->method_id, returnValue, pReq); 833 } 834 } 835 } 836 837 CleanupMatchList(match_list, match_count); 838 } 839 840 Dbg::ManageDeoptimization(); 841 842 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId); 843 return match_count != 0; 844} 845 846/* 847 * A thread is starting or stopping. 848 * 849 * Valid mods: 850 * Count, ThreadOnly 851 */ 852bool JdwpState::PostThreadChange(ObjectId threadId, bool start) { 853 CHECK_EQ(threadId, Dbg::GetThreadSelfId()); 854 855 /* 856 * I don't think this can happen. 857 */ 858 if (InvokeInProgress()) { 859 LOG(WARNING) << "Not posting thread change during invoke"; 860 return false; 861 } 862 863 ModBasket basket; 864 basket.threadId = threadId; 865 866 ExpandBuf* pReq = NULL; 867 JdwpSuspendPolicy suspend_policy = SP_NONE; 868 int match_count = 0; 869 { 870 // Don't allow the list to be updated while we scan it. 871 MutexLock mu(Thread::Current(), event_list_lock_); 872 JdwpEvent** match_list = AllocMatchList(event_list_size_); 873 874 if (start) { 875 FindMatchingEvents(EK_THREAD_START, &basket, match_list, &match_count); 876 } else { 877 FindMatchingEvents(EK_THREAD_DEATH, &basket, match_list, &match_count); 878 } 879 880 if (match_count != 0) { 881 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) " 882 << StringPrintf("thread=%#" PRIx64, basket.threadId) << ")"; 883 884 suspend_policy = scanSuspendPolicy(match_list, match_count); 885 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 886 887 pReq = eventPrep(); 888 expandBufAdd1(pReq, suspend_policy); 889 expandBufAdd4BE(pReq, match_count); 890 891 for (int i = 0; i < match_count; i++) { 892 expandBufAdd1(pReq, match_list[i]->eventKind); 893 expandBufAdd4BE(pReq, match_list[i]->requestId); 894 expandBufAdd8BE(pReq, basket.threadId); 895 } 896 } 897 898 CleanupMatchList(match_list, match_count); 899 } 900 901 Dbg::ManageDeoptimization(); 902 903 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId); 904 905 return match_count != 0; 906} 907 908/* 909 * Send a polite "VM is dying" message to the debugger. 910 * 911 * Skips the usual "event token" stuff. 912 */ 913bool JdwpState::PostVMDeath() { 914 VLOG(jdwp) << "EVENT: " << EK_VM_DEATH; 915 916 ExpandBuf* pReq = eventPrep(); 917 expandBufAdd1(pReq, SP_NONE); 918 expandBufAdd4BE(pReq, 1); 919 920 expandBufAdd1(pReq, EK_VM_DEATH); 921 expandBufAdd4BE(pReq, 0); 922 EventFinish(pReq); 923 return true; 924} 925 926/* 927 * An exception has been thrown. It may or may not have been caught. 928 * 929 * Valid mods: 930 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly, 931 * ExceptionOnly, InstanceOnly 932 * 933 * The "exceptionId" has not been added to the GC-visible object registry, 934 * because there's a pretty good chance that we're not going to send it 935 * up the debugger. 936 */ 937bool JdwpState::PostException(const JdwpLocation* pThrowLoc, 938 ObjectId exceptionId, RefTypeId exceptionClassId, 939 const JdwpLocation* pCatchLoc, ObjectId thisPtr) { 940 ModBasket basket; 941 942 basket.pLoc = pThrowLoc; 943 basket.classId = pThrowLoc->class_id; 944 basket.threadId = Dbg::GetThreadSelfId(); 945 basket.className = Dbg::GetClassName(basket.classId); 946 basket.excepClassId = exceptionClassId; 947 basket.caught = (pCatchLoc->class_id != 0); 948 basket.thisPtr = thisPtr; 949 950 /* don't try to post an exception caused by the debugger */ 951 if (InvokeInProgress()) { 952 VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")"; 953 return false; 954 } 955 956 int match_count = 0; 957 ExpandBuf* pReq = NULL; 958 JdwpSuspendPolicy suspend_policy = SP_NONE; 959 { 960 MutexLock mu(Thread::Current(), event_list_lock_); 961 JdwpEvent** match_list = AllocMatchList(event_list_size_); 962 FindMatchingEvents(EK_EXCEPTION, &basket, match_list, &match_count); 963 if (match_count != 0) { 964 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total)" 965 << StringPrintf(" thread=%#" PRIx64, basket.threadId) 966 << StringPrintf(" exceptId=%#" PRIx64, exceptionId) 967 << " caught=" << basket.caught << ")" 968 << " throw: " << *pThrowLoc; 969 if (pCatchLoc->class_id == 0) { 970 VLOG(jdwp) << " catch: (not caught)"; 971 } else { 972 VLOG(jdwp) << " catch: " << *pCatchLoc; 973 } 974 975 suspend_policy = scanSuspendPolicy(match_list, match_count); 976 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 977 978 pReq = eventPrep(); 979 expandBufAdd1(pReq, suspend_policy); 980 expandBufAdd4BE(pReq, match_count); 981 982 for (int i = 0; i < match_count; i++) { 983 expandBufAdd1(pReq, match_list[i]->eventKind); 984 expandBufAdd4BE(pReq, match_list[i]->requestId); 985 expandBufAdd8BE(pReq, basket.threadId); 986 987 expandBufAddLocation(pReq, *pThrowLoc); 988 expandBufAdd1(pReq, JT_OBJECT); 989 expandBufAdd8BE(pReq, exceptionId); 990 expandBufAddLocation(pReq, *pCatchLoc); 991 } 992 } 993 994 CleanupMatchList(match_list, match_count); 995 } 996 997 Dbg::ManageDeoptimization(); 998 999 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId); 1000 1001 return match_count != 0; 1002} 1003 1004/* 1005 * Announce that a class has been loaded. 1006 * 1007 * Valid mods: 1008 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude 1009 */ 1010bool JdwpState::PostClassPrepare(JdwpTypeTag tag, RefTypeId refTypeId, const std::string& signature, 1011 int status) { 1012 ModBasket basket; 1013 1014 basket.classId = refTypeId; 1015 basket.threadId = Dbg::GetThreadSelfId(); 1016 basket.className = Dbg::GetClassName(basket.classId); 1017 1018 /* suppress class prep caused by debugger */ 1019 if (InvokeInProgress()) { 1020 VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")"; 1021 return false; 1022 } 1023 1024 ExpandBuf* pReq = NULL; 1025 JdwpSuspendPolicy suspend_policy = SP_NONE; 1026 int match_count = 0; 1027 { 1028 MutexLock mu(Thread::Current(), event_list_lock_); 1029 JdwpEvent** match_list = AllocMatchList(event_list_size_); 1030 FindMatchingEvents(EK_CLASS_PREPARE, &basket, match_list, &match_count); 1031 if (match_count != 0) { 1032 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) " 1033 << StringPrintf("thread=%#" PRIx64, basket.threadId) << ") " << signature; 1034 1035 suspend_policy = scanSuspendPolicy(match_list, match_count); 1036 VLOG(jdwp) << " suspend_policy=" << suspend_policy; 1037 1038 if (basket.threadId == debug_thread_id_) { 1039 /* 1040 * JDWP says that, for a class prep in the debugger thread, we 1041 * should set threadId to null and if any threads were supposed 1042 * to be suspended then we suspend all other threads. 1043 */ 1044 VLOG(jdwp) << " NOTE: class prepare in debugger thread!"; 1045 basket.threadId = 0; 1046 if (suspend_policy == SP_EVENT_THREAD) { 1047 suspend_policy = SP_ALL; 1048 } 1049 } 1050 1051 pReq = eventPrep(); 1052 expandBufAdd1(pReq, suspend_policy); 1053 expandBufAdd4BE(pReq, match_count); 1054 1055 for (int i = 0; i < match_count; i++) { 1056 expandBufAdd1(pReq, match_list[i]->eventKind); 1057 expandBufAdd4BE(pReq, match_list[i]->requestId); 1058 expandBufAdd8BE(pReq, basket.threadId); 1059 1060 expandBufAdd1(pReq, tag); 1061 expandBufAdd8BE(pReq, refTypeId); 1062 expandBufAddUtf8String(pReq, signature); 1063 expandBufAdd4BE(pReq, status); 1064 } 1065 } 1066 CleanupMatchList(match_list, match_count); 1067 } 1068 1069 Dbg::ManageDeoptimization(); 1070 1071 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId); 1072 1073 return match_count != 0; 1074} 1075 1076/* 1077 * Send up a chunk of DDM data. 1078 * 1079 * While this takes the form of a JDWP "event", it doesn't interact with 1080 * other debugger traffic, and can't suspend the VM, so we skip all of 1081 * the fun event token gymnastics. 1082 */ 1083void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) { 1084 uint8_t header[kJDWPHeaderLen + 8]; 1085 size_t dataLen = 0; 1086 1087 CHECK(iov != NULL); 1088 CHECK_GT(iov_count, 0); 1089 CHECK_LT(iov_count, 10); 1090 1091 /* 1092 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do 1093 * this by creating a new copy of the vector with space for the header. 1094 */ 1095 std::vector<iovec> wrapiov; 1096 wrapiov.push_back(iovec()); 1097 for (int i = 0; i < iov_count; i++) { 1098 wrapiov.push_back(iov[i]); 1099 dataLen += iov[i].iov_len; 1100 } 1101 1102 /* form the header (JDWP plus DDMS) */ 1103 Set4BE(header, sizeof(header) + dataLen); 1104 Set4BE(header+4, NextRequestSerial()); 1105 Set1(header+8, 0); /* flags */ 1106 Set1(header+9, kJDWPDdmCmdSet); 1107 Set1(header+10, kJDWPDdmCmd); 1108 Set4BE(header+11, type); 1109 Set4BE(header+15, dataLen); 1110 1111 wrapiov[0].iov_base = header; 1112 wrapiov[0].iov_len = sizeof(header); 1113 1114 // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level 1115 // than mutator for lock ordering reasons. 1116 Thread* self = Thread::Current(); 1117 bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self); 1118 if (safe_to_release_mutator_lock_over_send) { 1119 for (size_t i = 0; i < kMutatorLock; ++i) { 1120 if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) { 1121 safe_to_release_mutator_lock_over_send = false; 1122 break; 1123 } 1124 } 1125 } 1126 if (safe_to_release_mutator_lock_over_send) { 1127 // Change state to waiting to allow GC, ... while we're sending. 1128 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend); 1129 SendBufferedRequest(type, wrapiov); 1130 self->TransitionFromSuspendedToRunnable(); 1131 } else { 1132 // Send and possibly block GC... 1133 SendBufferedRequest(type, wrapiov); 1134 } 1135} 1136 1137} // namespace JDWP 1138 1139} // namespace art 1140