blob: ff75268daa087aaff098a69dec6abed7c634c283 [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
Mathieu Chartierc7853442015-03-27 14:35:38 -070024#include "art_field-inl.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080025#include "base/logging.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080026#include "base/stringprintf.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080027#include "debugger.h"
28#include "jdwp/jdwp_constants.h"
29#include "jdwp/jdwp_expand_buf.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080030#include "jdwp/jdwp_priv.h"
Sebastien Hertz6995c602014-09-09 12:10:13 +020031#include "jdwp/object_registry.h"
Sebastien Hertz6995c602014-09-09 12:10:13 +020032#include "scoped_thread_state_change.h"
Ian Rogers693ff612013-02-01 10:56:12 -080033#include "thread-inl.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080034
Sebastien Hertz261bc042015-04-08 09:36:07 +020035#include "handle_scope-inl.h"
36
Elliott Hughes872d4ec2011-10-21 17:07:15 -070037/*
38General notes:
39
40The event add/remove stuff usually happens from the debugger thread,
41in response to requests from the debugger, but can also happen as the
42result of an event in an arbitrary thread (e.g. an event with a "count"
43mod expires). It's important to keep the event list locked when processing
44events.
45
46Event posting can happen from any thread. The JDWP thread will not usually
47post anything but VM start/death, but if a JDWP request causes a class
48to be loaded, the ClassPrepare event will come from the JDWP thread.
49
50
51We can have serialization issues when we post an event to the debugger.
52For example, a thread could send an "I hit a breakpoint and am suspending
53myself" message to the debugger. Before it manages to suspend itself, the
54debugger's response ("not interested, resume thread") arrives and is
55processed. We try to resume a thread that hasn't yet suspended.
56
57This means that, after posting an event to the debugger, we need to wait
58for the event thread to suspend itself (and, potentially, all other threads)
59before processing any additional requests from the debugger. While doing
60so we need to be aware that multiple threads may be hitting breakpoints
61or other events simultaneously, so we either need to wait for all of them
62or serialize the events with each other.
63
64The current mechanism works like this:
65 Event thread:
66 - If I'm going to suspend, grab the "I am posting an event" token. Wait
67 for it if it's not currently available.
68 - Post the event to the debugger.
69 - If appropriate, suspend others and then myself. As part of suspending
70 myself, release the "I am posting" token.
71 JDWP thread:
72 - When an event arrives, see if somebody is posting an event. If so,
73 sleep until we can acquire the "I am posting an event" token. Release
74 it immediately and continue processing -- the event we have already
75 received should not interfere with other events that haven't yet
76 been posted.
77
78Some care must be taken to avoid deadlock:
79
80 - thread A and thread B exit near-simultaneously, and post thread-death
81 events with a "suspend all" clause
82 - thread A gets the event token, thread B sits and waits for it
83 - thread A wants to suspend all other threads, but thread B is waiting
84 for the token and can't be suspended
85
86So we need to mark thread B in such a way that thread A doesn't wait for it.
87
88If we just bracket the "grab event token" call with a change to VMWAIT
89before sleeping, the switch back to RUNNING state when we get the token
90will cause thread B to suspend (remember, thread A's global suspend is
91still in force, even after it releases the token). Suspending while
92holding the event token is very bad, because it prevents the JDWP thread
93from processing incoming messages.
94
95We need to change to VMWAIT state at the *start* of posting an event,
96and stay there until we either finish posting the event or decide to
97put ourselves to sleep. That way we don't interfere with anyone else and
98don't allow anyone else to interfere with us.
99*/
100
101
102#define kJdwpEventCommandSet 64
103#define kJdwpCompositeCommand 100
104
105namespace art {
106
107namespace JDWP {
108
109/*
110 * Stuff to compare against when deciding if a mod matches. Only the
111 * values for mods valid for the event being evaluated will be filled in.
112 * The rest will be zeroed.
Sebastien Hertz261bc042015-04-08 09:36:07 +0200113 * Must be allocated on the stack only. This is enforced by removing the
114 * operator new.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700115 */
116struct ModBasket {
Sebastien Hertz261bc042015-04-08 09:36:07 +0200117 explicit ModBasket(Thread* self)
118 : hs(self), pLoc(nullptr), thread(self),
119 locationClass(hs.NewHandle<mirror::Class>(nullptr)),
120 exceptionClass(hs.NewHandle<mirror::Class>(nullptr)),
121 caught(false),
122 field(nullptr),
123 thisPtr(hs.NewHandle<mirror::Object>(nullptr)) { }
jeffhao162fd332013-01-08 16:21:01 -0800124
Sebastien Hertz261bc042015-04-08 09:36:07 +0200125 StackHandleScope<3> hs;
126 const EventLocation* pLoc; /* LocationOnly */
127 std::string className; /* ClassMatch/ClassExclude */
128 Thread* const thread; /* ThreadOnly */
129 MutableHandle<mirror::Class> locationClass; /* ClassOnly */
130 MutableHandle<mirror::Class> exceptionClass; /* ExceptionOnly */
131 bool caught; /* ExceptionOnly */
132 ArtField* field; /* FieldOnly */
133 MutableHandle<mirror::Object> thisPtr; /* InstanceOnly */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700134 /* nothing for StepOnly -- handled differently */
Sebastien Hertz261bc042015-04-08 09:36:07 +0200135
136 private:
137 DISALLOW_ALLOCATION(); // forbids allocation on the heap.
138 DISALLOW_IMPLICIT_CONSTRUCTORS(ModBasket);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700139};
140
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100141static bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
Sebastien Hertzf3928792014-11-17 19:00:37 +0100142 if (!Dbg::RequiresDeoptimization()) {
143 // We don't need deoptimization for debugging.
144 return false;
145 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100146 switch (eventKind) {
147 case EK_METHOD_ENTRY:
148 case EK_METHOD_EXIT:
149 case EK_METHOD_EXIT_WITH_RETURN_VALUE:
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200150 case EK_FIELD_ACCESS:
151 case EK_FIELD_MODIFICATION:
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100152 return true;
153 default:
154 return false;
155 }
156}
157
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200158// Returns the instrumentation event the DebugInstrumentationListener must
159// listen to in order to properly report the given JDWP event to the debugger.
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800160static uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200161 switch (eventKind) {
162 case EK_BREAKPOINT:
163 case EK_SINGLE_STEP:
164 return instrumentation::Instrumentation::kDexPcMoved;
165 case EK_EXCEPTION:
166 case EK_EXCEPTION_CATCH:
167 return instrumentation::Instrumentation::kExceptionCaught;
168 case EK_METHOD_ENTRY:
169 return instrumentation::Instrumentation::kMethodEntered;
170 case EK_METHOD_EXIT:
171 case EK_METHOD_EXIT_WITH_RETURN_VALUE:
172 return instrumentation::Instrumentation::kMethodExited;
173 case EK_FIELD_ACCESS:
174 return instrumentation::Instrumentation::kFieldRead;
175 case EK_FIELD_MODIFICATION:
176 return instrumentation::Instrumentation::kFieldWritten;
177 default:
178 return 0;
179 }
180}
181
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700182/*
183 * Add an event to the list. Ordering is not important.
184 *
185 * If something prevents the event from being registered, e.g. it's a
186 * single-step request on a thread that doesn't exist, the event will
187 * not be added to the list, and an appropriate error will be returned.
188 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800189JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200190 CHECK(pEvent != nullptr);
191 CHECK(pEvent->prev == nullptr);
192 CHECK(pEvent->next == nullptr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700193
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200194 {
195 /*
196 * If one or more "break"-type mods are used, register them with
197 * the interpreter.
198 */
199 DeoptimizationRequest req;
200 for (int i = 0; i < pEvent->modCount; i++) {
201 const JdwpEventMod* pMod = &pEvent->mods[i];
202 if (pMod->modKind == MK_LOCATION_ONLY) {
Sebastien Hertz033aabf2014-10-08 13:54:55 +0200203 // Should only concern breakpoint, field access, field modification, step, and exception
204 // events.
205 // However breakpoint requires specific handling. Field access, field modification and step
206 // events need full deoptimization to be reported while exception event is reported during
207 // exception handling.
208 if (pEvent->eventKind == EK_BREAKPOINT) {
209 Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
210 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200211 } else if (pMod->modKind == MK_STEP) {
212 /* should only be for EK_SINGLE_STEP; should only be one */
213 JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
214 JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
215 JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
216 if (status != ERR_NONE) {
217 return status;
218 }
Elliott Hughes2435a572012-02-17 16:07:41 -0800219 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700220 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200221 if (NeedsFullDeoptimization(pEvent->eventKind)) {
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700222 CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
223 CHECK(req.Method() == nullptr);
224 req.SetKind(DeoptimizationRequest::kFullDeoptimization);
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200225 }
226 Dbg::RequestDeoptimization(req);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700227 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200228 uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
229 if (instrumentation_event != 0) {
230 DeoptimizationRequest req;
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700231 req.SetKind(DeoptimizationRequest::kRegisterForEvent);
232 req.SetInstrumentationEvent(instrumentation_event);
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200233 Dbg::RequestDeoptimization(req);
Sebastien Hertz4d25df32014-03-21 17:44:46 +0100234 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700235
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100236 {
237 /*
238 * Add to list.
239 */
240 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200241 if (event_list_ != nullptr) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100242 pEvent->next = event_list_;
243 event_list_->prev = pEvent;
244 }
245 event_list_ = pEvent;
246 ++event_list_size_;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700247 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100248
249 Dbg::ManageDeoptimization();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700250
251 return ERR_NONE;
252}
253
254/*
255 * Remove an event from the list. This will also remove the event from
256 * any optimization tables, e.g. breakpoints.
257 *
258 * Does not free the JdwpEvent.
259 *
260 * Grab the eventLock before calling here.
261 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800262void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200263 if (pEvent->prev == nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700264 /* head of the list */
Elliott Hughesf8349362012-06-18 15:00:06 -0700265 CHECK(event_list_ == pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700266
Elliott Hughesf8349362012-06-18 15:00:06 -0700267 event_list_ = pEvent->next;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700268 } else {
269 pEvent->prev->next = pEvent->next;
270 }
271
Sebastien Hertz7d955652014-10-22 10:57:10 +0200272 if (pEvent->next != nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700273 pEvent->next->prev = pEvent->prev;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200274 pEvent->next = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700275 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200276 pEvent->prev = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700277
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200278 {
279 /*
280 * Unhook us from the interpreter, if necessary.
281 */
282 DeoptimizationRequest req;
283 for (int i = 0; i < pEvent->modCount; i++) {
284 JdwpEventMod* pMod = &pEvent->mods[i];
285 if (pMod->modKind == MK_LOCATION_ONLY) {
Sebastien Hertz033aabf2014-10-08 13:54:55 +0200286 // Like in RegisterEvent, we need specific handling for breakpoint only.
287 if (pEvent->eventKind == EK_BREAKPOINT) {
288 Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
289 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200290 }
291 if (pMod->modKind == MK_STEP) {
292 /* should only be for EK_SINGLE_STEP; should only be one */
293 Dbg::UnconfigureStep(pMod->step.threadId);
294 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700295 }
Daniel Mihalyieb076692014-08-22 17:33:31 +0200296 if (NeedsFullDeoptimization(pEvent->eventKind)) {
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700297 CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
298 CHECK(req.Method() == nullptr);
299 req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700300 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200301 Dbg::RequestDeoptimization(req);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700302 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200303 uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
304 if (instrumentation_event != 0) {
305 DeoptimizationRequest req;
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700306 req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
307 req.SetInstrumentationEvent(instrumentation_event);
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200308 Dbg::RequestDeoptimization(req);
Sebastien Hertz4d25df32014-03-21 17:44:46 +0100309 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700310
Elliott Hughesf8349362012-06-18 15:00:06 -0700311 --event_list_size_;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200312 CHECK(event_list_size_ != 0 || event_list_ == nullptr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700313}
314
315/*
316 * Remove the event with the given ID from the list.
317 *
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700318 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800319void JdwpState::UnregisterEventById(uint32_t requestId) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100320 bool found = false;
321 {
322 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700323
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100324 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
325 if (pEvent->requestId == requestId) {
326 found = true;
327 UnregisterEvent(pEvent);
328 EventFree(pEvent);
329 break; /* there can be only one with a given ID */
330 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700331 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700332 }
333
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100334 if (found) {
335 Dbg::ManageDeoptimization();
336 } else {
Sebastien Hertzf272af42014-09-18 10:20:42 +0200337 // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
338 // try to be extra careful and will explicitly remove one-off single-step events (using a
339 // 'count' event modifier of 1). So the event may have already been removed as part of the
340 // event notification (see JdwpState::CleanupMatchList).
341 VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100342 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700343}
344
345/*
346 * Remove all entries from the event list.
347 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800348void JdwpState::UnregisterAll() {
Ian Rogers50b35e22012-10-04 10:09:15 -0700349 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700350
Elliott Hughesf8349362012-06-18 15:00:06 -0700351 JdwpEvent* pEvent = event_list_;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200352 while (pEvent != nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700353 JdwpEvent* pNextEvent = pEvent->next;
354
Elliott Hughes761928d2011-11-16 18:33:03 -0800355 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700356 EventFree(pEvent);
357 pEvent = pNextEvent;
358 }
359
Sebastien Hertz7d955652014-10-22 10:57:10 +0200360 event_list_ = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700361}
362
363/*
364 * Allocate a JdwpEvent struct with enough space to hold the specified
365 * number of mod records.
366 */
367JdwpEvent* EventAlloc(int numMods) {
368 JdwpEvent* newEvent;
369 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
370 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
371 memset(newEvent, 0, allocSize);
372 return newEvent;
373}
374
375/*
376 * Free a JdwpEvent.
377 *
378 * Do not call this until the event has been removed from the list.
379 */
380void EventFree(JdwpEvent* pEvent) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200381 if (pEvent == nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700382 return;
383 }
384
385 /* make sure it was removed from the list */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200386 CHECK(pEvent->prev == nullptr);
387 CHECK(pEvent->next == nullptr);
Elliott Hughesf8349362012-06-18 15:00:06 -0700388 /* want to check state->event_list_ != pEvent */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700389
390 /*
391 * Free any hairy bits in the mods.
392 */
393 for (int i = 0; i < pEvent->modCount; i++) {
394 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
395 free(pEvent->mods[i].classMatch.classPattern);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200396 pEvent->mods[i].classMatch.classPattern = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700397 }
398 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
399 free(pEvent->mods[i].classExclude.classPattern);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200400 pEvent->mods[i].classExclude.classPattern = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700401 }
402 }
403
404 free(pEvent);
405}
406
407/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700408 * Run through the list and remove any entries with an expired "count" mod
Sebastien Hertz7d955652014-10-22 10:57:10 +0200409 * from the event list.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700410 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200411void JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
412 for (JdwpEvent* pEvent : match_list) {
413 for (int i = 0; i < pEvent->modCount; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700414 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200415 VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
416 pEvent->requestId);
Elliott Hughes761928d2011-11-16 18:33:03 -0800417 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700418 EventFree(pEvent);
419 break;
420 }
421 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700422 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700423}
424
425/*
426 * Match a string against a "restricted regular expression", which is just
427 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
428 *
429 * ("Restricted name globbing" might have been a better term.)
430 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800431static bool PatternMatch(const char* pattern, const std::string& target) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800432 size_t patLen = strlen(pattern);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700433 if (pattern[0] == '*') {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700434 patLen--;
Elliott Hughesa2155262011-11-16 16:26:58 -0800435 if (target.size() < patLen) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700436 return false;
437 }
Elliott Hughesa2155262011-11-16 16:26:58 -0800438 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700439 } else if (pattern[patLen-1] == '*') {
Elliott Hughesa2155262011-11-16 16:26:58 -0800440 return strncmp(pattern, target.c_str(), patLen-1) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700441 } else {
Elliott Hughesa2155262011-11-16 16:26:58 -0800442 return strcmp(pattern, target.c_str()) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700443 }
444}
445
446/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700447 * See if the event's mods match up with the contents of "basket".
448 *
449 * If we find a Count mod before rejecting an event, we decrement it. We
450 * need to do this even if later mods cause us to ignore the event.
451 */
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200452static bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700453 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700454 JdwpEventMod* pMod = pEvent->mods;
455
456 for (int i = pEvent->modCount; i > 0; i--, pMod++) {
457 switch (pMod->modKind) {
458 case MK_COUNT:
459 CHECK_GT(pMod->count.count, 0);
460 pMod->count.count--;
Sebastien Hertz43207792014-04-15 16:03:27 +0200461 if (pMod->count.count > 0) {
462 return false;
463 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700464 break;
465 case MK_CONDITIONAL:
466 CHECK(false); // should not be getting these
467 break;
468 case MK_THREAD_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200469 if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700470 return false;
471 }
472 break;
473 case MK_CLASS_ONLY:
Sebastien Hertz261bc042015-04-08 09:36:07 +0200474 if (!Dbg::MatchType(basket.locationClass.Get(), pMod->classOnly.refTypeId)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700475 return false;
476 }
477 break;
478 case MK_CLASS_MATCH:
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200479 if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700480 return false;
481 }
482 break;
483 case MK_CLASS_EXCLUDE:
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200484 if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700485 return false;
486 }
487 break;
488 case MK_LOCATION_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200489 if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700490 return false;
491 }
492 break;
493 case MK_EXCEPTION_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200494 if (pMod->exceptionOnly.refTypeId != 0 &&
Sebastien Hertz261bc042015-04-08 09:36:07 +0200495 !Dbg::MatchType(basket.exceptionClass.Get(), pMod->exceptionOnly.refTypeId)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700496 return false;
497 }
Sebastien Hertz6995c602014-09-09 12:10:13 +0200498 if ((basket.caught && !pMod->exceptionOnly.caught) ||
499 (!basket.caught && !pMod->exceptionOnly.uncaught)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700500 return false;
501 }
502 break;
503 case MK_FIELD_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200504 if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700505 return false;
506 }
507 break;
508 case MK_STEP:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200509 if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700510 return false;
511 }
512 break;
513 case MK_INSTANCE_ONLY:
Sebastien Hertz261bc042015-04-08 09:36:07 +0200514 if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr.Get())) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700515 return false;
516 }
517 break;
518 default:
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800519 LOG(FATAL) << "unknown mod kind " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700520 break;
521 }
522 }
523 return true;
524}
525
526/*
Sebastien Hertz7d955652014-10-22 10:57:10 +0200527 * Find all events of type "event_kind" with mods that match up with the
528 * rest of the arguments while holding the event list lock. This method
529 * is used by FindMatchingEvents below.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700530 *
Sebastien Hertz7d955652014-10-22 10:57:10 +0200531 * Found events are appended to "match_list" so this may be called multiple times for grouped
532 * events.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700533 *
534 * DO NOT call this multiple times for the same eventKind, as Count mods are
535 * decremented during the scan.
536 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200537void JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
538 std::vector<JdwpEvent*>* match_list) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200539 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200540 if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
541 match_list->push_back(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700542 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700543 }
544}
545
546/*
Sebastien Hertz7d955652014-10-22 10:57:10 +0200547 * Find all events of type "event_kind" with mods that match up with the
548 * rest of the arguments and return true if at least one event matches,
549 * false otherwise.
550 *
551 * Found events are appended to "match_list" so this may be called multiple
552 * times for grouped events.
553 *
554 * DO NOT call this multiple times for the same eventKind, as Count mods are
555 * decremented during the scan.
556 */
557bool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
558 std::vector<JdwpEvent*>* match_list) {
559 MutexLock mu(Thread::Current(), event_list_lock_);
560 match_list->reserve(event_list_size_);
561 FindMatchingEventsLocked(event_kind, basket, match_list);
562 return !match_list->empty();
563}
564
565/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700566 * Scan through the list of matches and determine the most severe
567 * suspension policy.
568 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200569static JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700570 JdwpSuspendPolicy policy = SP_NONE;
571
Sebastien Hertz7d955652014-10-22 10:57:10 +0200572 for (JdwpEvent* pEvent : match_list) {
573 if (pEvent->suspend_policy > policy) {
574 policy = pEvent->suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700575 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700576 }
577
578 return policy;
579}
580
581/*
582 * Three possibilities:
583 * SP_NONE - do nothing
584 * SP_EVENT_THREAD - suspend ourselves
585 * SP_ALL - suspend everybody except JDWP support thread
586 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700587void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700588 VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
589 if (suspend_policy == SP_NONE) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700590 return;
591 }
592
Elliott Hughesf8349362012-06-18 15:00:06 -0700593 if (suspend_policy == SP_ALL) {
Elliott Hughes475fc232011-10-25 15:00:35 -0700594 Dbg::SuspendVM();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700595 } else {
Elliott Hughesf8349362012-06-18 15:00:06 -0700596 CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700597 }
598
599 /* this is rare but possible -- see CLASS_PREPARE handling */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700600 if (thread_self_id == debug_thread_id_) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800601 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700602 return;
603 }
604
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700605 while (true) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700606 Dbg::SuspendSelf();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700607
608 /*
609 * The JDWP thread has told us (and possibly all other threads) to
610 * resume. See if it has left anything in our DebugInvokeReq mailbox.
611 */
Sebastien Hertz1558b572015-02-25 15:05:59 +0100612 DebugInvokeReq* const pReq = Dbg::GetInvokeReq();
613 if (pReq == nullptr) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800614 /*LOGD("SuspendByPolicy: no invoke needed");*/
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700615 break;
616 }
617
618 /* grab this before posting/suspending again */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100619 AcquireJdwpTokenForEvent(thread_self_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700620
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700621 Dbg::ExecuteMethod(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700622 }
623}
624
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700625void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
626 ObjectId threadId) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200627 Thread* const self = Thread::Current();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700628 self->AssertThreadSuspensionIsAllowable();
Sebastien Hertz7d955652014-10-22 10:57:10 +0200629 CHECK(pReq != nullptr);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700630 /* send request and possibly suspend ourselves */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200631 JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
632 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
633 if (suspend_policy != SP_NONE) {
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100634 AcquireJdwpTokenForEvent(threadId);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700635 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200636 EventFinish(pReq);
Sebastien Hertz813b9602015-02-24 14:56:59 +0100637 {
638 // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING.
639 ScopedThreadStateChange stsc(self, kSuspended);
640 SuspendByPolicy(suspend_policy, thread_self_id);
641 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200642 self->TransitionFromSuspendedToRunnable();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700643}
644
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700645/*
646 * Determine if there is a method invocation in progress in the current
647 * thread.
648 *
Elliott Hughes475fc232011-10-25 15:00:35 -0700649 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700650 * state. If set, we're in the process of invoking a method.
651 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800652bool JdwpState::InvokeInProgress() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700653 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
Sebastien Hertz1558b572015-02-25 15:05:59 +0100654 return pReq != nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700655}
656
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100657void JdwpState::AcquireJdwpTokenForCommand() {
658 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
659 SetWaitForJdwpToken(debug_thread_id_);
660}
661
662void JdwpState::ReleaseJdwpTokenForCommand() {
663 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
664 ClearWaitForJdwpToken();
665}
666
667void JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) {
668 CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
669 CHECK_NE(debug_thread_id_, threadId) << "Not expected debug thread";
670 SetWaitForJdwpToken(threadId);
671}
672
673void JdwpState::ReleaseJdwpTokenForEvent() {
674 CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
675 ClearWaitForJdwpToken();
676}
677
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700678/*
679 * We need the JDWP thread to hold off on doing stuff while we post an
680 * event and then suspend ourselves.
681 *
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700682 * This could go to sleep waiting for another thread, so it's important
683 * that the thread be marked as VMWAIT before calling here.
684 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100685void JdwpState::SetWaitForJdwpToken(ObjectId threadId) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700686 bool waited = false;
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100687 Thread* const self = Thread::Current();
688 CHECK_NE(threadId, 0u);
689 CHECK_NE(self->GetState(), kRunnable);
690 Locks::mutator_lock_->AssertNotHeld(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700691
692 /* this is held for very brief periods; contention is unlikely */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100693 MutexLock mu(self, jdwp_token_lock_);
694
695 CHECK_NE(jdwp_token_owner_thread_id_, threadId) << "Thread is already holding event thread lock";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700696
697 /*
698 * If another thread is already doing stuff, wait for it. This can
699 * go to sleep indefinitely.
700 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100701 while (jdwp_token_owner_thread_id_ != 0) {
Ian Rogersd9e4e0c2014-01-23 20:11:40 -0800702 VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100703 jdwp_token_owner_thread_id_, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700704 waited = true;
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100705 jdwp_token_cond_.Wait(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700706 }
707
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100708 if (waited || threadId != debug_thread_id_) {
Ian Rogersd9e4e0c2014-01-23 20:11:40 -0800709 VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700710 }
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100711 jdwp_token_owner_thread_id_ = threadId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700712}
713
714/*
715 * Clear the threadId and signal anybody waiting.
716 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100717void JdwpState::ClearWaitForJdwpToken() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700718 /*
719 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100720 * function is called by Dbg::SuspendSelf(), and the transition back
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700721 * to RUNNING would confuse it.
722 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100723 Thread* const self = Thread::Current();
724 MutexLock mu(self, jdwp_token_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700725
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100726 CHECK_NE(jdwp_token_owner_thread_id_, 0U);
727 VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700728
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100729 jdwp_token_owner_thread_id_ = 0;
730 jdwp_token_cond_.Signal(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700731}
732
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700733/*
734 * Prep an event. Allocates storage for the message and leaves space for
735 * the header.
736 */
737static ExpandBuf* eventPrep() {
738 ExpandBuf* pReq = expandBufAlloc();
739 expandBufAddSpace(pReq, kJDWPHeaderLen);
740 return pReq;
741}
742
743/*
744 * Write the header into the buffer and send the packet off to the debugger.
745 *
746 * Takes ownership of "pReq" (currently discards it).
747 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800748void JdwpState::EventFinish(ExpandBuf* pReq) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700749 uint8_t* buf = expandBufGetBuffer(pReq);
750
Elliott Hughesf7c3b662011-10-27 12:04:56 -0700751 Set4BE(buf, expandBufGetLength(pReq));
Sebastien Hertz7d955652014-10-22 10:57:10 +0200752 Set4BE(buf + 4, NextRequestSerial());
753 Set1(buf + 8, 0); /* flags */
754 Set1(buf + 9, kJdwpEventCommandSet);
755 Set1(buf + 10, kJdwpCompositeCommand);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700756
Elliott Hughes761928d2011-11-16 18:33:03 -0800757 SendRequest(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700758
759 expandBufFree(pReq);
760}
761
762
763/*
764 * Tell the debugger that we have finished initializing. This is always
765 * sent, even if the debugger hasn't requested it.
766 *
767 * This should be sent "before the main thread is started and before
768 * any application code has been executed". The thread ID in the message
769 * must be for the main thread.
770 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200771void JdwpState::PostVMStart() {
772 JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700773 ObjectId threadId = Dbg::GetThreadSelfId();
774
Sebastien Hertz7d955652014-10-22 10:57:10 +0200775 VLOG(jdwp) << "EVENT: " << EK_VM_START;
776 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700777
Elliott Hughes761928d2011-11-16 18:33:03 -0800778 ExpandBuf* pReq = eventPrep();
Sebastien Hertz7d955652014-10-22 10:57:10 +0200779 expandBufAdd1(pReq, suspend_policy);
780 expandBufAdd4BE(pReq, 1);
781 expandBufAdd1(pReq, EK_VM_START);
782 expandBufAdd4BE(pReq, 0); /* requestId */
783 expandBufAddObjectId(pReq, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700784
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100785 Dbg::ManageDeoptimization();
786
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700787 /* send request and possibly suspend ourselves */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700788 SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700789}
790
Sebastien Hertz7d955652014-10-22 10:57:10 +0200791static void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200792 ObjectId thread_id)
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200793 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200794 for (size_t i = 0, e = match_list.size(); i < e; ++i) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200795 JdwpEvent* pEvent = match_list[i];
796 VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
797 << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
798 }
799 std::string thread_name;
Sebastien Hertz6995c602014-09-09 12:10:13 +0200800 JdwpError error = Dbg::GetThreadName(thread_id, &thread_name);
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200801 if (error != JDWP::ERR_NONE) {
802 thread_name = "<unknown>";
803 }
Sebastien Hertz6995c602014-09-09 12:10:13 +0200804 VLOG(jdwp) << StringPrintf(" thread=%#" PRIx64, thread_id) << " " << thread_name;
805}
806
807static void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
808 JDWP::JdwpLocation* jdwp_location)
809 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
810 DCHECK(event_location != nullptr);
811 DCHECK(jdwp_location != nullptr);
812 Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200813}
814
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700815/*
816 * A location of interest has been reached. This handles:
817 * Breakpoint
818 * SingleStep
819 * MethodEntry
820 * MethodExit
821 * These four types must be grouped together in a single response. The
822 * "eventFlags" indicates the type of event(s) that have happened.
823 *
824 * Valid mods:
825 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
826 * LocationOnly (for breakpoint/step only)
827 * Step (for step only)
828 *
829 * Interesting test cases:
830 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY
831 * and METHOD_EXIT events with a ClassOnly mod on the method's class.
832 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1.
833 * - Single-step to a line with a breakpoint. Should get a single
834 * event message with both events in it.
835 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200836void JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200837 int eventFlags, const JValue* returnValue) {
838 DCHECK(pLoc != nullptr);
839 DCHECK(pLoc->method != nullptr);
840 DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
841
Sebastien Hertz261bc042015-04-08 09:36:07 +0200842 ModBasket basket(Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700843 basket.pLoc = pLoc;
Sebastien Hertz261bc042015-04-08 09:36:07 +0200844 basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
845 basket.thisPtr.Assign(thisPtr);
846 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700847
848 /*
849 * On rare occasions we may need to execute interpreted code in the VM
850 * while handling a request from the debugger. Don't fire breakpoints
851 * while doing so. (I don't think we currently do this at all, so
852 * this is mostly paranoia.)
853 */
Sebastien Hertz6995c602014-09-09 12:10:13 +0200854 if (basket.thread == GetDebugThread()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800855 VLOG(jdwp) << "Ignoring location event in JDWP thread";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200856 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700857 }
858
859 /*
860 * The debugger variable display tab may invoke the interpreter to format
861 * complex objects. We want to ignore breakpoints and method entry/exit
862 * traps while working on behalf of the debugger.
863 *
864 * If we don't ignore them, the VM will get hung up, because we'll
865 * suspend on a breakpoint while the debugger is still waiting for its
866 * method invocation to complete.
867 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800868 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800869 VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200870 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700871 }
872
Sebastien Hertz7d955652014-10-22 10:57:10 +0200873 std::vector<JdwpEvent*> match_list;
Elliott Hughes761928d2011-11-16 18:33:03 -0800874 {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200875 // We use the locked version because we have multiple possible match events.
876 MutexLock mu(Thread::Current(), event_list_lock_);
877 match_list.reserve(event_list_size_);
878 if ((eventFlags & Dbg::kBreakpoint) != 0) {
879 FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800880 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200881 if ((eventFlags & Dbg::kSingleStep) != 0) {
882 FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800883 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200884 if ((eventFlags & Dbg::kMethodEntry) != 0) {
885 FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
Sebastien Hertz6995c602014-09-09 12:10:13 +0200886 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200887 if ((eventFlags & Dbg::kMethodExit) != 0) {
888 FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
889 FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
890 }
891 }
892 if (match_list.empty()) {
893 // No matching event.
894 return;
895 }
896 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
897
898 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
899 JDWP::JdwpLocation jdwp_location;
900 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
901
902 if (VLOG_IS_ON(jdwp)) {
903 LogMatchingEventsAndThread(match_list, thread_id);
904 VLOG(jdwp) << " location=" << jdwp_location;
905 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
906 }
907
908 ExpandBuf* pReq = eventPrep();
909 expandBufAdd1(pReq, suspend_policy);
910 expandBufAdd4BE(pReq, match_list.size());
911
912 for (const JdwpEvent* pEvent : match_list) {
913 expandBufAdd1(pReq, pEvent->eventKind);
914 expandBufAdd4BE(pReq, pEvent->requestId);
915 expandBufAddObjectId(pReq, thread_id);
916 expandBufAddLocation(pReq, jdwp_location);
917 if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
918 Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
919 }
920 }
921
922 {
923 MutexLock mu(Thread::Current(), event_list_lock_);
924 CleanupMatchList(match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800925 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700926
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100927 Dbg::ManageDeoptimization();
928
Sebastien Hertz6995c602014-09-09 12:10:13 +0200929 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700930}
931
Mathieu Chartierc7853442015-03-27 14:35:38 -0700932void JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200933 mirror::Object* this_object, const JValue* fieldValue,
934 bool is_modification) {
935 DCHECK(pLoc != nullptr);
936 DCHECK(field != nullptr);
937 DCHECK_EQ(fieldValue != nullptr, is_modification);
938 DCHECK_EQ(field->IsStatic(), this_object == nullptr);
939
Sebastien Hertz261bc042015-04-08 09:36:07 +0200940 ModBasket basket(Thread::Current());
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200941 basket.pLoc = pLoc;
Sebastien Hertz261bc042015-04-08 09:36:07 +0200942 basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
943 basket.thisPtr.Assign(this_object);
944 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Sebastien Hertz6995c602014-09-09 12:10:13 +0200945 basket.field = field;
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200946
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200947 if (InvokeInProgress()) {
Sebastien Hertz261bc042015-04-08 09:36:07 +0200948 VLOG(jdwp) << "Not posting field event during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200949 return;
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200950 }
951
Sebastien Hertz7d955652014-10-22 10:57:10 +0200952 std::vector<JdwpEvent*> match_list;
953 const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
954 if (!FindMatchingEvents(match_kind, basket, &match_list)) {
955 // No matching event.
956 return;
957 }
958
959 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
960 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
961 ObjectRegistry* registry = Dbg::GetObjectRegistry();
962 ObjectId instance_id = registry->Add(basket.thisPtr);
963 RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
964 FieldId field_id = Dbg::ToFieldId(field);
965 JDWP::JdwpLocation jdwp_location;
966 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
967
968 if (VLOG_IS_ON(jdwp)) {
969 LogMatchingEventsAndThread(match_list, thread_id);
970 VLOG(jdwp) << " location=" << jdwp_location;
971 VLOG(jdwp) << StringPrintf(" this=%#" PRIx64, instance_id);
972 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, field_type_id) << " "
973 << Dbg::GetClassName(field_id);
Mathieu Chartierd3ed9a32015-04-10 14:23:35 -0700974 VLOG(jdwp) << StringPrintf(" field=%#" PRIx64, field_id) << " "
Sebastien Hertz7d955652014-10-22 10:57:10 +0200975 << Dbg::GetFieldName(field_id);
976 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
977 }
978
979 ExpandBuf* pReq = eventPrep();
980 expandBufAdd1(pReq, suspend_policy);
981 expandBufAdd4BE(pReq, match_list.size());
982
983 // Get field's reference type tag.
984 JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
985
986 // Get instance type tag.
987 uint8_t tag;
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200988 {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200989 ScopedObjectAccessUnchecked soa(Thread::Current());
Sebastien Hertz261bc042015-04-08 09:36:07 +0200990 tag = Dbg::TagFromObject(soa, basket.thisPtr.Get());
Sebastien Hertz7d955652014-10-22 10:57:10 +0200991 }
992
993 for (const JdwpEvent* pEvent : match_list) {
994 expandBufAdd1(pReq, pEvent->eventKind);
995 expandBufAdd4BE(pReq, pEvent->requestId);
996 expandBufAddObjectId(pReq, thread_id);
997 expandBufAddLocation(pReq, jdwp_location);
998 expandBufAdd1(pReq, type_tag);
999 expandBufAddRefTypeId(pReq, field_type_id);
1000 expandBufAddFieldId(pReq, field_id);
1001 expandBufAdd1(pReq, tag);
1002 expandBufAddObjectId(pReq, instance_id);
1003 if (is_modification) {
1004 Dbg::OutputFieldValue(field_id, fieldValue, pReq);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001005 }
Sebastien Hertz7d955652014-10-22 10:57:10 +02001006 }
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +02001007
Sebastien Hertz7d955652014-10-22 10:57:10 +02001008 {
1009 MutexLock mu(Thread::Current(), event_list_lock_);
1010 CleanupMatchList(match_list);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001011 }
1012
1013 Dbg::ManageDeoptimization();
1014
Sebastien Hertz6995c602014-09-09 12:10:13 +02001015 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001016}
1017
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001018/*
1019 * A thread is starting or stopping.
1020 *
1021 * Valid mods:
1022 * Count, ThreadOnly
1023 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001024void JdwpState::PostThreadChange(Thread* thread, bool start) {
Sebastien Hertz6995c602014-09-09 12:10:13 +02001025 CHECK_EQ(thread, Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001026
1027 /*
1028 * I don't think this can happen.
1029 */
Elliott Hughes761928d2011-11-16 18:33:03 -08001030 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001031 LOG(WARNING) << "Not posting thread change during invoke";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001032 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001033 }
1034
Sebastien Hertz107e7572014-12-18 11:13:15 +01001035 // We need the java.lang.Thread object associated to the starting/ending
1036 // thread to get its JDWP id. Therefore we can't report event if there
1037 // is no Java peer. This happens when the runtime shuts down and re-attaches
1038 // the current thread without creating a Java peer.
1039 if (thread->GetPeer() == nullptr) {
1040 return;
1041 }
1042
Sebastien Hertz261bc042015-04-08 09:36:07 +02001043 ModBasket basket(thread);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001044
Sebastien Hertz7d955652014-10-22 10:57:10 +02001045 std::vector<JdwpEvent*> match_list;
1046 const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
1047 if (!FindMatchingEvents(match_kind, basket, &match_list)) {
1048 // No matching event.
1049 return;
1050 }
1051
1052 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1053 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1054
1055 if (VLOG_IS_ON(jdwp)) {
1056 LogMatchingEventsAndThread(match_list, thread_id);
1057 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1058 }
1059
1060 ExpandBuf* pReq = eventPrep();
1061 expandBufAdd1(pReq, suspend_policy);
1062 expandBufAdd4BE(pReq, match_list.size());
1063
1064 for (const JdwpEvent* pEvent : match_list) {
1065 expandBufAdd1(pReq, pEvent->eventKind);
1066 expandBufAdd4BE(pReq, pEvent->requestId);
1067 expandBufAdd8BE(pReq, thread_id);
1068 }
1069
Elliott Hughes234ab152011-10-26 14:02:26 -07001070 {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001071 MutexLock mu(Thread::Current(), event_list_lock_);
1072 CleanupMatchList(match_list);
Elliott Hughes234ab152011-10-26 14:02:26 -07001073 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001074
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001075 Dbg::ManageDeoptimization();
1076
Sebastien Hertz6995c602014-09-09 12:10:13 +02001077 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001078}
1079
1080/*
1081 * Send a polite "VM is dying" message to the debugger.
1082 *
1083 * Skips the usual "event token" stuff.
1084 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001085bool JdwpState::PostVMDeath() {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001086 VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001087
1088 ExpandBuf* pReq = eventPrep();
1089 expandBufAdd1(pReq, SP_NONE);
1090 expandBufAdd4BE(pReq, 1);
1091
1092 expandBufAdd1(pReq, EK_VM_DEATH);
1093 expandBufAdd4BE(pReq, 0);
Elliott Hughes761928d2011-11-16 18:33:03 -08001094 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001095 return true;
1096}
1097
1098/*
1099 * An exception has been thrown. It may or may not have been caught.
1100 *
1101 * Valid mods:
1102 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1103 * ExceptionOnly, InstanceOnly
1104 *
1105 * The "exceptionId" has not been added to the GC-visible object registry,
1106 * because there's a pretty good chance that we're not going to send it
1107 * up the debugger.
1108 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001109void JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
Sebastien Hertz6995c602014-09-09 12:10:13 +02001110 const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
1111 DCHECK(exception_object != nullptr);
1112 DCHECK(pThrowLoc != nullptr);
1113 DCHECK(pCatchLoc != nullptr);
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001114 if (pThrowLoc->method != nullptr) {
1115 DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1116 } else {
1117 VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1118 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001119
Sebastien Hertz261bc042015-04-08 09:36:07 +02001120 ModBasket basket(Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001121 basket.pLoc = pThrowLoc;
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001122 if (pThrowLoc->method != nullptr) {
Sebastien Hertz261bc042015-04-08 09:36:07 +02001123 basket.locationClass.Assign(pThrowLoc->method->GetDeclaringClass());
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001124 }
Sebastien Hertz261bc042015-04-08 09:36:07 +02001125 basket.className = Dbg::GetClassName(basket.locationClass.Get());
1126 basket.exceptionClass.Assign(exception_object->GetClass());
Sebastien Hertz6995c602014-09-09 12:10:13 +02001127 basket.caught = (pCatchLoc->method != 0);
Sebastien Hertz261bc042015-04-08 09:36:07 +02001128 basket.thisPtr.Assign(thisPtr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001129
1130 /* don't try to post an exception caused by the debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -08001131 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001132 VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001133 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001134 }
1135
Sebastien Hertz7d955652014-10-22 10:57:10 +02001136 std::vector<JdwpEvent*> match_list;
1137 if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
1138 // No matching event.
1139 return;
1140 }
1141
1142 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1143 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1144 ObjectRegistry* registry = Dbg::GetObjectRegistry();
1145 ObjectId exceptionId = registry->Add(exception_object);
1146 JDWP::JdwpLocation jdwp_throw_location;
1147 JDWP::JdwpLocation jdwp_catch_location;
1148 SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
1149 SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
1150
1151 if (VLOG_IS_ON(jdwp)) {
1152 std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
1153
1154 LogMatchingEventsAndThread(match_list, thread_id);
1155 VLOG(jdwp) << " throwLocation=" << jdwp_throw_location;
1156 if (jdwp_catch_location.class_id == 0) {
1157 VLOG(jdwp) << " catchLocation=uncaught";
1158 } else {
1159 VLOG(jdwp) << " catchLocation=" << jdwp_catch_location;
1160 }
1161 VLOG(jdwp) << StringPrintf(" exception=%#" PRIx64, exceptionId) << " "
1162 << exceptionClassName;
1163 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1164 }
1165
1166 ExpandBuf* pReq = eventPrep();
1167 expandBufAdd1(pReq, suspend_policy);
1168 expandBufAdd4BE(pReq, match_list.size());
1169
1170 for (const JdwpEvent* pEvent : match_list) {
1171 expandBufAdd1(pReq, pEvent->eventKind);
1172 expandBufAdd4BE(pReq, pEvent->requestId);
1173 expandBufAddObjectId(pReq, thread_id);
1174 expandBufAddLocation(pReq, jdwp_throw_location);
1175 expandBufAdd1(pReq, JT_OBJECT);
1176 expandBufAddObjectId(pReq, exceptionId);
1177 expandBufAddLocation(pReq, jdwp_catch_location);
1178 }
1179
Elliott Hughes761928d2011-11-16 18:33:03 -08001180 {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001181 MutexLock mu(Thread::Current(), event_list_lock_);
1182 CleanupMatchList(match_list);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001183 }
1184
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001185 Dbg::ManageDeoptimization();
1186
Sebastien Hertz6995c602014-09-09 12:10:13 +02001187 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001188}
1189
1190/*
1191 * Announce that a class has been loaded.
1192 *
1193 * Valid mods:
1194 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1195 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001196void JdwpState::PostClassPrepare(mirror::Class* klass) {
Sebastien Hertz6995c602014-09-09 12:10:13 +02001197 DCHECK(klass != nullptr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001198
Sebastien Hertz261bc042015-04-08 09:36:07 +02001199 ModBasket basket(Thread::Current());
1200 basket.locationClass.Assign(klass);
1201 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001202
1203 /* suppress class prep caused by debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -08001204 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001205 VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001206 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001207 }
1208
Sebastien Hertz7d955652014-10-22 10:57:10 +02001209 std::vector<JdwpEvent*> match_list;
1210 if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
1211 // No matching event.
1212 return;
1213 }
1214
1215 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1216 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1217 ObjectRegistry* registry = Dbg::GetObjectRegistry();
1218 RefTypeId class_id = registry->AddRefType(basket.locationClass);
1219
1220 // OLD-TODO - we currently always send both "verified" and "prepared" since
1221 // debuggers seem to like that. There might be some advantage to honesty,
1222 // since the class may not yet be verified.
1223 int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
Sebastien Hertz261bc042015-04-08 09:36:07 +02001224 JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass.Get());
Sebastien Hertz7d955652014-10-22 10:57:10 +02001225 std::string temp;
1226 std::string signature(basket.locationClass->GetDescriptor(&temp));
1227
1228 if (VLOG_IS_ON(jdwp)) {
1229 LogMatchingEventsAndThread(match_list, thread_id);
1230 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, class_id) << " " << signature;
1231 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1232 }
1233
1234 if (thread_id == debug_thread_id_) {
1235 /*
1236 * JDWP says that, for a class prep in the debugger thread, we
1237 * should set thread to null and if any threads were supposed
1238 * to be suspended then we suspend all other threads.
1239 */
1240 VLOG(jdwp) << " NOTE: class prepare in debugger thread!";
1241 thread_id = 0;
1242 if (suspend_policy == SP_EVENT_THREAD) {
1243 suspend_policy = SP_ALL;
1244 }
1245 }
1246
1247 ExpandBuf* pReq = eventPrep();
1248 expandBufAdd1(pReq, suspend_policy);
1249 expandBufAdd4BE(pReq, match_list.size());
1250
1251 for (const JdwpEvent* pEvent : match_list) {
1252 expandBufAdd1(pReq, pEvent->eventKind);
1253 expandBufAdd4BE(pReq, pEvent->requestId);
1254 expandBufAddObjectId(pReq, thread_id);
1255 expandBufAdd1(pReq, tag);
1256 expandBufAddRefTypeId(pReq, class_id);
1257 expandBufAddUtf8String(pReq, signature);
1258 expandBufAdd4BE(pReq, status);
1259 }
1260
Elliott Hughes761928d2011-11-16 18:33:03 -08001261 {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001262 MutexLock mu(Thread::Current(), event_list_lock_);
1263 CleanupMatchList(match_list);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001264 }
1265
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001266 Dbg::ManageDeoptimization();
1267
Sebastien Hertz6995c602014-09-09 12:10:13 +02001268 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001269}
1270
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001271/*
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001272 * Setup the header for a chunk of DDM data.
1273 */
1274void JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size,
1275 uint8_t* out_header) {
1276 CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8));
1277 /* form the header (JDWP plus DDMS) */
1278 Set4BE(out_header, header_size + data_len);
1279 Set4BE(out_header + 4, NextRequestSerial());
1280 Set1(out_header + 8, 0); /* flags */
1281 Set1(out_header + 9, kJDWPDdmCmdSet);
1282 Set1(out_header + 10, kJDWPDdmCmd);
1283 Set4BE(out_header + 11, type);
1284 Set4BE(out_header + 15, data_len);
1285}
1286
1287/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001288 * Send up a chunk of DDM data.
1289 *
1290 * While this takes the form of a JDWP "event", it doesn't interact with
1291 * other debugger traffic, and can't suspend the VM, so we skip all of
1292 * the fun event token gymnastics.
1293 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001294void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001295 uint8_t header[kJDWPHeaderLen + 8] = { 0 };
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001296 size_t dataLen = 0;
1297
Sebastien Hertz7d955652014-10-22 10:57:10 +02001298 CHECK(iov != nullptr);
Elliott Hughescccd84f2011-12-05 16:51:54 -08001299 CHECK_GT(iov_count, 0);
1300 CHECK_LT(iov_count, 10);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001301
1302 /*
1303 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do
1304 * this by creating a new copy of the vector with space for the header.
1305 */
Brian Carlstromf5293522013-07-19 00:24:00 -07001306 std::vector<iovec> wrapiov;
1307 wrapiov.push_back(iovec());
Elliott Hughescccd84f2011-12-05 16:51:54 -08001308 for (int i = 0; i < iov_count; i++) {
Brian Carlstromf5293522013-07-19 00:24:00 -07001309 wrapiov.push_back(iov[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001310 dataLen += iov[i].iov_len;
1311 }
1312
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001313 SetupChunkHeader(type, dataLen, sizeof(header), header);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001314
1315 wrapiov[0].iov_base = header;
1316 wrapiov[0].iov_len = sizeof(header);
1317
Ian Rogers15bf2d32012-08-28 17:33:04 -07001318 // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
1319 // than mutator for lock ordering reasons.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001320 Thread* self = Thread::Current();
Ian Rogers62d6c772013-02-27 08:32:07 -08001321 bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
1322 if (safe_to_release_mutator_lock_over_send) {
Brian Carlstrom38f85e42013-07-18 14:45:22 -07001323 for (size_t i = 0; i < kMutatorLock; ++i) {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001324 if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -08001325 safe_to_release_mutator_lock_over_send = false;
1326 break;
1327 }
Ian Rogers15bf2d32012-08-28 17:33:04 -07001328 }
1329 }
1330 if (safe_to_release_mutator_lock_over_send) {
1331 // Change state to waiting to allow GC, ... while we're sending.
1332 self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
Brian Carlstromf5293522013-07-19 00:24:00 -07001333 SendBufferedRequest(type, wrapiov);
Ian Rogers15bf2d32012-08-28 17:33:04 -07001334 self->TransitionFromSuspendedToRunnable();
1335 } else {
1336 // Send and possibly block GC...
Brian Carlstromf5293522013-07-19 00:24:00 -07001337 SendBufferedRequest(type, wrapiov);
Ian Rogers15bf2d32012-08-28 17:33:04 -07001338 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001339}
1340
1341} // namespace JDWP
1342
1343} // namespace art