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