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