blob: a405c9b4ff1aae7babedbd00f7940b4ab3c3c062 [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 */
Elliott Hughesa2155262011-11-16 16:26:58 -0800112 std::string className; /* ClassMatch/ClassExclude */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700113 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 * Dump an event to the log file.
124 */
125static void dumpEvent(const JdwpEvent* pEvent) {
126 LOG(INFO) << StringPrintf("Event id=0x%4x %p (prev=%p next=%p):", pEvent->requestId, pEvent, pEvent->prev, pEvent->next);
127 LOG(INFO) << " kind=" << pEvent->eventKind << " susp=" << pEvent->suspendPolicy << " modCount=" << pEvent->modCount;
128
129 for (int i = 0; i < pEvent->modCount; i++) {
130 const JdwpEventMod* pMod = &pEvent->mods[i];
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800131 LOG(INFO) << " " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700132 /* TODO - show details */
133 }
134}
135
136/*
137 * Add an event to the list. Ordering is not important.
138 *
139 * If something prevents the event from being registered, e.g. it's a
140 * single-step request on a thread that doesn't exist, the event will
141 * not be added to the list, and an appropriate error will be returned.
142 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800143JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
144 MutexLock mu(event_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700145
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700146 CHECK(pEvent != NULL);
147 CHECK(pEvent->prev == NULL);
148 CHECK(pEvent->next == NULL);
149
150 /*
151 * If one or more "break"-type mods are used, register them with
152 * the interpreter.
153 */
154 for (int i = 0; i < pEvent->modCount; i++) {
155 const JdwpEventMod* pMod = &pEvent->mods[i];
156 if (pMod->modKind == MK_LOCATION_ONLY) {
157 /* should only be for Breakpoint, Step, and Exception */
158 Dbg::WatchLocation(&pMod->locationOnly.loc);
159 } else if (pMod->modKind == MK_STEP) {
160 /* should only be for EK_SINGLE_STEP; should only be one */
161 JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
162 JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
163 Dbg::ConfigureStep(pMod->step.threadId, size, depth);
164 } else if (pMod->modKind == MK_FIELD_ONLY) {
165 /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */
166 dumpEvent(pEvent); /* TODO - need for field watches */
167 }
168 }
169
170 /*
171 * Add to list.
172 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800173 if (eventList != NULL) {
174 pEvent->next = eventList;
175 eventList->prev = pEvent;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700176 }
Elliott Hughes761928d2011-11-16 18:33:03 -0800177 eventList = pEvent;
178 numEvents++;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700179
180 return ERR_NONE;
181}
182
183/*
184 * Remove an event from the list. This will also remove the event from
185 * any optimization tables, e.g. breakpoints.
186 *
187 * Does not free the JdwpEvent.
188 *
189 * Grab the eventLock before calling here.
190 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800191void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700192 if (pEvent->prev == NULL) {
193 /* head of the list */
Elliott Hughes761928d2011-11-16 18:33:03 -0800194 CHECK(eventList == pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700195
Elliott Hughes761928d2011-11-16 18:33:03 -0800196 eventList = pEvent->next;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700197 } else {
198 pEvent->prev->next = pEvent->next;
199 }
200
201 if (pEvent->next != NULL) {
202 pEvent->next->prev = pEvent->prev;
203 pEvent->next = NULL;
204 }
205 pEvent->prev = NULL;
206
207 /*
208 * Unhook us from the interpreter, if necessary.
209 */
210 for (int i = 0; i < pEvent->modCount; i++) {
211 JdwpEventMod* pMod = &pEvent->mods[i];
212 if (pMod->modKind == MK_LOCATION_ONLY) {
213 /* should only be for Breakpoint, Step, and Exception */
214 Dbg::UnwatchLocation(&pMod->locationOnly.loc);
215 }
216 if (pMod->modKind == MK_STEP) {
217 /* should only be for EK_SINGLE_STEP; should only be one */
218 Dbg::UnconfigureStep(pMod->step.threadId);
219 }
220 }
221
Elliott Hughes761928d2011-11-16 18:33:03 -0800222 numEvents--;
223 CHECK(numEvents != 0 || eventList == NULL);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700224}
225
226/*
227 * Remove the event with the given ID from the list.
228 *
229 * Failure to find the event isn't really an error, but it is a little
230 * weird. (It looks like Eclipse will try to be extra careful and will
231 * explicitly remove one-off single-step events.)
232 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800233void JdwpState::UnregisterEventById(uint32_t requestId) {
234 MutexLock mu(event_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700235
Elliott Hughes761928d2011-11-16 18:33:03 -0800236 JdwpEvent* pEvent = eventList;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700237 while (pEvent != NULL) {
238 if (pEvent->requestId == requestId) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800239 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700240 EventFree(pEvent);
Elliott Hughes761928d2011-11-16 18:33:03 -0800241 return; /* there can be only one with a given ID */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700242 }
243
244 pEvent = pEvent->next;
245 }
246
247 //LOGD("Odd: no match when removing event reqId=0x%04x", requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700248}
249
250/*
251 * Remove all entries from the event list.
252 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800253void JdwpState::UnregisterAll() {
254 MutexLock mu(event_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700255
Elliott Hughes761928d2011-11-16 18:33:03 -0800256 JdwpEvent* pEvent = eventList;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700257 while (pEvent != NULL) {
258 JdwpEvent* pNextEvent = pEvent->next;
259
Elliott Hughes761928d2011-11-16 18:33:03 -0800260 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700261 EventFree(pEvent);
262 pEvent = pNextEvent;
263 }
264
Elliott Hughes761928d2011-11-16 18:33:03 -0800265 eventList = NULL;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700266}
267
268/*
269 * Allocate a JdwpEvent struct with enough space to hold the specified
270 * number of mod records.
271 */
272JdwpEvent* EventAlloc(int numMods) {
273 JdwpEvent* newEvent;
274 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
275 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
276 memset(newEvent, 0, allocSize);
277 return newEvent;
278}
279
280/*
281 * Free a JdwpEvent.
282 *
283 * Do not call this until the event has been removed from the list.
284 */
285void EventFree(JdwpEvent* pEvent) {
286 if (pEvent == NULL) {
287 return;
288 }
289
290 /* make sure it was removed from the list */
291 CHECK(pEvent->prev == NULL);
292 CHECK(pEvent->next == NULL);
293 /* want to check state->eventList != pEvent */
294
295 /*
296 * Free any hairy bits in the mods.
297 */
298 for (int i = 0; i < pEvent->modCount; i++) {
299 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
300 free(pEvent->mods[i].classMatch.classPattern);
301 pEvent->mods[i].classMatch.classPattern = NULL;
302 }
303 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
304 free(pEvent->mods[i].classExclude.classPattern);
305 pEvent->mods[i].classExclude.classPattern = NULL;
306 }
307 }
308
309 free(pEvent);
310}
311
312/*
313 * Allocate storage for matching events. To keep things simple we
314 * use an array with enough storage for the entire list.
315 *
316 * The state->eventLock should be held before calling.
317 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800318static JdwpEvent** AllocMatchList(size_t event_count) {
319 return new JdwpEvent*[event_count];
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700320}
321
322/*
323 * Run through the list and remove any entries with an expired "count" mod
324 * from the event list, then free the match list.
325 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800326void JdwpState::CleanupMatchList(JdwpEvent** matchList, int matchCount) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700327 JdwpEvent** ppEvent = matchList;
328
329 while (matchCount--) {
330 JdwpEvent* pEvent = *ppEvent;
331
332 for (int i = 0; i < pEvent->modCount; i++) {
333 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
334 LOG(VERBOSE) << "##### Removing expired event";
Elliott Hughes761928d2011-11-16 18:33:03 -0800335 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700336 EventFree(pEvent);
337 break;
338 }
339 }
340
341 ppEvent++;
342 }
343
Elliott Hughes761928d2011-11-16 18:33:03 -0800344 delete[] matchList;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700345}
346
347/*
348 * Match a string against a "restricted regular expression", which is just
349 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
350 *
351 * ("Restricted name globbing" might have been a better term.)
352 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800353static bool PatternMatch(const char* pattern, const std::string& target) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800354 size_t patLen = strlen(pattern);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700355
356 if (pattern[0] == '*') {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700357 patLen--;
358 // TODO: remove printf when we find a test case to verify this
Elliott Hughesa2155262011-11-16 16:26:58 -0800359 LOG(ERROR) << ">>> comparing '" << (pattern + 1) << "' to '" << (target.c_str() + (target.size()-patLen)) << "'";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700360
Elliott Hughesa2155262011-11-16 16:26:58 -0800361 if (target.size() < patLen) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700362 return false;
363 }
Elliott Hughesa2155262011-11-16 16:26:58 -0800364 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700365 } else if (pattern[patLen-1] == '*') {
Elliott Hughesa2155262011-11-16 16:26:58 -0800366 return strncmp(pattern, target.c_str(), patLen-1) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700367 } else {
Elliott Hughesa2155262011-11-16 16:26:58 -0800368 return strcmp(pattern, target.c_str()) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700369 }
370}
371
372/*
373 * See if two locations are equal.
374 *
375 * It's tempting to do a bitwise compare ("struct ==" or memcmp), but if
376 * the storage wasn't zeroed out there could be undefined values in the
377 * padding. Besides, the odds of "idx" being equal while the others aren't
378 * is very small, so this is usually just a simple integer comparison.
379 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800380static inline bool LocationMatch(const JdwpLocation* pLoc1, const JdwpLocation* pLoc2) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700381 return pLoc1->idx == pLoc2->idx &&
382 pLoc1->methodId == pLoc2->methodId &&
383 pLoc1->classId == pLoc2->classId &&
384 pLoc1->typeTag == pLoc2->typeTag;
385}
386
387/*
388 * See if the event's mods match up with the contents of "basket".
389 *
390 * If we find a Count mod before rejecting an event, we decrement it. We
391 * need to do this even if later mods cause us to ignore the event.
392 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800393static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700394 JdwpEventMod* pMod = pEvent->mods;
395
396 for (int i = pEvent->modCount; i > 0; i--, pMod++) {
397 switch (pMod->modKind) {
398 case MK_COUNT:
399 CHECK_GT(pMod->count.count, 0);
400 pMod->count.count--;
401 break;
402 case MK_CONDITIONAL:
403 CHECK(false); // should not be getting these
404 break;
405 case MK_THREAD_ONLY:
406 if (pMod->threadOnly.threadId != basket->threadId) {
407 return false;
408 }
409 break;
410 case MK_CLASS_ONLY:
411 if (!Dbg::MatchType(basket->classId, pMod->classOnly.refTypeId)) {
412 return false;
413 }
414 break;
415 case MK_CLASS_MATCH:
Elliott Hughes761928d2011-11-16 18:33:03 -0800416 if (!PatternMatch(pMod->classMatch.classPattern, basket->className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700417 return false;
418 }
419 break;
420 case MK_CLASS_EXCLUDE:
Elliott Hughes761928d2011-11-16 18:33:03 -0800421 if (PatternMatch(pMod->classMatch.classPattern, basket->className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700422 return false;
423 }
424 break;
425 case MK_LOCATION_ONLY:
Elliott Hughes761928d2011-11-16 18:33:03 -0800426 if (!LocationMatch(&pMod->locationOnly.loc, basket->pLoc)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700427 return false;
428 }
429 break;
430 case MK_EXCEPTION_ONLY:
431 if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket->excepClassId, pMod->exceptionOnly.refTypeId)) {
432 return false;
433 }
434 if ((basket->caught && !pMod->exceptionOnly.caught) || (!basket->caught && !pMod->exceptionOnly.uncaught)) {
435 return false;
436 }
437 break;
438 case MK_FIELD_ONLY:
439 if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) {
440 return false;
441 }
442 break;
443 case MK_STEP:
444 if (pMod->step.threadId != basket->threadId) {
445 return false;
446 }
447 break;
448 case MK_INSTANCE_ONLY:
449 if (pMod->instanceOnly.objectId != basket->thisPtr) {
450 return false;
451 }
452 break;
453 default:
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800454 LOG(FATAL) << "unknown mod kind " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700455 break;
456 }
457 }
458 return true;
459}
460
461/*
462 * Find all events of type "eventKind" with mods that match up with the
463 * rest of the arguments.
464 *
465 * Found events are appended to "matchList", and "*pMatchCount" is advanced,
466 * so this may be called multiple times for grouped events.
467 *
468 * DO NOT call this multiple times for the same eventKind, as Count mods are
469 * decremented during the scan.
470 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800471void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, ModBasket* basket, JdwpEvent** matchList, int* pMatchCount) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700472 /* start after the existing entries */
473 matchList += *pMatchCount;
474
Elliott Hughes761928d2011-11-16 18:33:03 -0800475 JdwpEvent* pEvent = eventList;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700476 while (pEvent != NULL) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800477 if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700478 *matchList++ = pEvent;
479 (*pMatchCount)++;
480 }
481
482 pEvent = pEvent->next;
483 }
484}
485
486/*
487 * Scan through the list of matches and determine the most severe
488 * suspension policy.
489 */
490static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** matchList, int matchCount) {
491 JdwpSuspendPolicy policy = SP_NONE;
492
493 while (matchCount--) {
494 if ((*matchList)->suspendPolicy > policy) {
495 policy = (*matchList)->suspendPolicy;
496 }
497 matchList++;
498 }
499
500 return policy;
501}
502
503/*
504 * Three possibilities:
505 * SP_NONE - do nothing
506 * SP_EVENT_THREAD - suspend ourselves
507 * SP_ALL - suspend everybody except JDWP support thread
508 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800509void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspendPolicy) {
510 LOG(INFO) << "SuspendByPolicy(" << suspendPolicy << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700511 if (suspendPolicy == SP_NONE) {
512 return;
513 }
514
515 if (suspendPolicy == SP_ALL) {
Elliott Hughes475fc232011-10-25 15:00:35 -0700516 Dbg::SuspendVM();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700517 } else {
518 CHECK_EQ(suspendPolicy, SP_EVENT_THREAD);
519 }
520
521 /* this is rare but possible -- see CLASS_PREPARE handling */
Elliott Hughes761928d2011-11-16 18:33:03 -0800522 if (Dbg::GetThreadSelfId() == debugThreadId) {
523 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700524 return;
525 }
526
527 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
528 while (true) {
529 pReq->ready = true;
530 Dbg::SuspendSelf();
531 pReq->ready = false;
532
533 /*
534 * The JDWP thread has told us (and possibly all other threads) to
535 * resume. See if it has left anything in our DebugInvokeReq mailbox.
536 */
Elliott Hughesd07986f2011-12-06 18:27:45 -0800537 if (!pReq->invoke_needed_) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800538 /*LOGD("SuspendByPolicy: no invoke needed");*/
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700539 break;
540 }
541
542 /* grab this before posting/suspending again */
Elliott Hughes761928d2011-11-16 18:33:03 -0800543 SetWaitForEventThread(Dbg::GetThreadSelfId());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700544
Elliott Hughesd07986f2011-12-06 18:27:45 -0800545 /* leave pReq->invoke_needed_ raised so we can check reentrancy */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700546 Dbg::ExecuteMethod(pReq);
547
Elliott Hughes475fc232011-10-25 15:00:35 -0700548 pReq->error = ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700549
550 /* clear this before signaling */
Elliott Hughesd07986f2011-12-06 18:27:45 -0800551 pReq->invoke_needed_ = false;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700552
553 LOG(VERBOSE) << "invoke complete, signaling and self-suspending";
554 MutexLock mu(pReq->lock_);
555 pReq->cond_.Signal();
556 }
557}
558
559/*
560 * Determine if there is a method invocation in progress in the current
561 * thread.
562 *
Elliott Hughes475fc232011-10-25 15:00:35 -0700563 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700564 * state. If set, we're in the process of invoking a method.
565 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800566bool JdwpState::InvokeInProgress() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700567 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
Elliott Hughesd07986f2011-12-06 18:27:45 -0800568 return pReq->invoke_needed_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700569}
570
571/*
572 * We need the JDWP thread to hold off on doing stuff while we post an
573 * event and then suspend ourselves.
574 *
575 * Call this with a threadId of zero if you just want to wait for the
576 * current thread operation to complete.
577 *
578 * This could go to sleep waiting for another thread, so it's important
579 * that the thread be marked as VMWAIT before calling here.
580 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700581void JdwpState::SetWaitForEventThread(ObjectId threadId) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700582 bool waited = false;
583
584 /* this is held for very brief periods; contention is unlikely */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700585 MutexLock mu(event_thread_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700586
587 /*
588 * If another thread is already doing stuff, wait for it. This can
589 * go to sleep indefinitely.
590 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700591 while (eventThreadId != 0) {
592 LOG(VERBOSE) << StringPrintf("event in progress (0x%llx), 0x%llx sleeping", eventThreadId, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700593 waited = true;
Elliott Hughes376a7a02011-10-24 18:35:55 -0700594 event_thread_cond_.Wait(event_thread_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700595 }
596
597 if (waited || threadId != 0) {
598 LOG(VERBOSE) << StringPrintf("event token grabbed (0x%llx)", threadId);
599 }
600 if (threadId != 0) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700601 eventThreadId = threadId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700602 }
603}
604
605/*
606 * Clear the threadId and signal anybody waiting.
607 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700608void JdwpState::ClearWaitForEventThread() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700609 /*
610 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this
611 * function is called by dvmSuspendSelf(), and the transition back
612 * to RUNNING would confuse it.
613 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700614 MutexLock mu(event_thread_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700615
Elliott Hughes376a7a02011-10-24 18:35:55 -0700616 CHECK_NE(eventThreadId, 0U);
617 LOG(VERBOSE) << StringPrintf("cleared event token (0x%llx)", eventThreadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700618
Elliott Hughes376a7a02011-10-24 18:35:55 -0700619 eventThreadId = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700620
Elliott Hughes376a7a02011-10-24 18:35:55 -0700621 event_thread_cond_.Signal();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700622}
623
624
625/*
626 * Prep an event. Allocates storage for the message and leaves space for
627 * the header.
628 */
629static ExpandBuf* eventPrep() {
630 ExpandBuf* pReq = expandBufAlloc();
631 expandBufAddSpace(pReq, kJDWPHeaderLen);
632 return pReq;
633}
634
635/*
636 * Write the header into the buffer and send the packet off to the debugger.
637 *
638 * Takes ownership of "pReq" (currently discards it).
639 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800640void JdwpState::EventFinish(ExpandBuf* pReq) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700641 uint8_t* buf = expandBufGetBuffer(pReq);
642
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700643 Set4BE(buf, expandBufGetLength(pReq));
Elliott Hughes761928d2011-11-16 18:33:03 -0800644 Set4BE(buf+4, NextRequestSerial());
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700645 Set1(buf+8, 0); /* flags */
646 Set1(buf+9, kJdwpEventCommandSet);
647 Set1(buf+10, kJdwpCompositeCommand);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700648
Elliott Hughes761928d2011-11-16 18:33:03 -0800649 SendRequest(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700650
651 expandBufFree(pReq);
652}
653
654
655/*
656 * Tell the debugger that we have finished initializing. This is always
657 * sent, even if the debugger hasn't requested it.
658 *
659 * This should be sent "before the main thread is started and before
660 * any application code has been executed". The thread ID in the message
661 * must be for the main thread.
662 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700663bool JdwpState::PostVMStart() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700664 JdwpSuspendPolicy suspendPolicy;
665 ObjectId threadId = Dbg::GetThreadSelfId();
666
Elliott Hughes376a7a02011-10-24 18:35:55 -0700667 if (options_->suspend) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700668 suspendPolicy = SP_ALL;
669 } else {
670 suspendPolicy = SP_NONE;
671 }
672
Elliott Hughes761928d2011-11-16 18:33:03 -0800673 ExpandBuf* pReq = eventPrep();
674 {
675 MutexLock mu(event_lock_); // probably don't need this here
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700676
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700677 LOG(VERBOSE) << "EVENT: " << EK_VM_START;
678 LOG(VERBOSE) << " suspendPolicy=" << suspendPolicy;
679
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700680 expandBufAdd1(pReq, suspendPolicy);
681 expandBufAdd4BE(pReq, 1);
682
683 expandBufAdd1(pReq, EK_VM_START);
684 expandBufAdd4BE(pReq, 0); /* requestId */
685 expandBufAdd8BE(pReq, threadId);
686 }
687
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700688 /* send request and possibly suspend ourselves */
689 if (pReq != NULL) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700690 int old_state = Dbg::ThreadWaiting();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700691 if (suspendPolicy != SP_NONE) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700692 SetWaitForEventThread(threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700693 }
694
Elliott Hughes761928d2011-11-16 18:33:03 -0800695 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700696
Elliott Hughes761928d2011-11-16 18:33:03 -0800697 SuspendByPolicy(suspendPolicy);
Elliott Hughes376a7a02011-10-24 18:35:55 -0700698 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700699 }
700
701 return true;
702}
703
704// TODO: This doesn't behave like the real dvmDescriptorToName.
705// I'm hoping this isn't used to communicate with the debugger, and we can just use descriptors.
Elliott Hughesa2155262011-11-16 16:26:58 -0800706std::string dvmDescriptorToName(const std::string& descriptor) {
707 return descriptor;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700708}
709
710/*
711 * A location of interest has been reached. This handles:
712 * Breakpoint
713 * SingleStep
714 * MethodEntry
715 * MethodExit
716 * These four types must be grouped together in a single response. The
717 * "eventFlags" indicates the type of event(s) that have happened.
718 *
719 * Valid mods:
720 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
721 * LocationOnly (for breakpoint/step only)
722 * Step (for step only)
723 *
724 * Interesting test cases:
725 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY
726 * and METHOD_EXIT events with a ClassOnly mod on the method's class.
727 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1.
728 * - Single-step to a line with a breakpoint. Should get a single
729 * event message with both events in it.
730 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800731bool JdwpState::PostLocationEvent(const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700732 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700733
734 memset(&basket, 0, sizeof(basket));
735 basket.pLoc = pLoc;
736 basket.classId = pLoc->classId;
737 basket.thisPtr = thisPtr;
738 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughesa2155262011-11-16 16:26:58 -0800739 basket.className = dvmDescriptorToName(Dbg::GetClassDescriptor(pLoc->classId));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700740
741 /*
742 * On rare occasions we may need to execute interpreted code in the VM
743 * while handling a request from the debugger. Don't fire breakpoints
744 * while doing so. (I don't think we currently do this at all, so
745 * this is mostly paranoia.)
746 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800747 if (basket.threadId == debugThreadId) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700748 LOG(VERBOSE) << "Ignoring location event in JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700749 return false;
750 }
751
752 /*
753 * The debugger variable display tab may invoke the interpreter to format
754 * complex objects. We want to ignore breakpoints and method entry/exit
755 * traps while working on behalf of the debugger.
756 *
757 * If we don't ignore them, the VM will get hung up, because we'll
758 * suspend on a breakpoint while the debugger is still waiting for its
759 * method invocation to complete.
760 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800761 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700762 LOG(VERBOSE) << "Not checking breakpoints during invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700763 return false;
764 }
765
Elliott Hughes761928d2011-11-16 18:33:03 -0800766 JdwpEvent** matchList = AllocMatchList(numEvents);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700767 int matchCount = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700768 ExpandBuf* pReq = NULL;
769 JdwpSuspendPolicy suspendPolicy = SP_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700770
Elliott Hughes761928d2011-11-16 18:33:03 -0800771 {
772 MutexLock mu(event_lock_);
773 if ((eventFlags & Dbg::kBreakPoint) != 0) {
774 FindMatchingEvents(EK_BREAKPOINT, &basket, matchList, &matchCount);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700775 }
Elliott Hughes761928d2011-11-16 18:33:03 -0800776 if ((eventFlags & Dbg::kSingleStep) != 0) {
777 FindMatchingEvents(EK_SINGLE_STEP, &basket, matchList, &matchCount);
778 }
779 if ((eventFlags & Dbg::kMethodEntry) != 0) {
780 FindMatchingEvents(EK_METHOD_ENTRY, &basket, matchList, &matchCount);
781 }
782 if ((eventFlags & Dbg::kMethodExit) != 0) {
783 FindMatchingEvents(EK_METHOD_EXIT, &basket, matchList, &matchCount);
784 }
785 if (matchCount != 0) {
786 LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
787 << basket.className << "." << Dbg::GetMethodName(pLoc->classId, pLoc->methodId)
788 << " thread=" << (void*) basket.threadId << " code=" << (void*) pLoc->idx << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700789
Elliott Hughes761928d2011-11-16 18:33:03 -0800790 suspendPolicy = scanSuspendPolicy(matchList, matchCount);
791 LOG(VERBOSE) << " suspendPolicy=" << suspendPolicy;
792
793 pReq = eventPrep();
794 expandBufAdd1(pReq, suspendPolicy);
795 expandBufAdd4BE(pReq, matchCount);
796
797 for (int i = 0; i < matchCount; i++) {
798 expandBufAdd1(pReq, matchList[i]->eventKind);
799 expandBufAdd4BE(pReq, matchList[i]->requestId);
800 expandBufAdd8BE(pReq, basket.threadId);
801 AddLocation(pReq, pLoc);
802 }
803 }
804
805 CleanupMatchList(matchList, matchCount);
806 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700807
808 /* send request and possibly suspend ourselves */
809 if (pReq != NULL) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700810 int old_state = Dbg::ThreadWaiting();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700811 if (suspendPolicy != SP_NONE) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800812 SetWaitForEventThread(basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700813 }
814
Elliott Hughes761928d2011-11-16 18:33:03 -0800815 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700816
Elliott Hughes761928d2011-11-16 18:33:03 -0800817 SuspendByPolicy(suspendPolicy);
Elliott Hughes376a7a02011-10-24 18:35:55 -0700818 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700819 }
820
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700821 return matchCount != 0;
822}
823
824/*
825 * A thread is starting or stopping.
826 *
827 * Valid mods:
828 * Count, ThreadOnly
829 */
Elliott Hughes234ab152011-10-26 14:02:26 -0700830bool JdwpState::PostThreadChange(ObjectId threadId, bool start) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700831 CHECK_EQ(threadId, Dbg::GetThreadSelfId());
832
833 /*
834 * I don't think this can happen.
835 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800836 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700837 LOG(WARNING) << "Not posting thread change during invoke";
838 return false;
839 }
840
841 ModBasket basket;
842 memset(&basket, 0, sizeof(basket));
843 basket.threadId = threadId;
844
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700845 ExpandBuf* pReq = NULL;
846 JdwpSuspendPolicy suspendPolicy = SP_NONE;
Elliott Hughes234ab152011-10-26 14:02:26 -0700847 int matchCount = 0;
848 {
849 // Don't allow the list to be updated while we scan it.
850 MutexLock mu(event_lock_);
Elliott Hughes761928d2011-11-16 18:33:03 -0800851 JdwpEvent** matchList = AllocMatchList(numEvents);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700852
Elliott Hughes234ab152011-10-26 14:02:26 -0700853 if (start) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800854 FindMatchingEvents(EK_THREAD_START, &basket, matchList, &matchCount);
Elliott Hughes234ab152011-10-26 14:02:26 -0700855 } else {
Elliott Hughes761928d2011-11-16 18:33:03 -0800856 FindMatchingEvents(EK_THREAD_DEATH, &basket, matchList, &matchCount);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700857 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700858
Elliott Hughes234ab152011-10-26 14:02:26 -0700859 if (matchCount != 0) {
860 LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
861 << "thread=" << (void*) basket.threadId << ")";
862
863 suspendPolicy = scanSuspendPolicy(matchList, matchCount);
864 LOG(VERBOSE) << " suspendPolicy=" << suspendPolicy;
865
866 pReq = eventPrep();
867 expandBufAdd1(pReq, suspendPolicy);
868 expandBufAdd4BE(pReq, matchCount);
869
870 for (int i = 0; i < matchCount; i++) {
871 expandBufAdd1(pReq, matchList[i]->eventKind);
872 expandBufAdd4BE(pReq, matchList[i]->requestId);
873 expandBufAdd8BE(pReq, basket.threadId);
874 }
875 }
876
Elliott Hughes761928d2011-11-16 18:33:03 -0800877 CleanupMatchList(matchList, matchCount);
Elliott Hughes234ab152011-10-26 14:02:26 -0700878 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700879
880 /* send request and possibly suspend ourselves */
881 if (pReq != NULL) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700882 int old_state = Dbg::ThreadWaiting();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700883 if (suspendPolicy != SP_NONE) {
Elliott Hughes234ab152011-10-26 14:02:26 -0700884 SetWaitForEventThread(basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700885 }
Elliott Hughes761928d2011-11-16 18:33:03 -0800886 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700887
Elliott Hughes761928d2011-11-16 18:33:03 -0800888 SuspendByPolicy(suspendPolicy);
Elliott Hughes376a7a02011-10-24 18:35:55 -0700889 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700890 }
891
892 return matchCount != 0;
893}
894
895/*
896 * Send a polite "VM is dying" message to the debugger.
897 *
898 * Skips the usual "event token" stuff.
899 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700900bool JdwpState::PostVMDeath() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700901 LOG(VERBOSE) << "EVENT: " << EK_VM_DEATH;
902
903 ExpandBuf* pReq = eventPrep();
904 expandBufAdd1(pReq, SP_NONE);
905 expandBufAdd4BE(pReq, 1);
906
907 expandBufAdd1(pReq, EK_VM_DEATH);
908 expandBufAdd4BE(pReq, 0);
Elliott Hughes761928d2011-11-16 18:33:03 -0800909 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700910 return true;
911}
912
913/*
914 * An exception has been thrown. It may or may not have been caught.
915 *
916 * Valid mods:
917 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
918 * ExceptionOnly, InstanceOnly
919 *
920 * The "exceptionId" has not been added to the GC-visible object registry,
921 * because there's a pretty good chance that we're not going to send it
922 * up the debugger.
923 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800924bool JdwpState::PostException(const JdwpLocation* pThrowLoc,
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700925 ObjectId exceptionId, RefTypeId exceptionClassId,
926 const JdwpLocation* pCatchLoc, ObjectId thisPtr)
927{
928 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700929
930 memset(&basket, 0, sizeof(basket));
931 basket.pLoc = pThrowLoc;
932 basket.classId = pThrowLoc->classId;
933 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughesa2155262011-11-16 16:26:58 -0800934 basket.className = dvmDescriptorToName(Dbg::GetClassDescriptor(basket.classId));
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700935 basket.excepClassId = exceptionClassId;
936 basket.caught = (pCatchLoc->classId != 0);
937 basket.thisPtr = thisPtr;
938
939 /* don't try to post an exception caused by the debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -0800940 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700941 LOG(VERBOSE) << "Not posting exception hit during invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700942 return false;
943 }
944
Elliott Hughes761928d2011-11-16 18:33:03 -0800945 JdwpEvent** matchList = AllocMatchList(numEvents);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700946 int matchCount = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700947 ExpandBuf* pReq = NULL;
948 JdwpSuspendPolicy suspendPolicy = SP_NONE;
Elliott Hughes761928d2011-11-16 18:33:03 -0800949 {
950 MutexLock mu(event_lock_);
951 FindMatchingEvents(EK_EXCEPTION, &basket, matchList, &matchCount);
952 if (matchCount != 0) {
953 LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total)"
954 << " thread=" << (void*) basket.threadId
955 << " exceptId=" << (void*) exceptionId
956 << " caught=" << basket.caught << ")";
Elliott Hughes03181a82011-11-17 17:22:21 -0800957 LOG(VERBOSE) << " throw: " << *pThrowLoc;
Elliott Hughes761928d2011-11-16 18:33:03 -0800958 if (pCatchLoc->classId == 0) {
959 LOG(VERBOSE) << " catch: (not caught)";
960 } else {
Elliott Hughes03181a82011-11-17 17:22:21 -0800961 LOG(VERBOSE) << " catch: " << *pCatchLoc;
Elliott Hughes761928d2011-11-16 18:33:03 -0800962 }
963
964 suspendPolicy = scanSuspendPolicy(matchList, matchCount);
965 LOG(VERBOSE) << " suspendPolicy=" << suspendPolicy;
966
967 pReq = eventPrep();
968 expandBufAdd1(pReq, suspendPolicy);
969 expandBufAdd4BE(pReq, matchCount);
970
971 for (int i = 0; i < matchCount; i++) {
972 expandBufAdd1(pReq, matchList[i]->eventKind);
973 expandBufAdd4BE(pReq, matchList[i]->requestId);
974 expandBufAdd8BE(pReq, basket.threadId);
975
976 AddLocation(pReq, pThrowLoc);
977 expandBufAdd1(pReq, JT_OBJECT);
978 expandBufAdd8BE(pReq, exceptionId);
979 AddLocation(pReq, pCatchLoc);
980 }
981
982 /* don't let the GC discard it */
983 Dbg::RegisterObjectId(exceptionId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700984 }
985
Elliott Hughes761928d2011-11-16 18:33:03 -0800986 CleanupMatchList(matchList, matchCount);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700987 }
988
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700989 /* send request and possibly suspend ourselves */
990 if (pReq != NULL) {
Elliott Hughes376a7a02011-10-24 18:35:55 -0700991 int old_state = Dbg::ThreadWaiting();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700992 if (suspendPolicy != SP_NONE) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800993 SetWaitForEventThread(basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700994 }
995
Elliott Hughes761928d2011-11-16 18:33:03 -0800996 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700997
Elliott Hughes761928d2011-11-16 18:33:03 -0800998 SuspendByPolicy(suspendPolicy);
Elliott Hughes376a7a02011-10-24 18:35:55 -0700999 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001000 }
1001
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001002 return matchCount != 0;
1003}
1004
1005/*
1006 * Announce that a class has been loaded.
1007 *
1008 * Valid mods:
1009 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1010 */
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001011bool JdwpState::PostClassPrepare(JdwpTypeTag tag, RefTypeId refTypeId, const std::string& signature, int status) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001012 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001013
1014 memset(&basket, 0, sizeof(basket));
1015 basket.classId = refTypeId;
1016 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughesa2155262011-11-16 16:26:58 -08001017 basket.className = dvmDescriptorToName(Dbg::GetClassDescriptor(basket.classId));
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001018
1019 /* suppress class prep caused by debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -08001020 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001021 LOG(VERBOSE) << "Not posting class prep caused by invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001022 return false;
1023 }
1024
Elliott Hughes761928d2011-11-16 18:33:03 -08001025 JdwpEvent** matchList = AllocMatchList(numEvents);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001026 int matchCount = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001027 ExpandBuf* pReq = NULL;
1028 JdwpSuspendPolicy suspendPolicy = SP_NONE;
Elliott Hughes761928d2011-11-16 18:33:03 -08001029 {
1030 MutexLock mu(event_lock_);
1031 FindMatchingEvents(EK_CLASS_PREPARE, &basket, matchList, &matchCount);
1032 if (matchCount != 0) {
1033 LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
Elliott Hughes4740cdf2011-12-07 14:07:12 -08001034 << "thread=" << (void*) basket.threadId << ") " << signature;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001035
Elliott Hughes761928d2011-11-16 18:33:03 -08001036 suspendPolicy = scanSuspendPolicy(matchList, matchCount);
1037 LOG(VERBOSE) << " suspendPolicy=" << suspendPolicy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001038
Elliott Hughes761928d2011-11-16 18:33:03 -08001039 if (basket.threadId == debugThreadId) {
1040 /*
1041 * JDWP says that, for a class prep in the debugger thread, we
1042 * should set threadId to null and if any threads were supposed
1043 * to be suspended then we suspend all other threads.
1044 */
1045 LOG(VERBOSE) << " NOTE: class prepare in debugger thread!";
1046 basket.threadId = 0;
1047 if (suspendPolicy == SP_EVENT_THREAD) {
1048 suspendPolicy = SP_ALL;
1049 }
1050 }
1051
1052 pReq = eventPrep();
1053 expandBufAdd1(pReq, suspendPolicy);
1054 expandBufAdd4BE(pReq, matchCount);
1055
1056 for (int i = 0; i < matchCount; i++) {
1057 expandBufAdd1(pReq, matchList[i]->eventKind);
1058 expandBufAdd4BE(pReq, matchList[i]->requestId);
1059 expandBufAdd8BE(pReq, basket.threadId);
1060
1061 expandBufAdd1(pReq, tag);
1062 expandBufAdd8BE(pReq, refTypeId);
1063 expandBufAddUtf8String(pReq, signature);
1064 expandBufAdd4BE(pReq, status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001065 }
1066 }
Elliott Hughes761928d2011-11-16 18:33:03 -08001067 CleanupMatchList(matchList, matchCount);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001068 }
1069
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001070 /* send request and possibly suspend ourselves */
1071 if (pReq != NULL) {
Elliott Hughes376a7a02011-10-24 18:35:55 -07001072 int old_state = Dbg::ThreadWaiting();
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001073 if (suspendPolicy != SP_NONE) {
Elliott Hughes761928d2011-11-16 18:33:03 -08001074 SetWaitForEventThread(basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001075 }
Elliott Hughes761928d2011-11-16 18:33:03 -08001076 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001077
Elliott Hughes761928d2011-11-16 18:33:03 -08001078 SuspendByPolicy(suspendPolicy);
Elliott Hughes376a7a02011-10-24 18:35:55 -07001079 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001080 }
1081
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001082 return matchCount != 0;
1083}
1084
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001085/*
1086 * Send up a chunk of DDM data.
1087 *
1088 * While this takes the form of a JDWP "event", it doesn't interact with
1089 * other debugger traffic, and can't suspend the VM, so we skip all of
1090 * the fun event token gymnastics.
1091 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001092void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001093 uint8_t header[kJDWPHeaderLen + 8];
1094 size_t dataLen = 0;
1095
1096 CHECK(iov != NULL);
Elliott Hughescccd84f2011-12-05 16:51:54 -08001097 CHECK_GT(iov_count, 0);
1098 CHECK_LT(iov_count, 10);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001099
1100 /*
1101 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do
1102 * this by creating a new copy of the vector with space for the header.
1103 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001104 iovec wrapiov[iov_count+1];
1105 for (int i = 0; i < iov_count; i++) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001106 wrapiov[i+1].iov_base = iov[i].iov_base;
1107 wrapiov[i+1].iov_len = iov[i].iov_len;
1108 dataLen += iov[i].iov_len;
1109 }
1110
1111 /* form the header (JDWP plus DDMS) */
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001112 Set4BE(header, sizeof(header) + dataLen);
1113 Set4BE(header+4, NextRequestSerial());
1114 Set1(header+8, 0); /* flags */
1115 Set1(header+9, kJDWPDdmCmdSet);
1116 Set1(header+10, kJDWPDdmCmd);
1117 Set4BE(header+11, type);
1118 Set4BE(header+15, dataLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001119
1120 wrapiov[0].iov_base = header;
1121 wrapiov[0].iov_len = sizeof(header);
1122
1123 /*
1124 * Make sure we're in VMWAIT in case the write blocks.
1125 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001126 int old_state = Dbg::ThreadWaiting();
Elliott Hughescccd84f2011-12-05 16:51:54 -08001127 (*transport->sendBufferedRequest)(this, wrapiov, iov_count + 1);
Elliott Hughes376a7a02011-10-24 18:35:55 -07001128 Dbg::ThreadContinuing(old_state);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001129}
1130
1131} // namespace JDWP
1132
1133} // namespace art