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 /*
40 General notes:
41
42 The event add/remove stuff usually happens from the debugger thread,
43 in response to requests from the debugger, but can also happen as the
44 result of an event in an arbitrary thread (e.g. an event with a "count"
45 mod expires). It's important to keep the event list locked when processing
46 events.
47
48 Event posting can happen from any thread. The JDWP thread will not usually
49 post anything but VM start/death, but if a JDWP request causes a class
50 to be loaded, the ClassPrepare event will come from the JDWP thread.
51
52
53 We can have serialization issues when we post an event to the debugger.
54 For example, a thread could send an "I hit a breakpoint and am suspending
55 myself" message to the debugger. Before it manages to suspend itself, the
56 debugger's response ("not interested, resume thread") arrives and is
57 processed. We try to resume a thread that hasn't yet suspended.
58
59 This means that, after posting an event to the debugger, we need to wait
60 for the event thread to suspend itself (and, potentially, all other threads)
61 before processing any additional requests from the debugger. While doing
62 so we need to be aware that multiple threads may be hitting breakpoints
63 or other events simultaneously, so we either need to wait for all of them
64 or serialize the events with each other.
65
66 The 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
80 Some 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
88 So we need to mark thread B in such a way that thread A doesn't wait for it.
89
90 If we just bracket the "grab event token" call with a change to VMWAIT
91 before sleeping, the switch back to RUNNING state when we get the token
92 will cause thread B to suspend (remember, thread A's global suspend is
93 still in force, even after it releases the token). Suspending while
94 holding the event token is very bad, because it prevents the JDWP thread
95 from processing incoming messages.
96
97 We need to change to VMWAIT state at the *start* of posting an event,
98 and stay there until we either finish posting the event or decide to
99 put ourselves to sleep. That way we don't interfere with anyone else and
100 don't allow anyone else to interfere with us.
101 */
102
103 namespace art {
104
105 namespace JDWP {
106
107 using 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 */
116 struct ModBasket {
ModBasketart::JDWP::ModBasket117 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
NeedsFullDeoptimization(JdwpEventKind eventKind)141 static 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.
GetInstrumentationEventFor(JdwpEventKind eventKind)160 static 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 */
RegisterEvent(JdwpEvent * pEvent)189 JdwpError 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
UnregisterLocationEventsOnClass(ObjPtr<mirror::Class> klass)254 void 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 */
UnregisterEvent(JdwpEvent * pEvent)299 void 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 */
UnregisterEventById(uint32_t requestId)356 void 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 */
UnregisterAll()385 void 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 */
EventAlloc(int numMods)404 JdwpEvent* 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 */
EventFree(JdwpEvent * pEvent)417 void 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 */
CleanupMatchList(const std::vector<JdwpEvent * > & match_list)448 void 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 */
PatternMatch(const char * pattern,const std::string & target)468 static 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 */
ModsMatch(JdwpEvent * pEvent,const ModBasket & basket)489 static 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 */
FindMatchingEventsLocked(JdwpEventKind event_kind,const ModBasket & basket,std::vector<JdwpEvent * > * match_list)574 void 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 */
FindMatchingEvents(JdwpEventKind event_kind,const ModBasket & basket,std::vector<JdwpEvent * > * match_list)594 bool 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 */
ScanSuspendPolicy(const std::vector<JdwpEvent * > & match_list)606 static 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 */
SuspendByPolicy(JdwpSuspendPolicy suspend_policy,JDWP::ObjectId thread_self_id)624 void 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
SendRequestAndPossiblySuspend(ExpandBuf * pReq,JdwpSuspendPolicy suspend_policy,ObjectId threadId)659 void 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 */
InvokeInProgress()685 bool JdwpState::InvokeInProgress() {
686 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
687 return pReq != nullptr;
688 }
689
AcquireJdwpTokenForCommand()690 void JdwpState::AcquireJdwpTokenForCommand() {
691 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
692 SetWaitForJdwpToken(debug_thread_id_);
693 }
694
ReleaseJdwpTokenForCommand()695 void JdwpState::ReleaseJdwpTokenForCommand() {
696 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
697 ClearWaitForJdwpToken();
698 }
699
AcquireJdwpTokenForEvent(ObjectId threadId)700 void JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) {
701 SetWaitForJdwpToken(threadId);
702 }
703
ReleaseJdwpTokenForEvent()704 void 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 */
SetWaitForJdwpToken(ObjectId threadId)715 void 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 */
ClearWaitForJdwpToken()752 void 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 */
eventPrep()772 static 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 */
EventFinish(ExpandBuf * pReq)783 void 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 */
PostVMStart()806 void 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
LogMatchingEventsAndThread(const std::vector<JdwpEvent * > & match_list,ObjectId thread_id)826 static 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
SetJdwpLocationFromEventLocation(const JDWP::EventLocation * event_location,JDWP::JdwpLocation * jdwp_location)842 static 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 */
PostLocationEvent(const EventLocation * pLoc,mirror::Object * thisPtr,int eventFlags,const JValue * returnValue)871 void 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
PostFieldEvent(const EventLocation * pLoc,ArtField * field,mirror::Object * this_object,const JValue * fieldValue,bool is_modification)967 void 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 */
PostThreadChange(Thread * thread,bool start)1059 void 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 */
PostVMDeath()1120 bool 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 */
PostException(const EventLocation * pThrowLoc,mirror::Throwable * exception_object,const EventLocation * pCatchLoc,mirror::Object * thisPtr)1144 void 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 */
PostClassPrepare(mirror::Class * klass)1231 void 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 */
SetupChunkHeader(uint32_t type,size_t data_len,size_t header_size,uint8_t * out_header)1310 void 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 */
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] = { 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