blob: 9409b7661f29d78100c16f32846c8c73e72493c9 [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
Andreas Gampe46ee31b2016-12-14 10:11:49 -080024#include "android-base/stringprintf.h"
25
Mathieu Chartierc7853442015-03-27 14:35:38 -070026#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070027#include "art_method-inl.h"
Andreas Gampe57943812017-12-06 21:39:13 -080028#include "base/logging.h" // For VLOG.
Elliott Hughes07ed66b2012-12-12 18:34:25 -080029#include "debugger.h"
30#include "jdwp/jdwp_constants.h"
31#include "jdwp/jdwp_expand_buf.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080032#include "jdwp/jdwp_priv.h"
Sebastien Hertz6995c602014-09-09 12:10:13 +020033#include "jdwp/object_registry.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070034#include "scoped_thread_state_change-inl.h"
Ian Rogers693ff612013-02-01 10:56:12 -080035#include "thread-inl.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080036
Sebastien Hertz261bc042015-04-08 09:36:07 +020037#include "handle_scope-inl.h"
38
Elliott Hughes872d4ec2011-10-21 17:07:15 -070039/*
40General notes:
41
42The event add/remove stuff usually happens from the debugger thread,
43in response to requests from the debugger, but can also happen as the
44result of an event in an arbitrary thread (e.g. an event with a "count"
45mod expires). It's important to keep the event list locked when processing
46events.
47
48Event posting can happen from any thread. The JDWP thread will not usually
49post anything but VM start/death, but if a JDWP request causes a class
50to be loaded, the ClassPrepare event will come from the JDWP thread.
51
52
53We can have serialization issues when we post an event to the debugger.
54For example, a thread could send an "I hit a breakpoint and am suspending
55myself" message to the debugger. Before it manages to suspend itself, the
56debugger's response ("not interested, resume thread") arrives and is
57processed. We try to resume a thread that hasn't yet suspended.
58
59This means that, after posting an event to the debugger, we need to wait
60for the event thread to suspend itself (and, potentially, all other threads)
61before processing any additional requests from the debugger. While doing
62so we need to be aware that multiple threads may be hitting breakpoints
63or other events simultaneously, so we either need to wait for all of them
64or serialize the events with each other.
65
66The current mechanism works like this:
67 Event thread:
68 - If I'm going to suspend, grab the "I am posting an event" token. Wait
69 for it if it's not currently available.
70 - Post the event to the debugger.
71 - If appropriate, suspend others and then myself. As part of suspending
72 myself, release the "I am posting" token.
73 JDWP thread:
74 - When an event arrives, see if somebody is posting an event. If so,
75 sleep until we can acquire the "I am posting an event" token. Release
76 it immediately and continue processing -- the event we have already
77 received should not interfere with other events that haven't yet
78 been posted.
79
80Some care must be taken to avoid deadlock:
81
82 - thread A and thread B exit near-simultaneously, and post thread-death
83 events with a "suspend all" clause
84 - thread A gets the event token, thread B sits and waits for it
85 - thread A wants to suspend all other threads, but thread B is waiting
86 for the token and can't be suspended
87
88So we need to mark thread B in such a way that thread A doesn't wait for it.
89
90If we just bracket the "grab event token" call with a change to VMWAIT
91before sleeping, the switch back to RUNNING state when we get the token
92will cause thread B to suspend (remember, thread A's global suspend is
93still in force, even after it releases the token). Suspending while
94holding the event token is very bad, because it prevents the JDWP thread
95from processing incoming messages.
96
97We need to change to VMWAIT state at the *start* of posting an event,
98and stay there until we either finish posting the event or decide to
99put ourselves to sleep. That way we don't interfere with anyone else and
100don't allow anyone else to interfere with us.
101*/
102
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700103namespace art {
104
105namespace JDWP {
106
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800107using android::base::StringPrintf;
108
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700109/*
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:
Alex Light6e1607e2017-08-23 10:06:18 -0700167 return instrumentation::Instrumentation::kExceptionThrown;
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200168 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 */
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800240 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
Alex Light5643caf2017-02-08 11:39:07 -0800254void JdwpState::UnregisterLocationEventsOnClass(ObjPtr<mirror::Class> klass) {
255 VLOG(jdwp) << "Removing events within " << klass->PrettyClass();
256 StackHandleScope<1> hs(Thread::Current());
257 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
258 std::vector<JdwpEvent*> to_remove;
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800259 MutexLock mu(Thread::Current(), event_list_lock_);
Alex Light5643caf2017-02-08 11:39:07 -0800260 for (JdwpEvent* cur_event = event_list_; cur_event != nullptr; cur_event = cur_event->next) {
261 // Fill in the to_remove list
262 bool found_event = false;
263 for (int i = 0; i < cur_event->modCount && !found_event; i++) {
264 JdwpEventMod& mod = cur_event->mods[i];
265 switch (mod.modKind) {
266 case MK_LOCATION_ONLY: {
267 JdwpLocation& loc = mod.locationOnly.loc;
268 JdwpError error;
269 ObjPtr<mirror::Class> breakpoint_class(
270 Dbg::GetObjectRegistry()->Get<art::mirror::Class*>(loc.class_id, &error));
271 DCHECK_EQ(error, ERR_NONE);
272 if (breakpoint_class == h_klass.Get()) {
273 to_remove.push_back(cur_event);
274 found_event = true;
275 }
276 break;
277 }
278 default:
279 // TODO Investigate how we should handle non-locationOnly events.
280 break;
281 }
282 }
283 }
284
285 for (JdwpEvent* event : to_remove) {
286 UnregisterEvent(event);
287 EventFree(event);
288 }
289}
290
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700291/*
292 * Remove an event from the list. This will also remove the event from
293 * any optimization tables, e.g. breakpoints.
294 *
295 * Does not free the JdwpEvent.
296 *
297 * Grab the eventLock before calling here.
298 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800299void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200300 if (pEvent->prev == nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700301 /* head of the list */
Elliott Hughesf8349362012-06-18 15:00:06 -0700302 CHECK(event_list_ == pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700303
Elliott Hughesf8349362012-06-18 15:00:06 -0700304 event_list_ = pEvent->next;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700305 } else {
306 pEvent->prev->next = pEvent->next;
307 }
308
Sebastien Hertz7d955652014-10-22 10:57:10 +0200309 if (pEvent->next != nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700310 pEvent->next->prev = pEvent->prev;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200311 pEvent->next = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700312 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200313 pEvent->prev = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700314
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200315 {
316 /*
317 * Unhook us from the interpreter, if necessary.
318 */
319 DeoptimizationRequest req;
320 for (int i = 0; i < pEvent->modCount; i++) {
321 JdwpEventMod* pMod = &pEvent->mods[i];
322 if (pMod->modKind == MK_LOCATION_ONLY) {
Sebastien Hertz033aabf2014-10-08 13:54:55 +0200323 // Like in RegisterEvent, we need specific handling for breakpoint only.
324 if (pEvent->eventKind == EK_BREAKPOINT) {
325 Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
326 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200327 }
328 if (pMod->modKind == MK_STEP) {
329 /* should only be for EK_SINGLE_STEP; should only be one */
330 Dbg::UnconfigureStep(pMod->step.threadId);
331 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700332 }
Daniel Mihalyieb076692014-08-22 17:33:31 +0200333 if (NeedsFullDeoptimization(pEvent->eventKind)) {
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700334 CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
335 CHECK(req.Method() == nullptr);
336 req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700337 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200338 Dbg::RequestDeoptimization(req);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700339 }
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200340 uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
341 if (instrumentation_event != 0) {
342 DeoptimizationRequest req;
Hiroshi Yamauchi0ec17d22014-07-07 13:07:08 -0700343 req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
344 req.SetInstrumentationEvent(instrumentation_event);
Sebastien Hertz42cd43f2014-05-13 14:15:41 +0200345 Dbg::RequestDeoptimization(req);
Sebastien Hertz4d25df32014-03-21 17:44:46 +0100346 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700347
Elliott Hughesf8349362012-06-18 15:00:06 -0700348 --event_list_size_;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200349 CHECK(event_list_size_ != 0 || event_list_ == nullptr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700350}
351
352/*
353 * Remove the event with the given ID from the list.
354 *
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700355 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800356void JdwpState::UnregisterEventById(uint32_t requestId) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100357 bool found = false;
358 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800359 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700360
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100361 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
362 if (pEvent->requestId == requestId) {
363 found = true;
364 UnregisterEvent(pEvent);
365 EventFree(pEvent);
366 break; /* there can be only one with a given ID */
367 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700368 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700369 }
370
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100371 if (found) {
372 Dbg::ManageDeoptimization();
373 } else {
Sebastien Hertzf272af42014-09-18 10:20:42 +0200374 // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
375 // try to be extra careful and will explicitly remove one-off single-step events (using a
376 // 'count' event modifier of 1). So the event may have already been removed as part of the
377 // event notification (see JdwpState::CleanupMatchList).
378 VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100379 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700380}
381
382/*
383 * Remove all entries from the event list.
384 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800385void JdwpState::UnregisterAll() {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800386 MutexLock mu(Thread::Current(), event_list_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700387
Elliott Hughesf8349362012-06-18 15:00:06 -0700388 JdwpEvent* pEvent = event_list_;
Sebastien Hertz7d955652014-10-22 10:57:10 +0200389 while (pEvent != nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700390 JdwpEvent* pNextEvent = pEvent->next;
391
Elliott Hughes761928d2011-11-16 18:33:03 -0800392 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700393 EventFree(pEvent);
394 pEvent = pNextEvent;
395 }
396
Sebastien Hertz7d955652014-10-22 10:57:10 +0200397 event_list_ = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700398}
399
400/*
401 * Allocate a JdwpEvent struct with enough space to hold the specified
402 * number of mod records.
403 */
404JdwpEvent* EventAlloc(int numMods) {
405 JdwpEvent* newEvent;
406 int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
407 newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
408 memset(newEvent, 0, allocSize);
409 return newEvent;
410}
411
412/*
413 * Free a JdwpEvent.
414 *
415 * Do not call this until the event has been removed from the list.
416 */
417void EventFree(JdwpEvent* pEvent) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200418 if (pEvent == nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700419 return;
420 }
421
422 /* make sure it was removed from the list */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200423 CHECK(pEvent->prev == nullptr);
424 CHECK(pEvent->next == nullptr);
Elliott Hughesf8349362012-06-18 15:00:06 -0700425 /* want to check state->event_list_ != pEvent */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700426
427 /*
428 * Free any hairy bits in the mods.
429 */
430 for (int i = 0; i < pEvent->modCount; i++) {
431 if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
432 free(pEvent->mods[i].classMatch.classPattern);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200433 pEvent->mods[i].classMatch.classPattern = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700434 }
435 if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
436 free(pEvent->mods[i].classExclude.classPattern);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200437 pEvent->mods[i].classExclude.classPattern = nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700438 }
439 }
440
441 free(pEvent);
442}
443
444/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700445 * Run through the list and remove any entries with an expired "count" mod
Sebastien Hertz7d955652014-10-22 10:57:10 +0200446 * from the event list.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700447 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200448void JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
449 for (JdwpEvent* pEvent : match_list) {
450 for (int i = 0; i < pEvent->modCount; ++i) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700451 if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200452 VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
453 pEvent->requestId);
Elliott Hughes761928d2011-11-16 18:33:03 -0800454 UnregisterEvent(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700455 EventFree(pEvent);
456 break;
457 }
458 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700459 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700460}
461
462/*
463 * Match a string against a "restricted regular expression", which is just
464 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
465 *
466 * ("Restricted name globbing" might have been a better term.)
467 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800468static bool PatternMatch(const char* pattern, const std::string& target) {
Elliott Hughesa2155262011-11-16 16:26:58 -0800469 size_t patLen = strlen(pattern);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700470 if (pattern[0] == '*') {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700471 patLen--;
Elliott Hughesa2155262011-11-16 16:26:58 -0800472 if (target.size() < patLen) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700473 return false;
474 }
Elliott Hughesa2155262011-11-16 16:26:58 -0800475 return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700476 } else if (pattern[patLen-1] == '*') {
Elliott Hughesa2155262011-11-16 16:26:58 -0800477 return strncmp(pattern, target.c_str(), patLen-1) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700478 } else {
Elliott Hughesa2155262011-11-16 16:26:58 -0800479 return strcmp(pattern, target.c_str()) == 0;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700480 }
481}
482
483/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700484 * See if the event's mods match up with the contents of "basket".
485 *
486 * If we find a Count mod before rejecting an event, we decrement it. We
487 * need to do this even if later mods cause us to ignore the event.
488 */
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200489static bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700490 REQUIRES_SHARED(Locks::mutator_lock_) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700491 JdwpEventMod* pMod = pEvent->mods;
492
493 for (int i = pEvent->modCount; i > 0; i--, pMod++) {
494 switch (pMod->modKind) {
495 case MK_COUNT:
496 CHECK_GT(pMod->count.count, 0);
497 pMod->count.count--;
Sebastien Hertz43207792014-04-15 16:03:27 +0200498 if (pMod->count.count > 0) {
499 return false;
500 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700501 break;
502 case MK_CONDITIONAL:
Andreas Gampef45d61c2017-06-07 10:29:33 -0700503 LOG(FATAL) << "Unexpected MK_CONDITIONAL"; // should not be getting these
504 UNREACHABLE();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700505 case MK_THREAD_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200506 if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700507 return false;
508 }
509 break;
510 case MK_CLASS_ONLY:
Sebastien Hertz261bc042015-04-08 09:36:07 +0200511 if (!Dbg::MatchType(basket.locationClass.Get(), pMod->classOnly.refTypeId)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700512 return false;
513 }
514 break;
515 case MK_CLASS_MATCH:
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200516 if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700517 return false;
518 }
519 break;
520 case MK_CLASS_EXCLUDE:
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200521 if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700522 return false;
523 }
524 break;
525 case MK_LOCATION_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200526 if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700527 return false;
528 }
529 break;
530 case MK_EXCEPTION_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200531 if (pMod->exceptionOnly.refTypeId != 0 &&
Sebastien Hertz261bc042015-04-08 09:36:07 +0200532 !Dbg::MatchType(basket.exceptionClass.Get(), pMod->exceptionOnly.refTypeId)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700533 return false;
534 }
Sebastien Hertz6995c602014-09-09 12:10:13 +0200535 if ((basket.caught && !pMod->exceptionOnly.caught) ||
536 (!basket.caught && !pMod->exceptionOnly.uncaught)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700537 return false;
538 }
539 break;
540 case MK_FIELD_ONLY:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200541 if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700542 return false;
543 }
544 break;
545 case MK_STEP:
Sebastien Hertz6995c602014-09-09 12:10:13 +0200546 if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700547 return false;
548 }
549 break;
550 case MK_INSTANCE_ONLY:
Sebastien Hertz261bc042015-04-08 09:36:07 +0200551 if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr.Get())) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700552 return false;
553 }
554 break;
555 default:
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800556 LOG(FATAL) << "unknown mod kind " << pMod->modKind;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700557 break;
558 }
559 }
560 return true;
561}
562
563/*
Sebastien Hertz7d955652014-10-22 10:57:10 +0200564 * Find all events of type "event_kind" with mods that match up with the
565 * rest of the arguments while holding the event list lock. This method
566 * is used by FindMatchingEvents below.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700567 *
Sebastien Hertz7d955652014-10-22 10:57:10 +0200568 * Found events are appended to "match_list" so this may be called multiple times for grouped
569 * events.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700570 *
571 * DO NOT call this multiple times for the same eventKind, as Count mods are
572 * decremented during the scan.
573 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200574void JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
575 std::vector<JdwpEvent*>* match_list) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200576 for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200577 if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
578 match_list->push_back(pEvent);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700579 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700580 }
581}
582
583/*
Sebastien Hertz7d955652014-10-22 10:57:10 +0200584 * Find all events of type "event_kind" with mods that match up with the
585 * rest of the arguments and return true if at least one event matches,
586 * false otherwise.
587 *
588 * Found events are appended to "match_list" so this may be called multiple
589 * times for grouped events.
590 *
591 * DO NOT call this multiple times for the same eventKind, as Count mods are
592 * decremented during the scan.
593 */
594bool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
595 std::vector<JdwpEvent*>* match_list) {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800596 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200597 match_list->reserve(event_list_size_);
598 FindMatchingEventsLocked(event_kind, basket, match_list);
599 return !match_list->empty();
600}
601
602/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700603 * Scan through the list of matches and determine the most severe
604 * suspension policy.
605 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200606static JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700607 JdwpSuspendPolicy policy = SP_NONE;
608
Sebastien Hertz7d955652014-10-22 10:57:10 +0200609 for (JdwpEvent* pEvent : match_list) {
610 if (pEvent->suspend_policy > policy) {
611 policy = pEvent->suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700612 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700613 }
614
615 return policy;
616}
617
618/*
619 * Three possibilities:
620 * SP_NONE - do nothing
621 * SP_EVENT_THREAD - suspend ourselves
622 * SP_ALL - suspend everybody except JDWP support thread
623 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700624void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
Elliott Hughesf8349362012-06-18 15:00:06 -0700625 VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
626 if (suspend_policy == SP_NONE) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700627 return;
628 }
629
Elliott Hughesf8349362012-06-18 15:00:06 -0700630 if (suspend_policy == SP_ALL) {
Elliott Hughes475fc232011-10-25 15:00:35 -0700631 Dbg::SuspendVM();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700632 } else {
Elliott Hughesf8349362012-06-18 15:00:06 -0700633 CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700634 }
635
636 /* this is rare but possible -- see CLASS_PREPARE handling */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700637 if (thread_self_id == debug_thread_id_) {
Elliott Hughes761928d2011-11-16 18:33:03 -0800638 LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700639 return;
640 }
641
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700642 while (true) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700643 Dbg::SuspendSelf();
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700644
645 /*
646 * The JDWP thread has told us (and possibly all other threads) to
647 * resume. See if it has left anything in our DebugInvokeReq mailbox.
648 */
Sebastien Hertz1558b572015-02-25 15:05:59 +0100649 DebugInvokeReq* const pReq = Dbg::GetInvokeReq();
650 if (pReq == nullptr) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700651 break;
652 }
653
Sebastien Hertzcbc50642015-06-01 17:33:12 +0200654 // Execute method.
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700655 Dbg::ExecuteMethod(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700656 }
657}
658
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700659void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
660 ObjectId threadId) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200661 Thread* const self = Thread::Current();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700662 self->AssertThreadSuspensionIsAllowable();
Sebastien Hertz7d955652014-10-22 10:57:10 +0200663 CHECK(pReq != nullptr);
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +0100664 CHECK_EQ(threadId, Dbg::GetThreadSelfId()) << "Only the current thread can suspend itself";
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700665 /* send request and possibly suspend ourselves */
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700666 ScopedThreadSuspension sts(self, kWaitingForDebuggerSend);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200667 if (suspend_policy != SP_NONE) {
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100668 AcquireJdwpTokenForEvent(threadId);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700669 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200670 EventFinish(pReq);
Sebastien Hertz813b9602015-02-24 14:56:59 +0100671 {
672 // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING.
673 ScopedThreadStateChange stsc(self, kSuspended);
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +0100674 SuspendByPolicy(suspend_policy, threadId);
Sebastien Hertz813b9602015-02-24 14:56:59 +0100675 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700676}
677
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700678/*
679 * Determine if there is a method invocation in progress in the current
680 * thread.
681 *
Elliott Hughes475fc232011-10-25 15:00:35 -0700682 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700683 * state. If set, we're in the process of invoking a method.
684 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800685bool JdwpState::InvokeInProgress() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700686 DebugInvokeReq* pReq = Dbg::GetInvokeReq();
Sebastien Hertz1558b572015-02-25 15:05:59 +0100687 return pReq != nullptr;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700688}
689
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100690void JdwpState::AcquireJdwpTokenForCommand() {
691 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
692 SetWaitForJdwpToken(debug_thread_id_);
693}
694
695void JdwpState::ReleaseJdwpTokenForCommand() {
696 CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
697 ClearWaitForJdwpToken();
698}
699
700void JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) {
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100701 SetWaitForJdwpToken(threadId);
702}
703
704void JdwpState::ReleaseJdwpTokenForEvent() {
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100705 ClearWaitForJdwpToken();
706}
707
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700708/*
709 * We need the JDWP thread to hold off on doing stuff while we post an
710 * event and then suspend ourselves.
711 *
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700712 * This could go to sleep waiting for another thread, so it's important
713 * that the thread be marked as VMWAIT before calling here.
714 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100715void JdwpState::SetWaitForJdwpToken(ObjectId threadId) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700716 bool waited = false;
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100717 Thread* const self = Thread::Current();
718 CHECK_NE(threadId, 0u);
719 CHECK_NE(self->GetState(), kRunnable);
720 Locks::mutator_lock_->AssertNotHeld(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700721
722 /* this is held for very brief periods; contention is unlikely */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100723 MutexLock mu(self, jdwp_token_lock_);
724
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +0100725 if (jdwp_token_owner_thread_id_ == threadId) {
726 // Only the debugger thread may already hold the event token. For instance, it may trigger
727 // a CLASS_PREPARE event while processing a command that initializes a class.
728 CHECK_EQ(threadId, debug_thread_id_) << "Non-debugger thread is already holding event token";
729 } else {
730 /*
731 * If another thread is already doing stuff, wait for it. This can
732 * go to sleep indefinitely.
733 */
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700734
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +0100735 while (jdwp_token_owner_thread_id_ != 0) {
736 VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
737 jdwp_token_owner_thread_id_, threadId);
738 waited = true;
739 jdwp_token_cond_.Wait(self);
740 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700741
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +0100742 if (waited || threadId != debug_thread_id_) {
743 VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
744 }
745 jdwp_token_owner_thread_id_ = threadId;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700746 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700747}
748
749/*
750 * Clear the threadId and signal anybody waiting.
751 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100752void JdwpState::ClearWaitForJdwpToken() {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700753 /*
754 * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100755 * function is called by Dbg::SuspendSelf(), and the transition back
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700756 * to RUNNING would confuse it.
757 */
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100758 Thread* const self = Thread::Current();
759 MutexLock mu(self, jdwp_token_lock_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700760
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100761 CHECK_NE(jdwp_token_owner_thread_id_, 0U);
762 VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700763
Sebastien Hertz2bf93f42015-01-09 18:44:05 +0100764 jdwp_token_owner_thread_id_ = 0;
765 jdwp_token_cond_.Signal(self);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700766}
767
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700768/*
769 * Prep an event. Allocates storage for the message and leaves space for
770 * the header.
771 */
772static ExpandBuf* eventPrep() {
773 ExpandBuf* pReq = expandBufAlloc();
774 expandBufAddSpace(pReq, kJDWPHeaderLen);
775 return pReq;
776}
777
778/*
779 * Write the header into the buffer and send the packet off to the debugger.
780 *
781 * Takes ownership of "pReq" (currently discards it).
782 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800783void JdwpState::EventFinish(ExpandBuf* pReq) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700784 uint8_t* buf = expandBufGetBuffer(pReq);
785
Sebastien Hertzcbc50642015-06-01 17:33:12 +0200786 Set4BE(buf + kJDWPHeaderSizeOffset, expandBufGetLength(pReq));
787 Set4BE(buf + kJDWPHeaderIdOffset, NextRequestSerial());
788 Set1(buf + kJDWPHeaderFlagsOffset, 0); /* flags */
789 Set1(buf + kJDWPHeaderCmdSetOffset, kJDWPEventCmdSet);
790 Set1(buf + kJDWPHeaderCmdOffset, kJDWPEventCompositeCmd);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700791
Elliott Hughes761928d2011-11-16 18:33:03 -0800792 SendRequest(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700793
794 expandBufFree(pReq);
795}
796
797
798/*
799 * Tell the debugger that we have finished initializing. This is always
800 * sent, even if the debugger hasn't requested it.
801 *
802 * This should be sent "before the main thread is started and before
803 * any application code has been executed". The thread ID in the message
804 * must be for the main thread.
805 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200806void JdwpState::PostVMStart() {
807 JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700808 ObjectId threadId = Dbg::GetThreadSelfId();
809
Sebastien Hertz7d955652014-10-22 10:57:10 +0200810 VLOG(jdwp) << "EVENT: " << EK_VM_START;
811 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700812
Elliott Hughes761928d2011-11-16 18:33:03 -0800813 ExpandBuf* pReq = eventPrep();
Sebastien Hertz7d955652014-10-22 10:57:10 +0200814 expandBufAdd1(pReq, suspend_policy);
815 expandBufAdd4BE(pReq, 1);
816 expandBufAdd1(pReq, EK_VM_START);
817 expandBufAdd4BE(pReq, 0); /* requestId */
818 expandBufAddObjectId(pReq, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700819
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100820 Dbg::ManageDeoptimization();
821
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700822 /* send request and possibly suspend ourselves */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700823 SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700824}
825
Vladimir Marko5c657fe2016-11-03 15:12:29 +0000826static void LogMatchingEventsAndThread(const std::vector<JdwpEvent*>& match_list,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200827 ObjectId thread_id)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700828 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200829 for (size_t i = 0, e = match_list.size(); i < e; ++i) {
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200830 JdwpEvent* pEvent = match_list[i];
831 VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
832 << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
833 }
834 std::string thread_name;
Sebastien Hertz6995c602014-09-09 12:10:13 +0200835 JdwpError error = Dbg::GetThreadName(thread_id, &thread_name);
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200836 if (error != JDWP::ERR_NONE) {
837 thread_name = "<unknown>";
838 }
Sebastien Hertz6995c602014-09-09 12:10:13 +0200839 VLOG(jdwp) << StringPrintf(" thread=%#" PRIx64, thread_id) << " " << thread_name;
840}
841
842static void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
843 JDWP::JdwpLocation* jdwp_location)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700844 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz6995c602014-09-09 12:10:13 +0200845 DCHECK(event_location != nullptr);
846 DCHECK(jdwp_location != nullptr);
847 Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200848}
849
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700850/*
851 * A location of interest has been reached. This handles:
852 * Breakpoint
853 * SingleStep
854 * MethodEntry
855 * MethodExit
856 * These four types must be grouped together in a single response. The
857 * "eventFlags" indicates the type of event(s) that have happened.
858 *
859 * Valid mods:
860 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
861 * LocationOnly (for breakpoint/step only)
862 * Step (for step only)
863 *
864 * Interesting test cases:
865 * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY
866 * and METHOD_EXIT events with a ClassOnly mod on the method's class.
867 * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1.
868 * - Single-step to a line with a breakpoint. Should get a single
869 * event message with both events in it.
870 */
Sebastien Hertz7d955652014-10-22 10:57:10 +0200871void JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200872 int eventFlags, const JValue* returnValue) {
873 DCHECK(pLoc != nullptr);
874 DCHECK(pLoc->method != nullptr);
875 DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
876
Sebastien Hertz261bc042015-04-08 09:36:07 +0200877 ModBasket basket(Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700878 basket.pLoc = pLoc;
Sebastien Hertz261bc042015-04-08 09:36:07 +0200879 basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
880 basket.thisPtr.Assign(thisPtr);
881 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700882
883 /*
884 * On rare occasions we may need to execute interpreted code in the VM
885 * while handling a request from the debugger. Don't fire breakpoints
886 * while doing so. (I don't think we currently do this at all, so
887 * this is mostly paranoia.)
888 */
Sebastien Hertz6995c602014-09-09 12:10:13 +0200889 if (basket.thread == GetDebugThread()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800890 VLOG(jdwp) << "Ignoring location event in JDWP thread";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200891 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700892 }
893
894 /*
895 * The debugger variable display tab may invoke the interpreter to format
896 * complex objects. We want to ignore breakpoints and method entry/exit
897 * traps while working on behalf of the debugger.
898 *
899 * If we don't ignore them, the VM will get hung up, because we'll
900 * suspend on a breakpoint while the debugger is still waiting for its
901 * method invocation to complete.
902 */
Elliott Hughes761928d2011-11-16 18:33:03 -0800903 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800904 VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200905 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700906 }
907
Sebastien Hertz7d955652014-10-22 10:57:10 +0200908 std::vector<JdwpEvent*> match_list;
Elliott Hughes761928d2011-11-16 18:33:03 -0800909 {
Sebastien Hertz7d955652014-10-22 10:57:10 +0200910 // We use the locked version because we have multiple possible match events.
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800911 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200912 match_list.reserve(event_list_size_);
913 if ((eventFlags & Dbg::kBreakpoint) != 0) {
914 FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800915 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200916 if ((eventFlags & Dbg::kSingleStep) != 0) {
917 FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800918 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200919 if ((eventFlags & Dbg::kMethodEntry) != 0) {
920 FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
Sebastien Hertz6995c602014-09-09 12:10:13 +0200921 }
Sebastien Hertz7d955652014-10-22 10:57:10 +0200922 if ((eventFlags & Dbg::kMethodExit) != 0) {
923 FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
924 FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
925 }
926 }
927 if (match_list.empty()) {
928 // No matching event.
929 return;
930 }
931 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
932
933 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
934 JDWP::JdwpLocation jdwp_location;
935 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
936
937 if (VLOG_IS_ON(jdwp)) {
938 LogMatchingEventsAndThread(match_list, thread_id);
939 VLOG(jdwp) << " location=" << jdwp_location;
940 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
941 }
942
943 ExpandBuf* pReq = eventPrep();
944 expandBufAdd1(pReq, suspend_policy);
945 expandBufAdd4BE(pReq, match_list.size());
946
947 for (const JdwpEvent* pEvent : match_list) {
948 expandBufAdd1(pReq, pEvent->eventKind);
949 expandBufAdd4BE(pReq, pEvent->requestId);
950 expandBufAddObjectId(pReq, thread_id);
951 expandBufAddLocation(pReq, jdwp_location);
952 if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
953 Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
954 }
955 }
956
957 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -0800958 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +0200959 CleanupMatchList(match_list);
Elliott Hughes761928d2011-11-16 18:33:03 -0800960 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700961
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100962 Dbg::ManageDeoptimization();
963
Sebastien Hertz6995c602014-09-09 12:10:13 +0200964 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700965}
966
Mathieu Chartierc7853442015-03-27 14:35:38 -0700967void JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field,
Sebastien Hertz6995c602014-09-09 12:10:13 +0200968 mirror::Object* this_object, const JValue* fieldValue,
969 bool is_modification) {
970 DCHECK(pLoc != nullptr);
971 DCHECK(field != nullptr);
972 DCHECK_EQ(fieldValue != nullptr, is_modification);
973 DCHECK_EQ(field->IsStatic(), this_object == nullptr);
974
Sebastien Hertz261bc042015-04-08 09:36:07 +0200975 ModBasket basket(Thread::Current());
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200976 basket.pLoc = pLoc;
Sebastien Hertz261bc042015-04-08 09:36:07 +0200977 basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
978 basket.thisPtr.Assign(this_object);
979 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Sebastien Hertz6995c602014-09-09 12:10:13 +0200980 basket.field = field;
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +0200981
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200982 if (InvokeInProgress()) {
Sebastien Hertz261bc042015-04-08 09:36:07 +0200983 VLOG(jdwp) << "Not posting field event during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +0200984 return;
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +0200985 }
986
Sebastien Hertz7d955652014-10-22 10:57:10 +0200987 std::vector<JdwpEvent*> match_list;
988 const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
989 if (!FindMatchingEvents(match_kind, basket, &match_list)) {
990 // No matching event.
991 return;
992 }
993
994 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
995 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
996 ObjectRegistry* registry = Dbg::GetObjectRegistry();
997 ObjectId instance_id = registry->Add(basket.thisPtr);
998 RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
999 FieldId field_id = Dbg::ToFieldId(field);
1000 JDWP::JdwpLocation jdwp_location;
1001 SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
1002
1003 if (VLOG_IS_ON(jdwp)) {
1004 LogMatchingEventsAndThread(match_list, thread_id);
1005 VLOG(jdwp) << " location=" << jdwp_location;
1006 VLOG(jdwp) << StringPrintf(" this=%#" PRIx64, instance_id);
1007 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, field_type_id) << " "
1008 << Dbg::GetClassName(field_id);
Mathieu Chartierd3ed9a32015-04-10 14:23:35 -07001009 VLOG(jdwp) << StringPrintf(" field=%#" PRIx64, field_id) << " "
Sebastien Hertz7d955652014-10-22 10:57:10 +02001010 << Dbg::GetFieldName(field_id);
1011 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1012 }
1013
1014 ExpandBuf* pReq = eventPrep();
1015 expandBufAdd1(pReq, suspend_policy);
1016 expandBufAdd4BE(pReq, match_list.size());
1017
1018 // Get field's reference type tag.
1019 JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
1020
1021 // Get instance type tag.
1022 uint8_t tag;
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001023 {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001024 ScopedObjectAccessUnchecked soa(Thread::Current());
Sebastien Hertz261bc042015-04-08 09:36:07 +02001025 tag = Dbg::TagFromObject(soa, basket.thisPtr.Get());
Sebastien Hertz7d955652014-10-22 10:57:10 +02001026 }
1027
1028 for (const JdwpEvent* pEvent : match_list) {
1029 expandBufAdd1(pReq, pEvent->eventKind);
1030 expandBufAdd4BE(pReq, pEvent->requestId);
1031 expandBufAddObjectId(pReq, thread_id);
1032 expandBufAddLocation(pReq, jdwp_location);
1033 expandBufAdd1(pReq, type_tag);
1034 expandBufAddRefTypeId(pReq, field_type_id);
1035 expandBufAddFieldId(pReq, field_id);
1036 expandBufAdd1(pReq, tag);
1037 expandBufAddObjectId(pReq, instance_id);
1038 if (is_modification) {
1039 Dbg::OutputFieldValue(field_id, fieldValue, pReq);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001040 }
Sebastien Hertz7d955652014-10-22 10:57:10 +02001041 }
Sebastien Hertzbca0d3d2014-04-11 16:01:17 +02001042
Sebastien Hertz7d955652014-10-22 10:57:10 +02001043 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -08001044 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +02001045 CleanupMatchList(match_list);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001046 }
1047
1048 Dbg::ManageDeoptimization();
1049
Sebastien Hertz6995c602014-09-09 12:10:13 +02001050 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001051}
1052
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001053/*
1054 * A thread is starting or stopping.
1055 *
1056 * Valid mods:
1057 * Count, ThreadOnly
1058 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001059void JdwpState::PostThreadChange(Thread* thread, bool start) {
Sebastien Hertz6995c602014-09-09 12:10:13 +02001060 CHECK_EQ(thread, Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001061
1062 /*
1063 * I don't think this can happen.
1064 */
Elliott Hughes761928d2011-11-16 18:33:03 -08001065 if (InvokeInProgress()) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001066 LOG(WARNING) << "Not posting thread change during invoke";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001067 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001068 }
1069
Sebastien Hertz107e7572014-12-18 11:13:15 +01001070 // We need the java.lang.Thread object associated to the starting/ending
1071 // thread to get its JDWP id. Therefore we can't report event if there
1072 // is no Java peer. This happens when the runtime shuts down and re-attaches
1073 // the current thread without creating a Java peer.
1074 if (thread->GetPeer() == nullptr) {
1075 return;
1076 }
1077
Sebastien Hertz261bc042015-04-08 09:36:07 +02001078 ModBasket basket(thread);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001079
Sebastien Hertz7d955652014-10-22 10:57:10 +02001080 std::vector<JdwpEvent*> match_list;
1081 const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
1082 if (!FindMatchingEvents(match_kind, basket, &match_list)) {
1083 // No matching event.
1084 return;
1085 }
1086
1087 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1088 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1089
1090 if (VLOG_IS_ON(jdwp)) {
1091 LogMatchingEventsAndThread(match_list, thread_id);
1092 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1093 }
1094
1095 ExpandBuf* pReq = eventPrep();
1096 expandBufAdd1(pReq, suspend_policy);
1097 expandBufAdd4BE(pReq, match_list.size());
1098
1099 for (const JdwpEvent* pEvent : match_list) {
1100 expandBufAdd1(pReq, pEvent->eventKind);
1101 expandBufAdd4BE(pReq, pEvent->requestId);
1102 expandBufAdd8BE(pReq, thread_id);
1103 }
1104
Elliott Hughes234ab152011-10-26 14:02:26 -07001105 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -08001106 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +02001107 CleanupMatchList(match_list);
Elliott Hughes234ab152011-10-26 14:02:26 -07001108 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001109
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001110 Dbg::ManageDeoptimization();
1111
Sebastien Hertz6995c602014-09-09 12:10:13 +02001112 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001113}
1114
1115/*
1116 * Send a polite "VM is dying" message to the debugger.
1117 *
1118 * Skips the usual "event token" stuff.
1119 */
Elliott Hughes376a7a02011-10-24 18:35:55 -07001120bool JdwpState::PostVMDeath() {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001121 VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001122
1123 ExpandBuf* pReq = eventPrep();
1124 expandBufAdd1(pReq, SP_NONE);
1125 expandBufAdd4BE(pReq, 1);
1126
1127 expandBufAdd1(pReq, EK_VM_DEATH);
1128 expandBufAdd4BE(pReq, 0);
Elliott Hughes761928d2011-11-16 18:33:03 -08001129 EventFinish(pReq);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001130 return true;
1131}
1132
1133/*
1134 * An exception has been thrown. It may or may not have been caught.
1135 *
1136 * Valid mods:
1137 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1138 * ExceptionOnly, InstanceOnly
1139 *
1140 * The "exceptionId" has not been added to the GC-visible object registry,
1141 * because there's a pretty good chance that we're not going to send it
1142 * up the debugger.
1143 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001144void JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
Sebastien Hertz6995c602014-09-09 12:10:13 +02001145 const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
1146 DCHECK(exception_object != nullptr);
1147 DCHECK(pThrowLoc != nullptr);
1148 DCHECK(pCatchLoc != nullptr);
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001149 if (pThrowLoc->method != nullptr) {
1150 DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1151 } else {
1152 VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1153 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001154
Sebastien Hertz261bc042015-04-08 09:36:07 +02001155 ModBasket basket(Thread::Current());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001156 basket.pLoc = pThrowLoc;
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001157 if (pThrowLoc->method != nullptr) {
Sebastien Hertz261bc042015-04-08 09:36:07 +02001158 basket.locationClass.Assign(pThrowLoc->method->GetDeclaringClass());
Sebastien Hertza9aa0ff2014-09-19 12:07:51 +02001159 }
Sebastien Hertz261bc042015-04-08 09:36:07 +02001160 basket.className = Dbg::GetClassName(basket.locationClass.Get());
1161 basket.exceptionClass.Assign(exception_object->GetClass());
Sebastien Hertz6995c602014-09-09 12:10:13 +02001162 basket.caught = (pCatchLoc->method != 0);
Sebastien Hertz261bc042015-04-08 09:36:07 +02001163 basket.thisPtr.Assign(thisPtr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001164
1165 /* don't try to post an exception caused by the debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -08001166 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001167 VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001168 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001169 }
1170
Sebastien Hertz7d955652014-10-22 10:57:10 +02001171 std::vector<JdwpEvent*> match_list;
1172 if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
1173 // No matching event.
1174 return;
1175 }
1176
1177 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1178 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1179 ObjectRegistry* registry = Dbg::GetObjectRegistry();
1180 ObjectId exceptionId = registry->Add(exception_object);
1181 JDWP::JdwpLocation jdwp_throw_location;
1182 JDWP::JdwpLocation jdwp_catch_location;
1183 SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
1184 SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
1185
1186 if (VLOG_IS_ON(jdwp)) {
David Sehr709b0702016-10-13 09:12:37 -07001187 std::string exceptionClassName(mirror::Class::PrettyDescriptor(exception_object->GetClass()));
Sebastien Hertz7d955652014-10-22 10:57:10 +02001188
1189 LogMatchingEventsAndThread(match_list, thread_id);
1190 VLOG(jdwp) << " throwLocation=" << jdwp_throw_location;
1191 if (jdwp_catch_location.class_id == 0) {
1192 VLOG(jdwp) << " catchLocation=uncaught";
1193 } else {
1194 VLOG(jdwp) << " catchLocation=" << jdwp_catch_location;
1195 }
1196 VLOG(jdwp) << StringPrintf(" exception=%#" PRIx64, exceptionId) << " "
1197 << exceptionClassName;
1198 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1199 }
1200
1201 ExpandBuf* pReq = eventPrep();
1202 expandBufAdd1(pReq, suspend_policy);
1203 expandBufAdd4BE(pReq, match_list.size());
1204
1205 for (const JdwpEvent* pEvent : match_list) {
1206 expandBufAdd1(pReq, pEvent->eventKind);
1207 expandBufAdd4BE(pReq, pEvent->requestId);
1208 expandBufAddObjectId(pReq, thread_id);
1209 expandBufAddLocation(pReq, jdwp_throw_location);
1210 expandBufAdd1(pReq, JT_OBJECT);
1211 expandBufAddObjectId(pReq, exceptionId);
1212 expandBufAddLocation(pReq, jdwp_catch_location);
1213 }
1214
Elliott Hughes761928d2011-11-16 18:33:03 -08001215 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -08001216 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +02001217 CleanupMatchList(match_list);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001218 }
1219
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001220 Dbg::ManageDeoptimization();
1221
Sebastien Hertz6995c602014-09-09 12:10:13 +02001222 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001223}
1224
1225/*
1226 * Announce that a class has been loaded.
1227 *
1228 * Valid mods:
1229 * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1230 */
Sebastien Hertz7d955652014-10-22 10:57:10 +02001231void JdwpState::PostClassPrepare(mirror::Class* klass) {
Sebastien Hertz6995c602014-09-09 12:10:13 +02001232 DCHECK(klass != nullptr);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001233
Sebastien Hertz261bc042015-04-08 09:36:07 +02001234 ModBasket basket(Thread::Current());
1235 basket.locationClass.Assign(klass);
1236 basket.className = Dbg::GetClassName(basket.locationClass.Get());
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001237
1238 /* suppress class prep caused by debugger */
Elliott Hughes761928d2011-11-16 18:33:03 -08001239 if (InvokeInProgress()) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08001240 VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
Sebastien Hertz7d955652014-10-22 10:57:10 +02001241 return;
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001242 }
1243
Sebastien Hertz7d955652014-10-22 10:57:10 +02001244 std::vector<JdwpEvent*> match_list;
1245 if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
1246 // No matching event.
1247 return;
1248 }
1249
1250 JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
1251 ObjectId thread_id = Dbg::GetThreadId(basket.thread);
1252 ObjectRegistry* registry = Dbg::GetObjectRegistry();
1253 RefTypeId class_id = registry->AddRefType(basket.locationClass);
1254
1255 // OLD-TODO - we currently always send both "verified" and "prepared" since
1256 // debuggers seem to like that. There might be some advantage to honesty,
1257 // since the class may not yet be verified.
1258 int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
Sebastien Hertz261bc042015-04-08 09:36:07 +02001259 JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass.Get());
Sebastien Hertz7d955652014-10-22 10:57:10 +02001260 std::string temp;
1261 std::string signature(basket.locationClass->GetDescriptor(&temp));
1262
1263 if (VLOG_IS_ON(jdwp)) {
1264 LogMatchingEventsAndThread(match_list, thread_id);
1265 VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, class_id) << " " << signature;
1266 VLOG(jdwp) << " suspend_policy=" << suspend_policy;
1267 }
1268
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +01001269 ObjectId reported_thread_id = thread_id;
1270 if (reported_thread_id == debug_thread_id_) {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001271 /*
1272 * JDWP says that, for a class prep in the debugger thread, we
1273 * should set thread to null and if any threads were supposed
1274 * to be suspended then we suspend all other threads.
1275 */
1276 VLOG(jdwp) << " NOTE: class prepare in debugger thread!";
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +01001277 reported_thread_id = 0;
Sebastien Hertz7d955652014-10-22 10:57:10 +02001278 if (suspend_policy == SP_EVENT_THREAD) {
1279 suspend_policy = SP_ALL;
1280 }
1281 }
1282
1283 ExpandBuf* pReq = eventPrep();
1284 expandBufAdd1(pReq, suspend_policy);
1285 expandBufAdd4BE(pReq, match_list.size());
1286
1287 for (const JdwpEvent* pEvent : match_list) {
1288 expandBufAdd1(pReq, pEvent->eventKind);
1289 expandBufAdd4BE(pReq, pEvent->requestId);
Sebastien Hertzaf8bcf82016-11-22 14:55:04 +01001290 expandBufAddObjectId(pReq, reported_thread_id);
Sebastien Hertz7d955652014-10-22 10:57:10 +02001291 expandBufAdd1(pReq, tag);
1292 expandBufAddRefTypeId(pReq, class_id);
1293 expandBufAddUtf8String(pReq, signature);
1294 expandBufAdd4BE(pReq, status);
1295 }
1296
Elliott Hughes761928d2011-11-16 18:33:03 -08001297 {
Hiroshi Yamauchib139b6d2017-02-28 15:01:23 -08001298 MutexLock mu(Thread::Current(), event_list_lock_);
Sebastien Hertz7d955652014-10-22 10:57:10 +02001299 CleanupMatchList(match_list);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001300 }
1301
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001302 Dbg::ManageDeoptimization();
1303
Sebastien Hertz6995c602014-09-09 12:10:13 +02001304 SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001305}
1306
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001307/*
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001308 * Setup the header for a chunk of DDM data.
1309 */
1310void JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size,
1311 uint8_t* out_header) {
1312 CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8));
1313 /* form the header (JDWP plus DDMS) */
1314 Set4BE(out_header, header_size + data_len);
1315 Set4BE(out_header + 4, NextRequestSerial());
1316 Set1(out_header + 8, 0); /* flags */
1317 Set1(out_header + 9, kJDWPDdmCmdSet);
1318 Set1(out_header + 10, kJDWPDdmCmd);
1319 Set4BE(out_header + 11, type);
1320 Set4BE(out_header + 15, data_len);
1321}
1322
1323/*
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001324 * Send up a chunk of DDM data.
1325 *
1326 * While this takes the form of a JDWP "event", it doesn't interact with
1327 * other debugger traffic, and can't suspend the VM, so we skip all of
1328 * the fun event token gymnastics.
1329 */
Elliott Hughescccd84f2011-12-05 16:51:54 -08001330void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001331 uint8_t header[kJDWPHeaderLen + 8] = { 0 };
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001332 size_t dataLen = 0;
1333
Sebastien Hertz7d955652014-10-22 10:57:10 +02001334 CHECK(iov != nullptr);
Elliott Hughescccd84f2011-12-05 16:51:54 -08001335 CHECK_GT(iov_count, 0);
1336 CHECK_LT(iov_count, 10);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001337
1338 /*
1339 * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do
1340 * this by creating a new copy of the vector with space for the header.
1341 */
Brian Carlstromf5293522013-07-19 00:24:00 -07001342 std::vector<iovec> wrapiov;
1343 wrapiov.push_back(iovec());
Elliott Hughescccd84f2011-12-05 16:51:54 -08001344 for (int i = 0; i < iov_count; i++) {
Brian Carlstromf5293522013-07-19 00:24:00 -07001345 wrapiov.push_back(iov[i]);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001346 dataLen += iov[i].iov_len;
1347 }
1348
Mathieu Chartierad466ad2015-01-08 16:28:08 -08001349 SetupChunkHeader(type, dataLen, sizeof(header), header);
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001350
1351 wrapiov[0].iov_base = header;
1352 wrapiov[0].iov_len = sizeof(header);
1353
Ian Rogers15bf2d32012-08-28 17:33:04 -07001354 // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
1355 // than mutator for lock ordering reasons.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001356 Thread* self = Thread::Current();
Ian Rogers62d6c772013-02-27 08:32:07 -08001357 bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
1358 if (safe_to_release_mutator_lock_over_send) {
Brian Carlstrom38f85e42013-07-18 14:45:22 -07001359 for (size_t i = 0; i < kMutatorLock; ++i) {
Sebastien Hertz7d955652014-10-22 10:57:10 +02001360 if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -08001361 safe_to_release_mutator_lock_over_send = false;
1362 break;
1363 }
Ian Rogers15bf2d32012-08-28 17:33:04 -07001364 }
1365 }
1366 if (safe_to_release_mutator_lock_over_send) {
1367 // Change state to waiting to allow GC, ... while we're sending.
Mathieu Chartierf1d666e2015-09-03 16:13:34 -07001368 ScopedThreadSuspension sts(self, kWaitingForDebuggerSend);
Brian Carlstromf5293522013-07-19 00:24:00 -07001369 SendBufferedRequest(type, wrapiov);
Ian Rogers15bf2d32012-08-28 17:33:04 -07001370 } else {
1371 // Send and possibly block GC...
Brian Carlstromf5293522013-07-19 00:24:00 -07001372 SendBufferedRequest(type, wrapiov);
Ian Rogers15bf2d32012-08-28 17:33:04 -07001373 }
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001374}
1375
1376} // namespace JDWP
1377
1378} // namespace art