blob: 8b3964a095b4444c1ea346f61b29c8266bcf4be0 [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 */
Elliott Hughes872d4ec2011-10-21 17:07:15 -070016
Elliott Hughes07ed66b2012-12-12 18:34:25 -080017#include "jdwp/jdwp_event.h"
18
19#include <stddef.h> /* for offsetof() */
Elliott Hughes872d4ec2011-10-21 17:07:15 -070020#include <stdlib.h>
21#include <string.h>
Elliott Hughes872d4ec2011-10-21 17:07:15 -070022#include <unistd.h>
23
Elliott Hughes07ed66b2012-12-12 18:34:25 -080024#include "base/logging.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080025#include "base/stringprintf.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080026#include "debugger.h"
27#include "jdwp/jdwp_constants.h"
28#include "jdwp/jdwp_expand_buf.h"
29#include "jdwp/jdwp_handler.h"
30#include "jdwp/jdwp_priv.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031
Elliott Hughes872d4ec2011-10-21 17:07:15 -070032/*
33General notes:
34
35The event add/remove stuff usually happens from the debugger thread,
36in response to requests from the debugger, but can also happen as the
37result of an event in an arbitrary thread (e.g. an event with a "count"
38mod expires). It's important to keep the event list locked when processing
39events.
40
41Event posting can happen from any thread. The JDWP thread will not usually
42post anything but VM start/death, but if a JDWP request causes a class
43to be loaded, the ClassPrepare event will come from the JDWP thread.
44
45
46We can have serialization issues when we post an event to the debugger.
47For example, a thread could send an "I hit a breakpoint and am suspending
48myself" message to the debugger. Before it manages to suspend itself, the
49debugger's response ("not interested, resume thread") arrives and is
50processed. We try to resume a thread that hasn't yet suspended.
51
52This means that, after posting an event to the debugger, we need to wait
53for the event thread to suspend itself (and, potentially, all other threads)
54before processing any additional requests from the debugger. While doing
55so we need to be aware that multiple threads may be hitting breakpoints
56or other events simultaneously, so we either need to wait for all of them
57or serialize the events with each other.
58
59The current mechanism works like this:
60 Event thread:
61 - If I'm going to suspend, grab the "I am posting an event" token. Wait
62 for it if it's not currently available.
63 - Post the event to the debugger.
64 - If appropriate, suspend others and then myself. As part of suspending
65 myself, release the "I am posting" token.
66 JDWP thread:
67 - When an event arrives, see if somebody is posting an event. If so,
68 sleep until we can acquire the "I am posting an event" token. Release
69 it immediately and continue processing -- the event we have already
70 received should not interfere with other events that haven't yet
71 been posted.
72
73Some care must be taken to avoid deadlock:
74
75 - thread A and thread B exit near-simultaneously, and post thread-death
76 events with a "suspend all" clause
77 - thread A gets the event token, thread B sits and waits for it
78 - thread A wants to suspend all other threads, but thread B is waiting
79 for the token and can't be suspended
80
81So we need to mark thread B in such a way that thread A doesn't wait for it.
82
83If we just bracket the "grab event token" call with a change to VMWAIT
84before sleeping, the switch back to RUNNING state when we get the token
85will cause thread B to suspend (remember, thread A's global suspend is
86still in force, even after it releases the token). Suspending while
87holding the event token is very bad, because it prevents the JDWP thread
88from processing incoming messages.
89
90We need to change to VMWAIT state at the *start* of posting an event,
91and stay there until we either finish posting the event or decide to
92put ourselves to sleep. That way we don't interfere with anyone else and
93don't allow anyone else to interfere with us.
94*/
95
96
97#define kJdwpEventCommandSet 64
98#define kJdwpCompositeCommand 100
99
100namespace art {
101
102namespace JDWP {
103
104/*
105 * Stuff to compare against when deciding if a mod matches. Only the
106 * values for mods valid for the event being evaluated will be filled in.
107 * The rest will be zeroed.
108 */
109struct ModBasket {
110 const JdwpLocation* pLoc; /* LocationOnly */
Elliott Hughesa2155262011-11-16 16:26:58 -0800111 std::string className; /* ClassMatch/ClassExclude */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700112 ObjectId threadId; /* ThreadOnly */
113 RefTypeId classId; /* ClassOnly */
114 RefTypeId excepClassId; /* ExceptionOnly */
115 bool caught; /* ExceptionOnly */
116 FieldId field; /* FieldOnly */
117 ObjectId thisPtr; /* InstanceOnly */
118 /* nothing for StepOnly -- handled differently */
119};
120
121/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700122 * Dump an event to the log file.
123 */
124static void dumpEvent(const JdwpEvent* pEvent) {
125 LOG(INFO) << StringPrintf("Event id=0x%4x %p (prev=%p next=%p):", pEvent->requestId, pEvent, pEvent->prev, pEvent->next);
Elliott Hughesf8349362012-06-18 15:00:06 -0700126 LOG(INFO) << " kind=" << pEvent->eventKind << " susp=" << pEvent->suspend_policy << " modCount=" << pEvent->modCount;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700127
128 for (int i = 0; i < pEvent->modCount; i++) {
129 const JdwpEventMod* pMod = &pEvent->mods[i];
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800130 LOG(INFO) << " " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700131 /* TODO - show details */
132 }
133}
134
135/*
136 * Add an event to the list. Ordering is not important.
137 *
138 * If something prevents the event from being registered, e.g. it's a
139 * single-step request on a thread that doesn't exist, the event will
140 * not be added to the list, and an appropriate error will be returned.
141 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800142JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
Ian Rogers50b35e22012-10-04 10:09:15 -0700143 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700144
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700145 CHECK(pEvent != NULL);
146 CHECK(pEvent->prev == NULL);
147 CHECK(pEvent->next == NULL);
148
149 /*
150 * If one or more "break"-type mods are used, register them with
151 * the interpreter.
152 */
153 for (int i = 0; i < pEvent->modCount; i++) {
154 const JdwpEventMod* pMod = &pEvent->mods[i];
155 if (pMod->modKind == MK_LOCATION_ONLY) {
156 /* should only be for Breakpoint, Step, and Exception */
157 Dbg::WatchLocation(&pMod->locationOnly.loc);
158 } else if (pMod->modKind == MK_STEP) {
159 /* should only be for EK_SINGLE_STEP; should only be one */
160 JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
161 JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
Elliott Hughes2435a572012-02-17 16:07:41 -0800162 JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
163 if (status != ERR_NONE) {
164 return status;
165 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700166 } else if (pMod->modKind == MK_FIELD_ONLY) {
167 /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */
168 dumpEvent(pEvent); /* TODO - need for field watches */
169 }
170 }
171
172 /*
173 * Add to list.
174 */
Elliott Hughesf8349362012-06-18 15:00:06 -0700175 if (event_list_ != NULL) {
176 pEvent->next = event_list_;
177 event_list_->prev = pEvent;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700178 }
Elliott Hughesf8349362012-06-18 15:00:06 -0700179 event_list_ = pEvent;
180 ++event_list_size_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700181
182 return ERR_NONE;
183}
184
185/*
186 * Remove an event from the list. This will also remove the event from
187 * any optimization tables, e.g. breakpoints.
188 *
189 * Does not free the JdwpEvent.
190 *
191 * Grab the eventLock before calling here.
192 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800193void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700194 if (pEvent->prev == NULL) {
195 /* head of the list */
Elliott Hughesf8349362012-06-18 15:00:06 -0700196 CHECK(event_list_ == pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700197
Elliott Hughesf8349362012-06-18 15:00:06 -0700198 event_list_ = pEvent->next;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700199 } else {
200 pEvent->prev->next = pEvent->next;
201 }
202
203 if (pEvent->next != NULL) {
204 pEvent->next->prev = pEvent->prev;
205 pEvent->next = NULL;
206 }
207 pEvent->prev = NULL;
208
209 /*
210 * Unhook us from the interpreter, if necessary.
211 */
212 for (int i = 0; i < pEvent->modCount; i++) {
213 JdwpEventMod* pMod = &pEvent->mods[i];
214 if (pMod->modKind == MK_LOCATION_ONLY) {
215 /* should only be for Breakpoint, Step, and Exception */
216 Dbg::UnwatchLocation(&pMod->locationOnly.loc);
217 }
218 if (pMod->modKind == MK_STEP) {
219 /* should only be for EK_SINGLE_STEP; should only be one */
220 Dbg::UnconfigureStep(pMod->step.threadId);
221 }
222 }
223
Elliott Hughesf8349362012-06-18 15:00:06 -0700224 --event_list_size_;
225 CHECK(event_list_size_ != 0 || event_list_ == NULL);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700226}
227
228/*
229 * Remove the event with the given ID from the list.
230 *
231 * Failure to find the event isn't really an error, but it is a little
232 * weird. (It looks like Eclipse will try to be extra careful and will
233 * explicitly remove one-off single-step events.)
234 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800235void JdwpState::UnregisterEventById(uint32_t requestId) {
Ian Rogers50b35e22012-10-04 10:09:15 -0700236 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700237
Elliott Hughesf8349362012-06-18 15:00:06 -0700238 JdwpEvent* pEvent = event_list_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700239 while (pEvent != NULL) {
240 if (pEvent->requestId == requestId) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800241 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700242 EventFree(pEvent);
Elliott Hughes761928d2011-11-16 18:33:03 -0800243 return; /* there can be only one with a given ID */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700244 }
245
246 pEvent = pEvent->next;
247 }
248
249 //LOGD("Odd: no match when removing event reqId=0x%04x", requestId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700250}
251
252/*
253 * Remove all entries from the event list.
254 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800255void JdwpState::UnregisterAll() {
Ian Rogers50b35e22012-10-04 10:09:15 -0700256 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700257
Elliott Hughesf8349362012-06-18 15:00:06 -0700258 JdwpEvent* pEvent = event_list_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700259 while (pEvent != NULL) {
260 JdwpEvent* pNextEvent = pEvent->next;
261
Elliott Hughes761928d2011-11-16 18:33:03 -0800262 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700263 EventFree(pEvent);
264 pEvent = pNextEvent;
265 }
266
Elliott Hughesf8349362012-06-18 15:00:06 -0700267 event_list_ = NULL;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700268}
269
270/*
271 * Allocate a JdwpEvent struct with enough space to hold the specified
272 * number of mod records.
273 */
274JdwpEvent* EventAlloc(int numMods) {
275 JdwpEvent* newEvent;
276 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
277 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
278 memset(newEvent, 0, allocSize);
279 return newEvent;
280}
281
282/*
283 * Free a JdwpEvent.
284 *
285 * Do not call this until the event has been removed from the list.
286 */
287void EventFree(JdwpEvent* pEvent) {
288 if (pEvent == NULL) {
289 return;
290 }
291
292 /* make sure it was removed from the list */
293 CHECK(pEvent->prev == NULL);
294 CHECK(pEvent->next == NULL);
Elliott Hughesf8349362012-06-18 15:00:06 -0700295 /* want to check state->event_list_ != pEvent */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700296
297 /*
298 * Free any hairy bits in the mods.
299 */
300 for (int i = 0; i < pEvent->modCount; i++) {
301 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
302 free(pEvent->mods[i].classMatch.classPattern);
303 pEvent->mods[i].classMatch.classPattern = NULL;
304 }
305 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
306 free(pEvent->mods[i].classExclude.classPattern);
307 pEvent->mods[i].classExclude.classPattern = NULL;
308 }
309 }
310
311 free(pEvent);
312}
313
314/*
315 * Allocate storage for matching events. To keep things simple we
316 * use an array with enough storage for the entire list.
317 *
318 * The state->eventLock should be held before calling.
319 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800320static JdwpEvent** AllocMatchList(size_t event_count) {
321 return new JdwpEvent*[event_count];
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700322}
323
324/*
325 * Run through the list and remove any entries with an expired "count" mod
326 * from the event list, then free the match list.
327 */
Elliott Hughesf8349362012-06-18 15:00:06 -0700328void JdwpState::CleanupMatchList(JdwpEvent** match_list, int match_count) {
329 JdwpEvent** ppEvent = match_list;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700330
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800331 while (match_count--) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700332 JdwpEvent* pEvent = *ppEvent;
333
334 for (int i = 0; i < pEvent->modCount; i++) {
335 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800336 VLOG(jdwp) << "##### Removing expired event";
Elliott Hughes761928d2011-11-16 18:33:03 -0800337 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700338 EventFree(pEvent);
339 break;
340 }
341 }
342
343 ppEvent++;
344 }
345
Elliott Hughesf8349362012-06-18 15:00:06 -0700346 delete[] match_list;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700347}
348
349/*
350 * Match a string against a "restricted regular expression", which is just
351 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
352 *
353 * ("Restricted name globbing" might have been a better term.)
354 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800355static bool PatternMatch(const char* pattern, const std::string& target) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800356 size_t patLen = strlen(pattern);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700357 if (pattern[0] == '*') {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700358 patLen--;
Elliott Hughesa2155262011-11-16 16:26:58 -0800359 if (target.size() < patLen) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700360 return false;
361 }
Elliott Hughesa2155262011-11-16 16:26:58 -0800362 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700363 } else if (pattern[patLen-1] == '*') {
Elliott Hughesa2155262011-11-16 16:26:58 -0800364 return strncmp(pattern, target.c_str(), patLen-1) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700365 } else {
Elliott Hughesa2155262011-11-16 16:26:58 -0800366 return strcmp(pattern, target.c_str()) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700367 }
368}
369
370/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700371 * See if the event's mods match up with the contents of "basket".
372 *
373 * If we find a Count mod before rejecting an event, we decrement it. We
374 * need to do this even if later mods cause us to ignore the event.
375 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700376static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700377 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700378 JdwpEventMod* pMod = pEvent->mods;
379
380 for (int i = pEvent->modCount; i > 0; i--, pMod++) {
381 switch (pMod->modKind) {
382 case MK_COUNT:
383 CHECK_GT(pMod->count.count, 0);
384 pMod->count.count--;
385 break;
386 case MK_CONDITIONAL:
387 CHECK(false); // should not be getting these
388 break;
389 case MK_THREAD_ONLY:
390 if (pMod->threadOnly.threadId != basket->threadId) {
391 return false;
392 }
393 break;
394 case MK_CLASS_ONLY:
395 if (!Dbg::MatchType(basket->classId, pMod->classOnly.refTypeId)) {
396 return false;
397 }
398 break;
399 case MK_CLASS_MATCH:
Elliott Hughes761928d2011-11-16 18:33:03 -0800400 if (!PatternMatch(pMod->classMatch.classPattern, basket->className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700401 return false;
402 }
403 break;
404 case MK_CLASS_EXCLUDE:
Elliott Hughes761928d2011-11-16 18:33:03 -0800405 if (PatternMatch(pMod->classMatch.classPattern, basket->className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700406 return false;
407 }
408 break;
409 case MK_LOCATION_ONLY:
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800410 if (pMod->locationOnly.loc != *basket->pLoc) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700411 return false;
412 }
413 break;
414 case MK_EXCEPTION_ONLY:
415 if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket->excepClassId, pMod->exceptionOnly.refTypeId)) {
416 return false;
417 }
418 if ((basket->caught && !pMod->exceptionOnly.caught) || (!basket->caught && !pMod->exceptionOnly.uncaught)) {
419 return false;
420 }
421 break;
422 case MK_FIELD_ONLY:
423 if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) {
424 return false;
425 }
426 break;
427 case MK_STEP:
428 if (pMod->step.threadId != basket->threadId) {
429 return false;
430 }
431 break;
432 case MK_INSTANCE_ONLY:
433 if (pMod->instanceOnly.objectId != basket->thisPtr) {
434 return false;
435 }
436 break;
437 default:
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800438 LOG(FATAL) << "unknown mod kind " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700439 break;
440 }
441 }
442 return true;
443}
444
445/*
446 * Find all events of type "eventKind" with mods that match up with the
447 * rest of the arguments.
448 *
Elliott Hughesf8349362012-06-18 15:00:06 -0700449 * Found events are appended to "match_list", and "*pMatchCount" is advanced,
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700450 * so this may be called multiple times for grouped events.
451 *
452 * DO NOT call this multiple times for the same eventKind, as Count mods are
453 * decremented during the scan.
454 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700455void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, ModBasket* basket,
456 JdwpEvent** match_list, int* pMatchCount) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700457 /* start after the existing entries */
Elliott Hughesf8349362012-06-18 15:00:06 -0700458 match_list += *pMatchCount;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700459
Elliott Hughesf8349362012-06-18 15:00:06 -0700460 JdwpEvent* pEvent = event_list_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700461 while (pEvent != NULL) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800462 if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700463 *match_list++ = pEvent;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700464 (*pMatchCount)++;
465 }
466
467 pEvent = pEvent->next;
468 }
469}
470
471/*
472 * Scan through the list of matches and determine the most severe
473 * suspension policy.
474 */
Elliott Hughesf8349362012-06-18 15:00:06 -0700475static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700476 JdwpSuspendPolicy policy = SP_NONE;
477
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800478 while (match_count--) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700479 if ((*match_list)->suspend_policy > policy) {
480 policy = (*match_list)->suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700481 }
Elliott Hughesf8349362012-06-18 15:00:06 -0700482 match_list++;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700483 }
484
485 return policy;
486}
487
488/*
489 * Three possibilities:
490 * SP_NONE - do nothing
491 * SP_EVENT_THREAD - suspend ourselves
492 * SP_ALL - suspend everybody except JDWP support thread
493 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700494void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700495 VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
496 if (suspend_policy == SP_NONE) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700497 return;
498 }
499
Elliott Hughesf8349362012-06-18 15:00:06 -0700500 if (suspend_policy == SP_ALL) {
Elliott Hughes475fc232011-10-25 15:00:35 -0700501 Dbg::SuspendVM();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700502 } else {
Elliott Hughesf8349362012-06-18 15:00:06 -0700503 CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700504 }
505
506 /* this is rare but possible -- see CLASS_PREPARE handling */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700507 if (thread_self_id == debug_thread_id_) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800508 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700509 return;
510 }
511
512 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
513 while (true) {
514 pReq->ready = true;
515 Dbg::SuspendSelf();
516 pReq->ready = false;
517
518 /*
519 * The JDWP thread has told us (and possibly all other threads) to
520 * resume. See if it has left anything in our DebugInvokeReq mailbox.
521 */
Elliott Hughesd07986f2011-12-06 18:27:45 -0800522 if (!pReq->invoke_needed_) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800523 /*LOGD("SuspendByPolicy: no invoke needed");*/
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700524 break;
525 }
526
527 /* grab this before posting/suspending again */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700528 SetWaitForEventThread(thread_self_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700529
Elliott Hughesd07986f2011-12-06 18:27:45 -0800530 /* leave pReq->invoke_needed_ raised so we can check reentrancy */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700531 Dbg::ExecuteMethod(pReq);
532
Elliott Hughes475fc232011-10-25 15:00:35 -0700533 pReq->error = ERR_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700534
535 /* clear this before signaling */
Elliott Hughesd07986f2011-12-06 18:27:45 -0800536 pReq->invoke_needed_ = false;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700537
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800538 VLOG(jdwp) << "invoke complete, signaling and self-suspending";
Ian Rogersc604d732012-10-14 16:09:54 -0700539 Thread* self = Thread::Current();
540 MutexLock mu(self, pReq->lock_);
541 pReq->cond_.Signal(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700542 }
543}
544
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700545void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
546 ObjectId threadId) {
547 Thread* self = Thread::Current();
548 self->AssertThreadSuspensionIsAllowable();
549 /* send request and possibly suspend ourselves */
550 if (pReq != NULL) {
551 JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
552 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
553 if (suspend_policy != SP_NONE) {
554 SetWaitForEventThread(threadId);
555 }
556 EventFinish(pReq);
557 SuspendByPolicy(suspend_policy, thread_self_id);
558 self->TransitionFromSuspendedToRunnable();
559 }
560}
561
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700562/*
563 * Determine if there is a method invocation in progress in the current
564 * thread.
565 *
Elliott Hughes475fc232011-10-25 15:00:35 -0700566 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700567 * state. If set, we're in the process of invoking a method.
568 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800569bool JdwpState::InvokeInProgress() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700570 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
Elliott Hughesd07986f2011-12-06 18:27:45 -0800571 return pReq->invoke_needed_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700572}
573
574/*
575 * We need the JDWP thread to hold off on doing stuff while we post an
576 * event and then suspend ourselves.
577 *
578 * Call this with a threadId of zero if you just want to wait for the
579 * current thread operation to complete.
580 *
581 * This could go to sleep waiting for another thread, so it's important
582 * that the thread be marked as VMWAIT before calling here.
583 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700584void JdwpState::SetWaitForEventThread(ObjectId threadId) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700585 bool waited = false;
586
587 /* this is held for very brief periods; contention is unlikely */
Ian Rogers81d425b2012-09-27 16:03:43 -0700588 Thread* self = Thread::Current();
589 MutexLock mu(self, event_thread_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700590
591 /*
592 * If another thread is already doing stuff, wait for it. This can
593 * go to sleep indefinitely.
594 */
Elliott Hughesa21039c2012-06-21 12:09:25 -0700595 while (event_thread_id_ != 0) {
596 VLOG(jdwp) << StringPrintf("event in progress (%#llx), %#llx sleeping", event_thread_id_, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700597 waited = true;
Ian Rogersc604d732012-10-14 16:09:54 -0700598 event_thread_cond_.Wait(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700599 }
600
601 if (waited || threadId != 0) {
Elliott Hughes229feb72012-02-23 13:33:29 -0800602 VLOG(jdwp) << StringPrintf("event token grabbed (%#llx)", threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700603 }
604 if (threadId != 0) {
Elliott Hughesa21039c2012-06-21 12:09:25 -0700605 event_thread_id_ = threadId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700606 }
607}
608
609/*
610 * Clear the threadId and signal anybody waiting.
611 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700612void JdwpState::ClearWaitForEventThread() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700613 /*
614 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this
615 * function is called by dvmSuspendSelf(), and the transition back
616 * to RUNNING would confuse it.
617 */
Ian Rogersc604d732012-10-14 16:09:54 -0700618 Thread* self = Thread::Current();
619 MutexLock mu(self, event_thread_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700620
Elliott Hughesa21039c2012-06-21 12:09:25 -0700621 CHECK_NE(event_thread_id_, 0U);
622 VLOG(jdwp) << StringPrintf("cleared event token (%#llx)", event_thread_id_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700623
Elliott Hughesa21039c2012-06-21 12:09:25 -0700624 event_thread_id_ = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700625
Ian Rogersc604d732012-10-14 16:09:54 -0700626 event_thread_cond_.Signal(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700627}
628
629
630/*
631 * Prep an event. Allocates storage for the message and leaves space for
632 * the header.
633 */
634static ExpandBuf* eventPrep() {
635 ExpandBuf* pReq = expandBufAlloc();
636 expandBufAddSpace(pReq, kJDWPHeaderLen);
637 return pReq;
638}
639
640/*
641 * Write the header into the buffer and send the packet off to the debugger.
642 *
643 * Takes ownership of "pReq" (currently discards it).
644 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800645void JdwpState::EventFinish(ExpandBuf* pReq) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700646 uint8_t* buf = expandBufGetBuffer(pReq);
647
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700648 Set4BE(buf, expandBufGetLength(pReq));
Elliott Hughes761928d2011-11-16 18:33:03 -0800649 Set4BE(buf+4, NextRequestSerial());
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700650 Set1(buf+8, 0); /* flags */
651 Set1(buf+9, kJdwpEventCommandSet);
652 Set1(buf+10, kJdwpCompositeCommand);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700653
Elliott Hughes761928d2011-11-16 18:33:03 -0800654 SendRequest(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700655
656 expandBufFree(pReq);
657}
658
659
660/*
661 * Tell the debugger that we have finished initializing. This is always
662 * sent, even if the debugger hasn't requested it.
663 *
664 * This should be sent "before the main thread is started and before
665 * any application code has been executed". The thread ID in the message
666 * must be for the main thread.
667 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700668bool JdwpState::PostVMStart() {
Elliott Hughesf8349362012-06-18 15:00:06 -0700669 JdwpSuspendPolicy suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700670 ObjectId threadId = Dbg::GetThreadSelfId();
671
Elliott Hughes376a7a02011-10-24 18:35:55 -0700672 if (options_->suspend) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700673 suspend_policy = SP_ALL;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700674 } else {
Elliott Hughesf8349362012-06-18 15:00:06 -0700675 suspend_policy = SP_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700676 }
677
Elliott Hughes761928d2011-11-16 18:33:03 -0800678 ExpandBuf* pReq = eventPrep();
679 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700680 MutexLock mu(Thread::Current(), event_list_lock_); // probably don't need this here
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700681
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800682 VLOG(jdwp) << "EVENT: " << EK_VM_START;
Elliott Hughesf8349362012-06-18 15:00:06 -0700683 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700684
Elliott Hughesf8349362012-06-18 15:00:06 -0700685 expandBufAdd1(pReq, suspend_policy);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700686 expandBufAdd4BE(pReq, 1);
687
688 expandBufAdd1(pReq, EK_VM_START);
689 expandBufAdd4BE(pReq, 0); /* requestId */
690 expandBufAdd8BE(pReq, threadId);
691 }
692
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700693 /* send request and possibly suspend ourselves */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700694 SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700695
696 return true;
697}
698
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700699/*
700 * A location of interest has been reached. This handles:
701 * Breakpoint
702 * SingleStep
703 * MethodEntry
704 * MethodExit
705 * These four types must be grouped together in a single response. The
706 * "eventFlags" indicates the type of event(s) that have happened.
707 *
708 * Valid mods:
709 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
710 * LocationOnly (for breakpoint/step only)
711 * Step (for step only)
712 *
713 * Interesting test cases:
714 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY
715 * and METHOD_EXIT events with a ClassOnly mod on the method's class.
716 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1.
717 * - Single-step to a line with a breakpoint. Should get a single
718 * event message with both events in it.
719 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800720bool JdwpState::PostLocationEvent(const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700721 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700722
723 memset(&basket, 0, sizeof(basket));
724 basket.pLoc = pLoc;
Elliott Hughes74847412012-06-20 18:10:21 -0700725 basket.classId = pLoc->class_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700726 basket.thisPtr = thisPtr;
727 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughes74847412012-06-20 18:10:21 -0700728 basket.className = Dbg::GetClassName(pLoc->class_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700729
730 /*
731 * On rare occasions we may need to execute interpreted code in the VM
732 * while handling a request from the debugger. Don't fire breakpoints
733 * while doing so. (I don't think we currently do this at all, so
734 * this is mostly paranoia.)
735 */
Elliott Hughesa21039c2012-06-21 12:09:25 -0700736 if (basket.threadId == debug_thread_id_) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800737 VLOG(jdwp) << "Ignoring location event in JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700738 return false;
739 }
740
741 /*
742 * The debugger variable display tab may invoke the interpreter to format
743 * complex objects. We want to ignore breakpoints and method entry/exit
744 * traps while working on behalf of the debugger.
745 *
746 * If we don't ignore them, the VM will get hung up, because we'll
747 * suspend on a breakpoint while the debugger is still waiting for its
748 * method invocation to complete.
749 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800750 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800751 VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700752 return false;
753 }
754
Elliott Hughesf8349362012-06-18 15:00:06 -0700755 JdwpEvent** match_list = NULL;
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800756 int match_count = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700757 ExpandBuf* pReq = NULL;
Elliott Hughesf8349362012-06-18 15:00:06 -0700758 JdwpSuspendPolicy suspend_policy = SP_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700759
Elliott Hughes761928d2011-11-16 18:33:03 -0800760 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700761 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700762 match_list = AllocMatchList(event_list_size_);
Elliott Hughes86964332012-02-15 19:37:42 -0800763 if ((eventFlags & Dbg::kBreakpoint) != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700764 FindMatchingEvents(EK_BREAKPOINT, &basket, match_list, &match_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700765 }
Elliott Hughes761928d2011-11-16 18:33:03 -0800766 if ((eventFlags & Dbg::kSingleStep) != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700767 FindMatchingEvents(EK_SINGLE_STEP, &basket, match_list, &match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800768 }
769 if ((eventFlags & Dbg::kMethodEntry) != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700770 FindMatchingEvents(EK_METHOD_ENTRY, &basket, match_list, &match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800771 }
772 if ((eventFlags & Dbg::kMethodExit) != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700773 FindMatchingEvents(EK_METHOD_EXIT, &basket, match_list, &match_count);
Elliott Hughes86964332012-02-15 19:37:42 -0800774
775 // TODO: match EK_METHOD_EXIT_WITH_RETURN_VALUE too; we need to include the 'value', though.
Elliott Hughesf8349362012-06-18 15:00:06 -0700776 //FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, &basket, match_list, &match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800777 }
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800778 if (match_count != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700779 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
Elliott Hughes74847412012-06-20 18:10:21 -0700780 << basket.className << "." << Dbg::GetMethodName(pLoc->class_id, pLoc->method_id)
Elliott Hughes229feb72012-02-23 13:33:29 -0800781 << StringPrintf(" thread=%#llx dex_pc=%#llx)", basket.threadId, pLoc->dex_pc);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700782
Elliott Hughesf8349362012-06-18 15:00:06 -0700783 suspend_policy = scanSuspendPolicy(match_list, match_count);
784 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes761928d2011-11-16 18:33:03 -0800785
786 pReq = eventPrep();
Elliott Hughesf8349362012-06-18 15:00:06 -0700787 expandBufAdd1(pReq, suspend_policy);
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800788 expandBufAdd4BE(pReq, match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800789
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800790 for (int i = 0; i < match_count; i++) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700791 expandBufAdd1(pReq, match_list[i]->eventKind);
792 expandBufAdd4BE(pReq, match_list[i]->requestId);
Elliott Hughes761928d2011-11-16 18:33:03 -0800793 expandBufAdd8BE(pReq, basket.threadId);
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700794 expandBufAddLocation(pReq, *pLoc);
Elliott Hughes761928d2011-11-16 18:33:03 -0800795 }
796 }
797
Elliott Hughesf8349362012-06-18 15:00:06 -0700798 CleanupMatchList(match_list, match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800799 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700800
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700801 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700802
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800803 return match_count != 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700804}
805
806/*
807 * A thread is starting or stopping.
808 *
809 * Valid mods:
810 * Count, ThreadOnly
811 */
Elliott Hughes234ab152011-10-26 14:02:26 -0700812bool JdwpState::PostThreadChange(ObjectId threadId, bool start) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700813 CHECK_EQ(threadId, Dbg::GetThreadSelfId());
814
815 /*
816 * I don't think this can happen.
817 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800818 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700819 LOG(WARNING) << "Not posting thread change during invoke";
820 return false;
821 }
822
823 ModBasket basket;
824 memset(&basket, 0, sizeof(basket));
825 basket.threadId = threadId;
826
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700827 ExpandBuf* pReq = NULL;
Elliott Hughesf8349362012-06-18 15:00:06 -0700828 JdwpSuspendPolicy suspend_policy = SP_NONE;
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800829 int match_count = 0;
Elliott Hughes234ab152011-10-26 14:02:26 -0700830 {
831 // Don't allow the list to be updated while we scan it.
Ian Rogers50b35e22012-10-04 10:09:15 -0700832 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700833 JdwpEvent** match_list = AllocMatchList(event_list_size_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700834
Elliott Hughes234ab152011-10-26 14:02:26 -0700835 if (start) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700836 FindMatchingEvents(EK_THREAD_START, &basket, match_list, &match_count);
Elliott Hughes234ab152011-10-26 14:02:26 -0700837 } else {
Elliott Hughesf8349362012-06-18 15:00:06 -0700838 FindMatchingEvents(EK_THREAD_DEATH, &basket, match_list, &match_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700839 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700840
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800841 if (match_count != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700842 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
Elliott Hughes0cf74332012-02-23 23:14:00 -0800843 << StringPrintf("thread=%#llx", basket.threadId) << ")";
Elliott Hughes234ab152011-10-26 14:02:26 -0700844
Elliott Hughesf8349362012-06-18 15:00:06 -0700845 suspend_policy = scanSuspendPolicy(match_list, match_count);
846 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes234ab152011-10-26 14:02:26 -0700847
848 pReq = eventPrep();
Elliott Hughesf8349362012-06-18 15:00:06 -0700849 expandBufAdd1(pReq, suspend_policy);
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800850 expandBufAdd4BE(pReq, match_count);
Elliott Hughes234ab152011-10-26 14:02:26 -0700851
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800852 for (int i = 0; i < match_count; i++) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700853 expandBufAdd1(pReq, match_list[i]->eventKind);
854 expandBufAdd4BE(pReq, match_list[i]->requestId);
Elliott Hughes234ab152011-10-26 14:02:26 -0700855 expandBufAdd8BE(pReq, basket.threadId);
856 }
857 }
858
Elliott Hughesf8349362012-06-18 15:00:06 -0700859 CleanupMatchList(match_list, match_count);
Elliott Hughes234ab152011-10-26 14:02:26 -0700860 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700861
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700862 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700863
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800864 return match_count != 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700865}
866
867/*
868 * Send a polite "VM is dying" message to the debugger.
869 *
870 * Skips the usual "event token" stuff.
871 */
Elliott Hughes376a7a02011-10-24 18:35:55 -0700872bool JdwpState::PostVMDeath() {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800873 VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700874
875 ExpandBuf* pReq = eventPrep();
876 expandBufAdd1(pReq, SP_NONE);
877 expandBufAdd4BE(pReq, 1);
878
879 expandBufAdd1(pReq, EK_VM_DEATH);
880 expandBufAdd4BE(pReq, 0);
Elliott Hughes761928d2011-11-16 18:33:03 -0800881 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700882 return true;
883}
884
885/*
886 * An exception has been thrown. It may or may not have been caught.
887 *
888 * Valid mods:
889 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
890 * ExceptionOnly, InstanceOnly
891 *
892 * The "exceptionId" has not been added to the GC-visible object registry,
893 * because there's a pretty good chance that we're not going to send it
894 * up the debugger.
895 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800896bool JdwpState::PostException(const JdwpLocation* pThrowLoc,
Elliott Hughes74847412012-06-20 18:10:21 -0700897 ObjectId exceptionId, RefTypeId exceptionClassId,
898 const JdwpLocation* pCatchLoc, ObjectId thisPtr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700899 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700900
901 memset(&basket, 0, sizeof(basket));
902 basket.pLoc = pThrowLoc;
Elliott Hughes74847412012-06-20 18:10:21 -0700903 basket.classId = pThrowLoc->class_id;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700904 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughesc308a5d2012-02-16 17:12:06 -0800905 basket.className = Dbg::GetClassName(basket.classId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700906 basket.excepClassId = exceptionClassId;
Elliott Hughes74847412012-06-20 18:10:21 -0700907 basket.caught = (pCatchLoc->class_id != 0);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700908 basket.thisPtr = thisPtr;
909
910 /* don't try to post an exception caused by the debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -0800911 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800912 VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700913 return false;
914 }
915
Elliott Hughesf8349362012-06-18 15:00:06 -0700916 JdwpEvent** match_list = NULL;
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800917 int match_count = 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700918 ExpandBuf* pReq = NULL;
Elliott Hughesf8349362012-06-18 15:00:06 -0700919 JdwpSuspendPolicy suspend_policy = SP_NONE;
Elliott Hughes761928d2011-11-16 18:33:03 -0800920 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700921 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700922 match_list = AllocMatchList(event_list_size_);
923 FindMatchingEvents(EK_EXCEPTION, &basket, match_list, &match_count);
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800924 if (match_count != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700925 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total)"
Elliott Hughes0cf74332012-02-23 23:14:00 -0800926 << StringPrintf(" thread=%#llx", basket.threadId)
927 << StringPrintf(" exceptId=%#llx", exceptionId)
Elliott Hughes436e3722012-02-17 20:01:47 -0800928 << " caught=" << basket.caught << ")"
929 << " throw: " << *pThrowLoc;
Elliott Hughes74847412012-06-20 18:10:21 -0700930 if (pCatchLoc->class_id == 0) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800931 VLOG(jdwp) << " catch: (not caught)";
Elliott Hughes761928d2011-11-16 18:33:03 -0800932 } else {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800933 VLOG(jdwp) << " catch: " << *pCatchLoc;
Elliott Hughes761928d2011-11-16 18:33:03 -0800934 }
935
Elliott Hughesf8349362012-06-18 15:00:06 -0700936 suspend_policy = scanSuspendPolicy(match_list, match_count);
937 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes761928d2011-11-16 18:33:03 -0800938
939 pReq = eventPrep();
Elliott Hughesf8349362012-06-18 15:00:06 -0700940 expandBufAdd1(pReq, suspend_policy);
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800941 expandBufAdd4BE(pReq, match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -0800942
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800943 for (int i = 0; i < match_count; i++) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700944 expandBufAdd1(pReq, match_list[i]->eventKind);
945 expandBufAdd4BE(pReq, match_list[i]->requestId);
Elliott Hughes761928d2011-11-16 18:33:03 -0800946 expandBufAdd8BE(pReq, basket.threadId);
947
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700948 expandBufAddLocation(pReq, *pThrowLoc);
Elliott Hughes761928d2011-11-16 18:33:03 -0800949 expandBufAdd1(pReq, JT_OBJECT);
950 expandBufAdd8BE(pReq, exceptionId);
Elliott Hughes6e9d22c2012-06-22 15:02:37 -0700951 expandBufAddLocation(pReq, *pCatchLoc);
Elliott Hughes761928d2011-11-16 18:33:03 -0800952 }
953
954 /* don't let the GC discard it */
955 Dbg::RegisterObjectId(exceptionId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700956 }
957
Elliott Hughesf8349362012-06-18 15:00:06 -0700958 CleanupMatchList(match_list, match_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700959 }
960
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700961 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700962
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800963 return match_count != 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700964}
965
966/*
967 * Announce that a class has been loaded.
968 *
969 * Valid mods:
970 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
971 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700972bool JdwpState::PostClassPrepare(JdwpTypeTag tag, RefTypeId refTypeId, const std::string& signature,
973 int status) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700974 ModBasket basket;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700975
976 memset(&basket, 0, sizeof(basket));
977 basket.classId = refTypeId;
978 basket.threadId = Dbg::GetThreadSelfId();
Elliott Hughesc308a5d2012-02-16 17:12:06 -0800979 basket.className = Dbg::GetClassName(basket.classId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700980
981 /* suppress class prep caused by debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -0800982 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800983 VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700984 return false;
985 }
986
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700987 ExpandBuf* pReq = NULL;
Elliott Hughesf8349362012-06-18 15:00:06 -0700988 JdwpSuspendPolicy suspend_policy = SP_NONE;
989 int match_count = 0;
Elliott Hughes761928d2011-11-16 18:33:03 -0800990 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700991 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700992 JdwpEvent** match_list = AllocMatchList(event_list_size_);
993 FindMatchingEvents(EK_CLASS_PREPARE, &basket, match_list, &match_count);
Elliott Hughes2aa2e392012-02-17 17:15:43 -0800994 if (match_count != 0) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700995 VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
Elliott Hughes0cf74332012-02-23 23:14:00 -0800996 << StringPrintf("thread=%#llx", basket.threadId) << ") " << signature;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700997
Elliott Hughesf8349362012-06-18 15:00:06 -0700998 suspend_policy = scanSuspendPolicy(match_list, match_count);
999 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001000
Elliott Hughesa21039c2012-06-21 12:09:25 -07001001 if (basket.threadId == debug_thread_id_) {
Elliott Hughes761928d2011-11-16 18:33:03 -08001002 /*
1003 * JDWP says that, for a class prep in the debugger thread, we
1004 * should set threadId to null and if any threads were supposed
1005 * to be suspended then we suspend all other threads.
1006 */
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001007 VLOG(jdwp) << " NOTE: class prepare in debugger thread!";
Elliott Hughes761928d2011-11-16 18:33:03 -08001008 basket.threadId = 0;
Elliott Hughesf8349362012-06-18 15:00:06 -07001009 if (suspend_policy == SP_EVENT_THREAD) {
1010 suspend_policy = SP_ALL;
Elliott Hughes761928d2011-11-16 18:33:03 -08001011 }
1012 }
1013
1014 pReq = eventPrep();
Elliott Hughesf8349362012-06-18 15:00:06 -07001015 expandBufAdd1(pReq, suspend_policy);
Elliott Hughes2aa2e392012-02-17 17:15:43 -08001016 expandBufAdd4BE(pReq, match_count);
Elliott Hughes761928d2011-11-16 18:33:03 -08001017
Elliott Hughes2aa2e392012-02-17 17:15:43 -08001018 for (int i = 0; i < match_count; i++) {
Elliott Hughesf8349362012-06-18 15:00:06 -07001019 expandBufAdd1(pReq, match_list[i]->eventKind);
1020 expandBufAdd4BE(pReq, match_list[i]->requestId);
Elliott Hughes761928d2011-11-16 18:33:03 -08001021 expandBufAdd8BE(pReq, basket.threadId);
1022
1023 expandBufAdd1(pReq, tag);
1024 expandBufAdd8BE(pReq, refTypeId);
1025 expandBufAddUtf8String(pReq, signature);
1026 expandBufAdd4BE(pReq, status);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001027 }
1028 }
Elliott Hughesf8349362012-06-18 15:00:06 -07001029 CleanupMatchList(match_list, match_count);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001030 }
1031
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001032 SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001033
Elliott Hughes2aa2e392012-02-17 17:15:43 -08001034 return match_count != 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001035}
1036
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001037/*
1038 * Send up a chunk of DDM data.
1039 *
1040 * While this takes the form of a JDWP "event", it doesn't interact with
1041 * other debugger traffic, and can't suspend the VM, so we skip all of
1042 * the fun event token gymnastics.
1043 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001044void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001045 uint8_t header[kJDWPHeaderLen + 8];
1046 size_t dataLen = 0;
1047
1048 CHECK(iov != NULL);
Elliott Hughescccd84f2011-12-05 16:51:54 -08001049 CHECK_GT(iov_count, 0);
1050 CHECK_LT(iov_count, 10);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001051
1052 /*
1053 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do
1054 * this by creating a new copy of the vector with space for the header.
1055 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001056 iovec wrapiov[iov_count+1];
1057 for (int i = 0; i < iov_count; i++) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001058 wrapiov[i+1].iov_base = iov[i].iov_base;
1059 wrapiov[i+1].iov_len = iov[i].iov_len;
1060 dataLen += iov[i].iov_len;
1061 }
1062
1063 /* form the header (JDWP plus DDMS) */
Elliott Hughesf7c3b662011-10-27 12:04:56 -07001064 Set4BE(header, sizeof(header) + dataLen);
1065 Set4BE(header+4, NextRequestSerial());
1066 Set1(header+8, 0); /* flags */
1067 Set1(header+9, kJDWPDdmCmdSet);
1068 Set1(header+10, kJDWPDdmCmd);
1069 Set4BE(header+11, type);
1070 Set4BE(header+15, dataLen);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001071
1072 wrapiov[0].iov_base = header;
1073 wrapiov[0].iov_len = sizeof(header);
1074
Ian Rogers15bf2d32012-08-28 17:33:04 -07001075 // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
1076 // than mutator for lock ordering reasons.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001077 Thread* self = Thread::Current();
Ian Rogers15bf2d32012-08-28 17:33:04 -07001078 bool safe_to_release_mutator_lock_over_send;
1079 for (size_t i=0; i < kMutatorLock; ++i) {
Ian Rogers81d425b2012-09-27 16:03:43 -07001080 if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) {
Ian Rogers15bf2d32012-08-28 17:33:04 -07001081 safe_to_release_mutator_lock_over_send = false;
1082 break;
1083 }
1084 }
1085 if (safe_to_release_mutator_lock_over_send) {
1086 // Change state to waiting to allow GC, ... while we're sending.
1087 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1088 (*transport_->sendBufferedRequest)(this, wrapiov, iov_count + 1);
1089 self->TransitionFromSuspendedToRunnable();
1090 } else {
1091 // Send and possibly block GC...
1092 (*transport_->sendBufferedRequest)(this, wrapiov, iov_count + 1);
1093 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001094}
1095
1096} // namespace JDWP
1097
1098} // namespace art