jdwp_event.cc revision bbb63897d7f2d99219cb50721fe530521e08ddff
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "jdwp/jdwp_event.h"
18
19#include <stddef.h>     /* for offsetof() */
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23
24#include "base/logging.h"
25#include "base/stringprintf.h"
26#include "debugger.h"
27#include "jdwp/jdwp_constants.h"
28#include "jdwp/jdwp_expand_buf.h"
29#include "jdwp/jdwp_priv.h"
30#include "jdwp/object_registry.h"
31#include "mirror/art_field-inl.h"
32#include "scoped_thread_state_change.h"
33#include "thread-inl.h"
34
35/*
36General notes:
37
38The event add/remove stuff usually happens from the debugger thread,
39in response to requests from the debugger, but can also happen as the
40result of an event in an arbitrary thread (e.g. an event with a "count"
41mod expires).  It's important to keep the event list locked when processing
42events.
43
44Event posting can happen from any thread.  The JDWP thread will not usually
45post anything but VM start/death, but if a JDWP request causes a class
46to be loaded, the ClassPrepare event will come from the JDWP thread.
47
48
49We can have serialization issues when we post an event to the debugger.
50For example, a thread could send an "I hit a breakpoint and am suspending
51myself" message to the debugger.  Before it manages to suspend itself, the
52debugger's response ("not interested, resume thread") arrives and is
53processed.  We try to resume a thread that hasn't yet suspended.
54
55This means that, after posting an event to the debugger, we need to wait
56for the event thread to suspend itself (and, potentially, all other threads)
57before processing any additional requests from the debugger.  While doing
58so we need to be aware that multiple threads may be hitting breakpoints
59or other events simultaneously, so we either need to wait for all of them
60or serialize the events with each other.
61
62The current mechanism works like this:
63  Event thread:
64   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
65     for it if it's not currently available.
66   - Post the event to the debugger.
67   - If appropriate, suspend others and then myself.  As part of suspending
68     myself, release the "I am posting" token.
69  JDWP thread:
70   - When an event arrives, see if somebody is posting an event.  If so,
71     sleep until we can acquire the "I am posting an event" token.  Release
72     it immediately and continue processing -- the event we have already
73     received should not interfere with other events that haven't yet
74     been posted.
75
76Some care must be taken to avoid deadlock:
77
78 - thread A and thread B exit near-simultaneously, and post thread-death
79   events with a "suspend all" clause
80 - thread A gets the event token, thread B sits and waits for it
81 - thread A wants to suspend all other threads, but thread B is waiting
82   for the token and can't be suspended
83
84So we need to mark thread B in such a way that thread A doesn't wait for it.
85
86If we just bracket the "grab event token" call with a change to VMWAIT
87before sleeping, the switch back to RUNNING state when we get the token
88will cause thread B to suspend (remember, thread A's global suspend is
89still in force, even after it releases the token).  Suspending while
90holding the event token is very bad, because it prevents the JDWP thread
91from processing incoming messages.
92
93We need to change to VMWAIT state at the *start* of posting an event,
94and stay there until we either finish posting the event or decide to
95put ourselves to sleep.  That way we don't interfere with anyone else and
96don't allow anyone else to interfere with us.
97*/
98
99
100#define kJdwpEventCommandSet    64
101#define kJdwpCompositeCommand   100
102
103namespace art {
104
105namespace JDWP {
106
107/*
108 * Stuff to compare against when deciding if a mod matches.  Only the
109 * values for mods valid for the event being evaluated will be filled in.
110 * The rest will be zeroed.
111 */
112struct ModBasket {
113  ModBasket() : pLoc(nullptr), thread(nullptr), locationClass(nullptr), exceptionClass(nullptr),
114                caught(false), field(nullptr), thisPtr(nullptr) { }
115
116  const EventLocation*  pLoc;             /* LocationOnly */
117  std::string           className;        /* ClassMatch/ClassExclude */
118  Thread*               thread;           /* ThreadOnly */
119  mirror::Class*        locationClass;    /* ClassOnly */
120  mirror::Class*        exceptionClass;   /* ExceptionOnly */
121  bool                  caught;           /* ExceptionOnly */
122  mirror::ArtField*     field;            /* FieldOnly */
123  mirror::Object*       thisPtr;          /* InstanceOnly */
124  /* nothing for StepOnly -- handled differently */
125};
126
127static bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
128  switch (eventKind) {
129      case EK_METHOD_ENTRY:
130      case EK_METHOD_EXIT:
131      case EK_METHOD_EXIT_WITH_RETURN_VALUE:
132      case EK_SINGLE_STEP:
133      case EK_FIELD_ACCESS:
134      case EK_FIELD_MODIFICATION:
135        return true;
136      default:
137        return false;
138    }
139}
140
141uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
142  switch (eventKind) {
143    case EK_BREAKPOINT:
144    case EK_SINGLE_STEP:
145      return instrumentation::Instrumentation::kDexPcMoved;
146    case EK_EXCEPTION:
147    case EK_EXCEPTION_CATCH:
148      return instrumentation::Instrumentation::kExceptionCaught;
149    case EK_METHOD_ENTRY:
150      return instrumentation::Instrumentation::kMethodEntered;
151    case EK_METHOD_EXIT:
152    case EK_METHOD_EXIT_WITH_RETURN_VALUE:
153      return instrumentation::Instrumentation::kMethodExited;
154    case EK_FIELD_ACCESS:
155      return instrumentation::Instrumentation::kFieldRead;
156    case EK_FIELD_MODIFICATION:
157      return instrumentation::Instrumentation::kFieldWritten;
158    default:
159      return 0;
160  }
161}
162
163/*
164 * Add an event to the list.  Ordering is not important.
165 *
166 * If something prevents the event from being registered, e.g. it's a
167 * single-step request on a thread that doesn't exist, the event will
168 * not be added to the list, and an appropriate error will be returned.
169 */
170JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
171  CHECK(pEvent != NULL);
172  CHECK(pEvent->prev == NULL);
173  CHECK(pEvent->next == NULL);
174
175  {
176    /*
177     * If one or more "break"-type mods are used, register them with
178     * the interpreter.
179     */
180    DeoptimizationRequest req;
181    for (int i = 0; i < pEvent->modCount; i++) {
182      const JdwpEventMod* pMod = &pEvent->mods[i];
183      if (pMod->modKind == MK_LOCATION_ONLY) {
184        /* should only be for Breakpoint, Step, and Exception */
185        Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
186      } else if (pMod->modKind == MK_STEP) {
187        /* should only be for EK_SINGLE_STEP; should only be one */
188        JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
189        JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
190        JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
191        if (status != ERR_NONE) {
192          return status;
193        }
194      }
195    }
196    if (NeedsFullDeoptimization(pEvent->eventKind)) {
197      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
198      CHECK(req.Method() == nullptr);
199      req.SetKind(DeoptimizationRequest::kFullDeoptimization);
200    }
201    Dbg::RequestDeoptimization(req);
202  }
203  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
204  if (instrumentation_event != 0) {
205    DeoptimizationRequest req;
206    req.SetKind(DeoptimizationRequest::kRegisterForEvent);
207    req.SetInstrumentationEvent(instrumentation_event);
208    Dbg::RequestDeoptimization(req);
209  }
210
211  {
212    /*
213     * Add to list.
214     */
215    MutexLock mu(Thread::Current(), event_list_lock_);
216    if (event_list_ != NULL) {
217      pEvent->next = event_list_;
218      event_list_->prev = pEvent;
219    }
220    event_list_ = pEvent;
221    ++event_list_size_;
222  }
223
224  Dbg::ManageDeoptimization();
225
226  return ERR_NONE;
227}
228
229/*
230 * Remove an event from the list.  This will also remove the event from
231 * any optimization tables, e.g. breakpoints.
232 *
233 * Does not free the JdwpEvent.
234 *
235 * Grab the eventLock before calling here.
236 */
237void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
238  if (pEvent->prev == NULL) {
239    /* head of the list */
240    CHECK(event_list_ == pEvent);
241
242    event_list_ = pEvent->next;
243  } else {
244    pEvent->prev->next = pEvent->next;
245  }
246
247  if (pEvent->next != NULL) {
248    pEvent->next->prev = pEvent->prev;
249    pEvent->next = NULL;
250  }
251  pEvent->prev = NULL;
252
253  {
254    /*
255     * Unhook us from the interpreter, if necessary.
256     */
257    DeoptimizationRequest req;
258    for (int i = 0; i < pEvent->modCount; i++) {
259      JdwpEventMod* pMod = &pEvent->mods[i];
260      if (pMod->modKind == MK_LOCATION_ONLY) {
261        /* should only be for Breakpoint, Step, and Exception */
262        Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
263      }
264      if (pMod->modKind == MK_STEP) {
265        /* should only be for EK_SINGLE_STEP; should only be one */
266        Dbg::UnconfigureStep(pMod->step.threadId);
267      }
268    }
269    if (pEvent->eventKind == EK_SINGLE_STEP) {
270      // Special case for single-steps where we want to avoid the slow pattern deoptimize/undeoptimize
271      // loop between each single-step. In a IDE, this would happens each time the user click on the
272      // "single-step" button. Here we delay the full undeoptimization to the next resume
273      // (VM.Resume or ThreadReference.Resume) or the end of the debugging session (VM.Dispose or
274      // runtime shutdown).
275      // Therefore, in a singles-stepping sequence, only the first single-step will trigger a full
276      // deoptimization and only the last single-step will trigger a full undeoptimization.
277      Dbg::DelayFullUndeoptimization();
278    } else if (NeedsFullDeoptimization(pEvent->eventKind)) {
279      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
280      CHECK(req.Method() == nullptr);
281      req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
282    }
283    Dbg::RequestDeoptimization(req);
284  }
285  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
286  if (instrumentation_event != 0) {
287    DeoptimizationRequest req;
288    req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
289    req.SetInstrumentationEvent(instrumentation_event);
290    Dbg::RequestDeoptimization(req);
291  }
292
293  --event_list_size_;
294  CHECK(event_list_size_ != 0 || event_list_ == NULL);
295}
296
297/*
298 * Remove the event with the given ID from the list.
299 *
300 */
301void JdwpState::UnregisterEventById(uint32_t requestId) {
302  bool found = false;
303  {
304    MutexLock mu(Thread::Current(), event_list_lock_);
305
306    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
307      if (pEvent->requestId == requestId) {
308        found = true;
309        UnregisterEvent(pEvent);
310        EventFree(pEvent);
311        break;      /* there can be only one with a given ID */
312      }
313    }
314  }
315
316  if (found) {
317    Dbg::ManageDeoptimization();
318  } else {
319    // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
320    // try to be extra careful and will explicitly remove one-off single-step events (using a
321    // 'count' event modifier of 1). So the event may have already been removed as part of the
322    // event notification (see JdwpState::CleanupMatchList).
323    VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
324  }
325}
326
327/*
328 * Remove all entries from the event list.
329 */
330void JdwpState::UnregisterAll() {
331  MutexLock mu(Thread::Current(), event_list_lock_);
332
333  JdwpEvent* pEvent = event_list_;
334  while (pEvent != NULL) {
335    JdwpEvent* pNextEvent = pEvent->next;
336
337    UnregisterEvent(pEvent);
338    EventFree(pEvent);
339    pEvent = pNextEvent;
340  }
341
342  event_list_ = NULL;
343}
344
345/*
346 * Allocate a JdwpEvent struct with enough space to hold the specified
347 * number of mod records.
348 */
349JdwpEvent* EventAlloc(int numMods) {
350  JdwpEvent* newEvent;
351  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
352  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
353  memset(newEvent, 0, allocSize);
354  return newEvent;
355}
356
357/*
358 * Free a JdwpEvent.
359 *
360 * Do not call this until the event has been removed from the list.
361 */
362void EventFree(JdwpEvent* pEvent) {
363  if (pEvent == NULL) {
364    return;
365  }
366
367  /* make sure it was removed from the list */
368  CHECK(pEvent->prev == NULL);
369  CHECK(pEvent->next == NULL);
370  /* want to check state->event_list_ != pEvent */
371
372  /*
373   * Free any hairy bits in the mods.
374   */
375  for (int i = 0; i < pEvent->modCount; i++) {
376    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
377      free(pEvent->mods[i].classMatch.classPattern);
378      pEvent->mods[i].classMatch.classPattern = NULL;
379    }
380    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
381      free(pEvent->mods[i].classExclude.classPattern);
382      pEvent->mods[i].classExclude.classPattern = NULL;
383    }
384  }
385
386  free(pEvent);
387}
388
389/*
390 * Allocate storage for matching events.  To keep things simple we
391 * use an array with enough storage for the entire list.
392 *
393 * The state->eventLock should be held before calling.
394 */
395static JdwpEvent** AllocMatchList(size_t event_count) {
396  return new JdwpEvent*[event_count];
397}
398
399/*
400 * Run through the list and remove any entries with an expired "count" mod
401 * from the event list, then free the match list.
402 */
403void JdwpState::CleanupMatchList(JdwpEvent** match_list, size_t match_count) {
404  JdwpEvent** ppEvent = match_list;
405
406  while (match_count--) {
407    JdwpEvent* pEvent = *ppEvent;
408
409    for (int i = 0; i < pEvent->modCount; i++) {
410      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
411        VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
412                                   pEvent->requestId);
413        UnregisterEvent(pEvent);
414        EventFree(pEvent);
415        break;
416      }
417    }
418
419    ppEvent++;
420  }
421
422  delete[] match_list;
423}
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 */
431static bool PatternMatch(const char* pattern, const std::string& target) {
432  size_t patLen = strlen(pattern);
433  if (pattern[0] == '*') {
434    patLen--;
435    if (target.size() < patLen) {
436      return false;
437    }
438    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
439  } else if (pattern[patLen-1] == '*') {
440    return strncmp(pattern, target.c_str(), patLen-1) == 0;
441  } else {
442    return strcmp(pattern, target.c_str()) == 0;
443  }
444}
445
446/*
447 * 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 */
452static bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
453    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
454  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--;
461      if (pMod->count.count > 0) {
462        return false;
463      }
464      break;
465    case MK_CONDITIONAL:
466      CHECK(false);  // should not be getting these
467      break;
468    case MK_THREAD_ONLY:
469      if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
470        return false;
471      }
472      break;
473    case MK_CLASS_ONLY:
474      if (!Dbg::MatchType(basket.locationClass, pMod->classOnly.refTypeId)) {
475        return false;
476      }
477      break;
478    case MK_CLASS_MATCH:
479      if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
480        return false;
481      }
482      break;
483    case MK_CLASS_EXCLUDE:
484      if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
485        return false;
486      }
487      break;
488    case MK_LOCATION_ONLY:
489      if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
490        return false;
491      }
492      break;
493    case MK_EXCEPTION_ONLY:
494      if (pMod->exceptionOnly.refTypeId != 0 &&
495          !Dbg::MatchType(basket.exceptionClass, pMod->exceptionOnly.refTypeId)) {
496        return false;
497      }
498      if ((basket.caught && !pMod->exceptionOnly.caught) ||
499          (!basket.caught && !pMod->exceptionOnly.uncaught)) {
500        return false;
501      }
502      break;
503    case MK_FIELD_ONLY:
504      if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
505        return false;
506      }
507      break;
508    case MK_STEP:
509      if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
510        return false;
511      }
512      break;
513    case MK_INSTANCE_ONLY:
514      if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr)) {
515        return false;
516      }
517      break;
518    default:
519      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
520      break;
521    }
522  }
523  return true;
524}
525
526/*
527 * Find all events of type "eventKind" with mods that match up with the
528 * rest of the arguments.
529 *
530 * Found events are appended to "match_list", and "*pMatchCount" is advanced,
531 * so this may be called multiple times for grouped events.
532 *
533 * DO NOT call this multiple times for the same eventKind, as Count mods are
534 * decremented during the scan.
535 */
536void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, const ModBasket& basket,
537                                   JdwpEvent** match_list, size_t* pMatchCount) {
538  /* start after the existing entries */
539  match_list += *pMatchCount;
540
541  for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
542    if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
543      *match_list++ = pEvent;
544      (*pMatchCount)++;
545    }
546  }
547}
548
549/*
550 * Scan through the list of matches and determine the most severe
551 * suspension policy.
552 */
553static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) {
554  JdwpSuspendPolicy policy = SP_NONE;
555
556  while (match_count--) {
557    if ((*match_list)->suspend_policy > policy) {
558      policy = (*match_list)->suspend_policy;
559    }
560    match_list++;
561  }
562
563  return policy;
564}
565
566/*
567 * Three possibilities:
568 *  SP_NONE - do nothing
569 *  SP_EVENT_THREAD - suspend ourselves
570 *  SP_ALL - suspend everybody except JDWP support thread
571 */
572void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
573  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
574  if (suspend_policy == SP_NONE) {
575    return;
576  }
577
578  if (suspend_policy == SP_ALL) {
579    Dbg::SuspendVM();
580  } else {
581    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
582  }
583
584  /* this is rare but possible -- see CLASS_PREPARE handling */
585  if (thread_self_id == debug_thread_id_) {
586    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
587    return;
588  }
589
590  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
591  while (true) {
592    pReq->ready = true;
593    Dbg::SuspendSelf();
594    pReq->ready = false;
595
596    /*
597     * The JDWP thread has told us (and possibly all other threads) to
598     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
599     */
600    if (!pReq->invoke_needed) {
601      /*LOGD("SuspendByPolicy: no invoke needed");*/
602      break;
603    }
604
605    /* grab this before posting/suspending again */
606    SetWaitForEventThread(thread_self_id);
607
608    /* leave pReq->invoke_needed_ raised so we can check reentrancy */
609    Dbg::ExecuteMethod(pReq);
610
611    pReq->error = ERR_NONE;
612  }
613}
614
615void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
616                                              ObjectId threadId) {
617  Thread* self = Thread::Current();
618  self->AssertThreadSuspensionIsAllowable();
619  /* send request and possibly suspend ourselves */
620  if (pReq != NULL) {
621    JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
622    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
623    if (suspend_policy != SP_NONE) {
624      SetWaitForEventThread(threadId);
625    }
626    EventFinish(pReq);
627    SuspendByPolicy(suspend_policy, thread_self_id);
628    self->TransitionFromSuspendedToRunnable();
629  }
630}
631
632/*
633 * Determine if there is a method invocation in progress in the current
634 * thread.
635 *
636 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
637 * state.  If set, we're in the process of invoking a method.
638 */
639bool JdwpState::InvokeInProgress() {
640  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
641  return pReq->invoke_needed;
642}
643
644/*
645 * We need the JDWP thread to hold off on doing stuff while we post an
646 * event and then suspend ourselves.
647 *
648 * Call this with a threadId of zero if you just want to wait for the
649 * current thread operation to complete.
650 *
651 * This could go to sleep waiting for another thread, so it's important
652 * that the thread be marked as VMWAIT before calling here.
653 */
654void JdwpState::SetWaitForEventThread(ObjectId threadId) {
655  bool waited = false;
656
657  /* this is held for very brief periods; contention is unlikely */
658  Thread* self = Thread::Current();
659  MutexLock mu(self, event_thread_lock_);
660
661  /*
662   * If another thread is already doing stuff, wait for it.  This can
663   * go to sleep indefinitely.
664   */
665  while (event_thread_id_ != 0) {
666    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
667                               event_thread_id_, threadId);
668    waited = true;
669    event_thread_cond_.Wait(self);
670  }
671
672  if (waited || threadId != 0) {
673    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
674  }
675  if (threadId != 0) {
676    event_thread_id_ = threadId;
677  }
678}
679
680/*
681 * Clear the threadId and signal anybody waiting.
682 */
683void JdwpState::ClearWaitForEventThread() {
684  /*
685   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
686   * function is called by dvmSuspendSelf(), and the transition back
687   * to RUNNING would confuse it.
688   */
689  Thread* self = Thread::Current();
690  MutexLock mu(self, event_thread_lock_);
691
692  CHECK_NE(event_thread_id_, 0U);
693  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", event_thread_id_);
694
695  event_thread_id_ = 0;
696
697  event_thread_cond_.Signal(self);
698}
699
700
701/*
702 * Prep an event.  Allocates storage for the message and leaves space for
703 * the header.
704 */
705static ExpandBuf* eventPrep() {
706  ExpandBuf* pReq = expandBufAlloc();
707  expandBufAddSpace(pReq, kJDWPHeaderLen);
708  return pReq;
709}
710
711/*
712 * Write the header into the buffer and send the packet off to the debugger.
713 *
714 * Takes ownership of "pReq" (currently discards it).
715 */
716void JdwpState::EventFinish(ExpandBuf* pReq) {
717  uint8_t* buf = expandBufGetBuffer(pReq);
718
719  Set4BE(buf, expandBufGetLength(pReq));
720  Set4BE(buf+4, NextRequestSerial());
721  Set1(buf+8, 0);     /* flags */
722  Set1(buf+9, kJdwpEventCommandSet);
723  Set1(buf+10, kJdwpCompositeCommand);
724
725  // Prevents from interleaving commands and events. Otherwise we could end up in sending an event
726  // before sending the reply of the command being processed and would lead to bad synchronization
727  // between the debugger and the debuggee.
728  WaitForProcessingRequest();
729
730  SendRequest(pReq);
731
732  expandBufFree(pReq);
733}
734
735
736/*
737 * Tell the debugger that we have finished initializing.  This is always
738 * sent, even if the debugger hasn't requested it.
739 *
740 * This should be sent "before the main thread is started and before
741 * any application code has been executed".  The thread ID in the message
742 * must be for the main thread.
743 */
744bool JdwpState::PostVMStart() {
745  JdwpSuspendPolicy suspend_policy;
746  ObjectId threadId = Dbg::GetThreadSelfId();
747
748  if (options_->suspend) {
749    suspend_policy = SP_ALL;
750  } else {
751    suspend_policy = SP_NONE;
752  }
753
754  ExpandBuf* pReq = eventPrep();
755  {
756    MutexLock mu(Thread::Current(), event_list_lock_);  // probably don't need this here
757
758    VLOG(jdwp) << "EVENT: " << EK_VM_START;
759    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
760
761    expandBufAdd1(pReq, suspend_policy);
762    expandBufAdd4BE(pReq, 1);
763
764    expandBufAdd1(pReq, EK_VM_START);
765    expandBufAdd4BE(pReq, 0);       /* requestId */
766    expandBufAdd8BE(pReq, threadId);
767  }
768
769  Dbg::ManageDeoptimization();
770
771  /* send request and possibly suspend ourselves */
772  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
773
774  return true;
775}
776
777static void LogMatchingEventsAndThread(JdwpEvent** match_list, size_t match_count,
778                                       ObjectId thread_id)
779    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
780  for (size_t i = 0; i < match_count; ++i) {
781    JdwpEvent* pEvent = match_list[i];
782    VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
783               << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
784  }
785  std::string thread_name;
786  JdwpError error = Dbg::GetThreadName(thread_id, thread_name);
787  if (error != JDWP::ERR_NONE) {
788    thread_name = "<unknown>";
789  }
790  VLOG(jdwp) << StringPrintf("  thread=%#" PRIx64, thread_id) << " " << thread_name;
791}
792
793static void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
794                                             JDWP::JdwpLocation* jdwp_location)
795    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
796  DCHECK(event_location != nullptr);
797  DCHECK(jdwp_location != nullptr);
798  Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
799}
800
801/*
802 * A location of interest has been reached.  This handles:
803 *   Breakpoint
804 *   SingleStep
805 *   MethodEntry
806 *   MethodExit
807 * These four types must be grouped together in a single response.  The
808 * "eventFlags" indicates the type of event(s) that have happened.
809 *
810 * Valid mods:
811 *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
812 *   LocationOnly (for breakpoint/step only)
813 *   Step (for step only)
814 *
815 * Interesting test cases:
816 *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
817 *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
818 *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
819 *  - Single-step to a line with a breakpoint.  Should get a single
820 *    event message with both events in it.
821 */
822bool JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
823                                  int eventFlags, const JValue* returnValue) {
824  DCHECK(pLoc != nullptr);
825  DCHECK(pLoc->method != nullptr);
826  DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
827
828  ModBasket basket;
829  basket.pLoc = pLoc;
830  basket.locationClass = pLoc->method->GetDeclaringClass();
831  basket.thisPtr = thisPtr;
832  basket.thread = Thread::Current();
833  basket.className = Dbg::GetClassName(basket.locationClass);
834
835  /*
836   * On rare occasions we may need to execute interpreted code in the VM
837   * while handling a request from the debugger.  Don't fire breakpoints
838   * while doing so.  (I don't think we currently do this at all, so
839   * this is mostly paranoia.)
840   */
841  if (basket.thread == GetDebugThread()) {
842    VLOG(jdwp) << "Ignoring location event in JDWP thread";
843    return false;
844  }
845
846  /*
847   * The debugger variable display tab may invoke the interpreter to format
848   * complex objects.  We want to ignore breakpoints and method entry/exit
849   * traps while working on behalf of the debugger.
850   *
851   * If we don't ignore them, the VM will get hung up, because we'll
852   * suspend on a breakpoint while the debugger is still waiting for its
853   * method invocation to complete.
854   */
855  if (InvokeInProgress()) {
856    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
857    return false;
858  }
859
860  size_t match_count = 0;
861  ExpandBuf* pReq = NULL;
862  JdwpSuspendPolicy suspend_policy = SP_NONE;
863  JdwpEvent** match_list = nullptr;
864  ObjectId thread_id = 0;
865  {
866    {
867      MutexLock mu(Thread::Current(), event_list_lock_);
868      match_list = AllocMatchList(event_list_size_);
869      if ((eventFlags & Dbg::kBreakpoint) != 0) {
870        FindMatchingEvents(EK_BREAKPOINT, basket, match_list, &match_count);
871      }
872      if ((eventFlags & Dbg::kSingleStep) != 0) {
873        FindMatchingEvents(EK_SINGLE_STEP, basket, match_list, &match_count);
874      }
875      if ((eventFlags & Dbg::kMethodEntry) != 0) {
876        FindMatchingEvents(EK_METHOD_ENTRY, basket, match_list, &match_count);
877      }
878      if ((eventFlags & Dbg::kMethodExit) != 0) {
879        FindMatchingEvents(EK_METHOD_EXIT, basket, match_list, &match_count);
880        FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, match_list, &match_count);
881      }
882    }
883    if (match_count != 0) {
884      suspend_policy = scanSuspendPolicy(match_list, match_count);
885
886      thread_id = Dbg::GetThreadId(basket.thread);
887      JDWP::JdwpLocation jdwp_location;
888      SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
889
890      if (VLOG_IS_ON(jdwp)) {
891        LogMatchingEventsAndThread(match_list, match_count, thread_id);
892        VLOG(jdwp) << "  location=" << jdwp_location;
893        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
894      }
895
896      pReq = eventPrep();
897      expandBufAdd1(pReq, suspend_policy);
898      expandBufAdd4BE(pReq, match_count);
899
900      for (size_t i = 0; i < match_count; i++) {
901        expandBufAdd1(pReq, match_list[i]->eventKind);
902        expandBufAdd4BE(pReq, match_list[i]->requestId);
903        expandBufAdd8BE(pReq, thread_id);
904        expandBufAddLocation(pReq, jdwp_location);
905        if (match_list[i]->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
906          Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
907        }
908      }
909    }
910
911    {
912      MutexLock mu(Thread::Current(), event_list_lock_);
913      CleanupMatchList(match_list, match_count);
914    }
915  }
916
917  Dbg::ManageDeoptimization();
918
919  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
920  return match_count != 0;
921}
922
923bool JdwpState::PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field,
924                               mirror::Object* this_object, const JValue* fieldValue,
925                               bool is_modification) {
926  DCHECK(pLoc != nullptr);
927  DCHECK(field != nullptr);
928  DCHECK_EQ(fieldValue != nullptr, is_modification);
929  DCHECK_EQ(field->IsStatic(), this_object == nullptr);
930
931  ModBasket basket;
932  basket.pLoc = pLoc;
933  basket.locationClass = pLoc->method->GetDeclaringClass();
934  basket.thisPtr = this_object;
935  basket.thread = Thread::Current();
936  basket.className = Dbg::GetClassName(basket.locationClass);
937  basket.field = field;
938
939  if (InvokeInProgress()) {
940    VLOG(jdwp) << "Not posting field event during invoke";
941    return false;
942  }
943
944  size_t match_count = 0;
945  ExpandBuf* pReq = NULL;
946  JdwpSuspendPolicy suspend_policy = SP_NONE;
947  JdwpEvent** match_list = nullptr;
948  ObjectId thread_id = 0;
949  {
950    {
951      MutexLock mu(Thread::Current(), event_list_lock_);
952      match_list = AllocMatchList(event_list_size_);
953      if (is_modification) {
954        FindMatchingEvents(EK_FIELD_MODIFICATION, basket, match_list, &match_count);
955      } else {
956        FindMatchingEvents(EK_FIELD_ACCESS, basket, match_list, &match_count);
957      }
958    }
959    if (match_count != 0) {
960      suspend_policy = scanSuspendPolicy(match_list, match_count);
961
962      thread_id = Dbg::GetThreadId(basket.thread);
963      ObjectRegistry* registry = Dbg::GetObjectRegistry();
964      ObjectId instance_id = registry->Add(basket.thisPtr);
965      RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
966      FieldId field_id = Dbg::ToFieldId(field);
967      JDWP::JdwpLocation jdwp_location;
968      SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
969
970      if (VLOG_IS_ON(jdwp)) {
971        LogMatchingEventsAndThread(match_list, match_count, thread_id);
972        VLOG(jdwp) << "  location=" << jdwp_location;
973        VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
974        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
975                   << Dbg::GetClassName(field_id);
976        VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, field_id) << " "
977                   << Dbg::GetFieldName(field_id);
978        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
979      }
980
981      pReq = eventPrep();
982      expandBufAdd1(pReq, suspend_policy);
983      expandBufAdd4BE(pReq, match_count);
984
985      // Get field's reference type tag.
986      JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
987
988      // Get instance type tag.
989      uint8_t tag;
990      {
991        ScopedObjectAccessUnchecked soa(Thread::Current());
992        tag = Dbg::TagFromObject(soa, basket.thisPtr);
993      }
994
995      for (size_t i = 0; i < match_count; i++) {
996        expandBufAdd1(pReq, match_list[i]->eventKind);
997        expandBufAdd4BE(pReq, match_list[i]->requestId);
998        expandBufAdd8BE(pReq, thread_id);
999        expandBufAddLocation(pReq, jdwp_location);
1000        expandBufAdd1(pReq, type_tag);
1001        expandBufAddRefTypeId(pReq, field_type_id);
1002        expandBufAddFieldId(pReq, field_id);
1003        expandBufAdd1(pReq, tag);
1004        expandBufAddObjectId(pReq, instance_id);
1005        if (is_modification) {
1006          Dbg::OutputFieldValue(field_id, fieldValue, pReq);
1007        }
1008      }
1009    }
1010
1011    {
1012      MutexLock mu(Thread::Current(), event_list_lock_);
1013      CleanupMatchList(match_list, match_count);
1014    }
1015  }
1016
1017  Dbg::ManageDeoptimization();
1018
1019  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1020  return match_count != 0;
1021}
1022
1023/*
1024 * A thread is starting or stopping.
1025 *
1026 * Valid mods:
1027 *  Count, ThreadOnly
1028 */
1029bool JdwpState::PostThreadChange(Thread* thread, bool start) {
1030  CHECK_EQ(thread, Thread::Current());
1031
1032  /*
1033   * I don't think this can happen.
1034   */
1035  if (InvokeInProgress()) {
1036    LOG(WARNING) << "Not posting thread change during invoke";
1037    return false;
1038  }
1039
1040  ModBasket basket;
1041  basket.thread = thread;
1042
1043  ExpandBuf* pReq = NULL;
1044  JdwpSuspendPolicy suspend_policy = SP_NONE;
1045  JdwpEvent** match_list = nullptr;
1046  size_t match_count = 0;
1047  ObjectId thread_id = 0;
1048  {
1049    {
1050      // Don't allow the list to be updated while we scan it.
1051      MutexLock mu(Thread::Current(), event_list_lock_);
1052      match_list = AllocMatchList(event_list_size_);
1053      if (start) {
1054        FindMatchingEvents(EK_THREAD_START, basket, match_list, &match_count);
1055      } else {
1056        FindMatchingEvents(EK_THREAD_DEATH, basket, match_list, &match_count);
1057      }
1058    }
1059
1060    if (match_count != 0) {
1061      suspend_policy = scanSuspendPolicy(match_list, match_count);
1062
1063      thread_id = Dbg::GetThreadId(basket.thread);
1064
1065      if (VLOG_IS_ON(jdwp)) {
1066        LogMatchingEventsAndThread(match_list, match_count, thread_id);
1067        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1068      }
1069
1070      pReq = eventPrep();
1071      expandBufAdd1(pReq, suspend_policy);
1072      expandBufAdd4BE(pReq, match_count);
1073
1074      for (size_t i = 0; i < match_count; i++) {
1075        expandBufAdd1(pReq, match_list[i]->eventKind);
1076        expandBufAdd4BE(pReq, match_list[i]->requestId);
1077        expandBufAdd8BE(pReq, thread_id);
1078      }
1079    }
1080
1081    {
1082      MutexLock mu(Thread::Current(), event_list_lock_);
1083      CleanupMatchList(match_list, match_count);
1084    }
1085  }
1086
1087  Dbg::ManageDeoptimization();
1088
1089  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1090
1091  return match_count != 0;
1092}
1093
1094/*
1095 * Send a polite "VM is dying" message to the debugger.
1096 *
1097 * Skips the usual "event token" stuff.
1098 */
1099bool JdwpState::PostVMDeath() {
1100  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
1101
1102  ExpandBuf* pReq = eventPrep();
1103  expandBufAdd1(pReq, SP_NONE);
1104  expandBufAdd4BE(pReq, 1);
1105
1106  expandBufAdd1(pReq, EK_VM_DEATH);
1107  expandBufAdd4BE(pReq, 0);
1108  EventFinish(pReq);
1109  return true;
1110}
1111
1112/*
1113 * An exception has been thrown.  It may or may not have been caught.
1114 *
1115 * Valid mods:
1116 *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1117 *    ExceptionOnly, InstanceOnly
1118 *
1119 * The "exceptionId" has not been added to the GC-visible object registry,
1120 * because there's a pretty good chance that we're not going to send it
1121 * up the debugger.
1122 */
1123bool JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
1124                              const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
1125  DCHECK(exception_object != nullptr);
1126  DCHECK(pThrowLoc != nullptr);
1127  DCHECK(pCatchLoc != nullptr);
1128  if (pThrowLoc->method != nullptr) {
1129    DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1130  } else {
1131    VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1132  }
1133
1134  ModBasket basket;
1135  basket.pLoc = pThrowLoc;
1136  if (pThrowLoc->method != nullptr) {
1137    basket.locationClass = pThrowLoc->method->GetDeclaringClass();
1138  } else {
1139    basket.locationClass = nullptr;
1140  }
1141  basket.thread = Thread::Current();
1142  basket.className = Dbg::GetClassName(basket.locationClass);
1143  basket.exceptionClass = exception_object->GetClass();
1144  basket.caught = (pCatchLoc->method != 0);
1145  basket.thisPtr = thisPtr;
1146
1147  /* don't try to post an exception caused by the debugger */
1148  if (InvokeInProgress()) {
1149    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
1150    return false;
1151  }
1152
1153  size_t match_count = 0;
1154  ExpandBuf* pReq = NULL;
1155  JdwpSuspendPolicy suspend_policy = SP_NONE;
1156  JdwpEvent** match_list = nullptr;
1157  ObjectId thread_id = 0;
1158  {
1159    {
1160      MutexLock mu(Thread::Current(), event_list_lock_);
1161      match_list = AllocMatchList(event_list_size_);
1162      FindMatchingEvents(EK_EXCEPTION, basket, match_list, &match_count);
1163    }
1164    if (match_count != 0) {
1165      suspend_policy = scanSuspendPolicy(match_list, match_count);
1166
1167      thread_id = Dbg::GetThreadId(basket.thread);
1168      ObjectRegistry* registry = Dbg::GetObjectRegistry();
1169      ObjectId exceptionId = registry->Add(exception_object);
1170      JDWP::JdwpLocation jdwp_throw_location;
1171      JDWP::JdwpLocation jdwp_catch_location;
1172      SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
1173      SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
1174
1175      if (VLOG_IS_ON(jdwp)) {
1176        std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
1177
1178        LogMatchingEventsAndThread(match_list, match_count, thread_id);
1179        VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
1180        if (jdwp_catch_location.class_id == 0) {
1181          VLOG(jdwp) << "  catchLocation=uncaught";
1182        } else {
1183          VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
1184        }
1185        VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
1186                   << exceptionClassName;
1187        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1188      }
1189
1190      pReq = eventPrep();
1191      expandBufAdd1(pReq, suspend_policy);
1192      expandBufAdd4BE(pReq, match_count);
1193
1194      for (size_t i = 0; i < match_count; i++) {
1195        expandBufAdd1(pReq, match_list[i]->eventKind);
1196        expandBufAdd4BE(pReq, match_list[i]->requestId);
1197        expandBufAdd8BE(pReq, thread_id);
1198        expandBufAddLocation(pReq, jdwp_throw_location);
1199        expandBufAdd1(pReq, JT_OBJECT);
1200        expandBufAdd8BE(pReq, exceptionId);
1201        expandBufAddLocation(pReq, jdwp_catch_location);
1202      }
1203    }
1204
1205    {
1206      MutexLock mu(Thread::Current(), event_list_lock_);
1207      CleanupMatchList(match_list, match_count);
1208    }
1209  }
1210
1211  Dbg::ManageDeoptimization();
1212
1213  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1214
1215  return match_count != 0;
1216}
1217
1218/*
1219 * Announce that a class has been loaded.
1220 *
1221 * Valid mods:
1222 *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1223 */
1224bool JdwpState::PostClassPrepare(mirror::Class* klass) {
1225  DCHECK(klass != nullptr);
1226
1227  ModBasket basket;
1228  basket.locationClass = klass;
1229  basket.thread = Thread::Current();
1230  basket.className = Dbg::GetClassName(basket.locationClass);
1231
1232  /* suppress class prep caused by debugger */
1233  if (InvokeInProgress()) {
1234    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
1235    return false;
1236  }
1237
1238  ExpandBuf* pReq = NULL;
1239  JdwpSuspendPolicy suspend_policy = SP_NONE;
1240  JdwpEvent** match_list = nullptr;
1241  size_t match_count = 0;
1242  ObjectId thread_id = 0;
1243  {
1244    {
1245      MutexLock mu(Thread::Current(), event_list_lock_);
1246      match_list = AllocMatchList(event_list_size_);
1247      FindMatchingEvents(EK_CLASS_PREPARE, basket, match_list, &match_count);
1248    }
1249    if (match_count != 0) {
1250      suspend_policy = scanSuspendPolicy(match_list, match_count);
1251
1252      thread_id = Dbg::GetThreadId(basket.thread);
1253      ObjectRegistry* registry = Dbg::GetObjectRegistry();
1254      RefTypeId class_id = registry->AddRefType(basket.locationClass);
1255
1256      // OLD-TODO - we currently always send both "verified" and "prepared" since
1257      // debuggers seem to like that.  There might be some advantage to honesty,
1258      // since the class may not yet be verified.
1259      int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
1260      JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass);
1261      std::string temp;
1262      std::string signature(basket.locationClass->GetDescriptor(&temp));
1263
1264      if (VLOG_IS_ON(jdwp)) {
1265        LogMatchingEventsAndThread(match_list, match_count, thread_id);
1266        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
1267        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1268      }
1269
1270      if (thread_id == debug_thread_id_) {
1271        /*
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!";
1277        thread_id = 0;
1278        if (suspend_policy == SP_EVENT_THREAD) {
1279          suspend_policy = SP_ALL;
1280        }
1281      }
1282
1283      pReq = eventPrep();
1284      expandBufAdd1(pReq, suspend_policy);
1285      expandBufAdd4BE(pReq, match_count);
1286
1287      for (size_t i = 0; i < match_count; i++) {
1288        expandBufAdd1(pReq, match_list[i]->eventKind);
1289        expandBufAdd4BE(pReq, match_list[i]->requestId);
1290        expandBufAdd8BE(pReq, thread_id);
1291        expandBufAdd1(pReq, tag);
1292        expandBufAdd8BE(pReq, class_id);
1293        expandBufAddUtf8String(pReq, signature);
1294        expandBufAdd4BE(pReq, status);
1295      }
1296    }
1297
1298    {
1299      MutexLock mu(Thread::Current(), event_list_lock_);
1300      CleanupMatchList(match_list, match_count);
1301    }
1302  }
1303
1304  Dbg::ManageDeoptimization();
1305
1306  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1307
1308  return match_count != 0;
1309}
1310
1311/*
1312 * Send up a chunk of DDM data.
1313 *
1314 * While this takes the form of a JDWP "event", it doesn't interact with
1315 * other debugger traffic, and can't suspend the VM, so we skip all of
1316 * the fun event token gymnastics.
1317 */
1318void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1319  uint8_t header[kJDWPHeaderLen + 8];
1320  size_t dataLen = 0;
1321
1322  CHECK(iov != NULL);
1323  CHECK_GT(iov_count, 0);
1324  CHECK_LT(iov_count, 10);
1325
1326  /*
1327   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1328   * this by creating a new copy of the vector with space for the header.
1329   */
1330  std::vector<iovec> wrapiov;
1331  wrapiov.push_back(iovec());
1332  for (int i = 0; i < iov_count; i++) {
1333    wrapiov.push_back(iov[i]);
1334    dataLen += iov[i].iov_len;
1335  }
1336
1337  /* form the header (JDWP plus DDMS) */
1338  Set4BE(header, sizeof(header) + dataLen);
1339  Set4BE(header+4, NextRequestSerial());
1340  Set1(header+8, 0);     /* flags */
1341  Set1(header+9, kJDWPDdmCmdSet);
1342  Set1(header+10, kJDWPDdmCmd);
1343  Set4BE(header+11, type);
1344  Set4BE(header+15, dataLen);
1345
1346  wrapiov[0].iov_base = header;
1347  wrapiov[0].iov_len = sizeof(header);
1348
1349  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
1350  // than mutator for lock ordering reasons.
1351  Thread* self = Thread::Current();
1352  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
1353  if (safe_to_release_mutator_lock_over_send) {
1354    for (size_t i = 0; i < kMutatorLock; ++i) {
1355      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) {
1356        safe_to_release_mutator_lock_over_send = false;
1357        break;
1358      }
1359    }
1360  }
1361  if (safe_to_release_mutator_lock_over_send) {
1362    // Change state to waiting to allow GC, ... while we're sending.
1363    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1364    SendBufferedRequest(type, wrapiov);
1365    self->TransitionFromSuspendedToRunnable();
1366  } else {
1367    // Send and possibly block GC...
1368    SendBufferedRequest(type, wrapiov);
1369  }
1370}
1371
1372}  // namespace JDWP
1373
1374}  // namespace art
1375