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