jdwp_event.cc revision 4d25df3f76f864b7629ac8c0046d46997f293d8d
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 "thread-inl.h"
31
32/*
33General notes:
34
35The event add/remove stuff usually happens from the debugger thread,
36in response to requests from the debugger, but can also happen as the
37result of an event in an arbitrary thread (e.g. an event with a "count"
38mod expires).  It's important to keep the event list locked when processing
39events.
40
41Event posting can happen from any thread.  The JDWP thread will not usually
42post anything but VM start/death, but if a JDWP request causes a class
43to be loaded, the ClassPrepare event will come from the JDWP thread.
44
45
46We can have serialization issues when we post an event to the debugger.
47For example, a thread could send an "I hit a breakpoint and am suspending
48myself" message to the debugger.  Before it manages to suspend itself, the
49debugger's response ("not interested, resume thread") arrives and is
50processed.  We try to resume a thread that hasn't yet suspended.
51
52This means that, after posting an event to the debugger, we need to wait
53for the event thread to suspend itself (and, potentially, all other threads)
54before processing any additional requests from the debugger.  While doing
55so we need to be aware that multiple threads may be hitting breakpoints
56or other events simultaneously, so we either need to wait for all of them
57or serialize the events with each other.
58
59The current mechanism works like this:
60  Event thread:
61   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
62     for it if it's not currently available.
63   - Post the event to the debugger.
64   - If appropriate, suspend others and then myself.  As part of suspending
65     myself, release the "I am posting" token.
66  JDWP thread:
67   - When an event arrives, see if somebody is posting an event.  If so,
68     sleep until we can acquire the "I am posting an event" token.  Release
69     it immediately and continue processing -- the event we have already
70     received should not interfere with other events that haven't yet
71     been posted.
72
73Some care must be taken to avoid deadlock:
74
75 - thread A and thread B exit near-simultaneously, and post thread-death
76   events with a "suspend all" clause
77 - thread A gets the event token, thread B sits and waits for it
78 - thread A wants to suspend all other threads, but thread B is waiting
79   for the token and can't be suspended
80
81So we need to mark thread B in such a way that thread A doesn't wait for it.
82
83If we just bracket the "grab event token" call with a change to VMWAIT
84before sleeping, the switch back to RUNNING state when we get the token
85will cause thread B to suspend (remember, thread A's global suspend is
86still in force, even after it releases the token).  Suspending while
87holding the event token is very bad, because it prevents the JDWP thread
88from processing incoming messages.
89
90We need to change to VMWAIT state at the *start* of posting an event,
91and stay there until we either finish posting the event or decide to
92put ourselves to sleep.  That way we don't interfere with anyone else and
93don't allow anyone else to interfere with us.
94*/
95
96
97#define kJdwpEventCommandSet    64
98#define kJdwpCompositeCommand   100
99
100namespace art {
101
102namespace JDWP {
103
104/*
105 * Stuff to compare against when deciding if a mod matches.  Only the
106 * values for mods valid for the event being evaluated will be filled in.
107 * The rest will be zeroed.
108 */
109struct ModBasket {
110  ModBasket() : pLoc(NULL), threadId(0), classId(0), excepClassId(0),
111                caught(false), field(0), thisPtr(0) { }
112
113  const JdwpLocation* pLoc;           /* LocationOnly */
114  std::string         className;      /* ClassMatch/ClassExclude */
115  ObjectId            threadId;       /* ThreadOnly */
116  RefTypeId           classId;        /* ClassOnly */
117  RefTypeId           excepClassId;   /* ExceptionOnly */
118  bool                caught;         /* ExceptionOnly */
119  FieldId             field;          /* FieldOnly */
120  ObjectId            thisPtr;        /* InstanceOnly */
121  /* nothing for StepOnly -- handled differently */
122};
123
124/*
125 * Dump an event to the log file.
126 */
127static void dumpEvent(const JdwpEvent* pEvent) {
128  LOG(INFO) << StringPrintf("Event id=0x%4x %p (prev=%p next=%p):", pEvent->requestId, pEvent, pEvent->prev, pEvent->next);
129  LOG(INFO) << "  kind=" << pEvent->eventKind << " susp=" << pEvent->suspend_policy << " modCount=" << pEvent->modCount;
130
131  for (int i = 0; i < pEvent->modCount; i++) {
132    const JdwpEventMod* pMod = &pEvent->mods[i];
133    LOG(INFO) << "  " << pMod->modKind;
134    /* TODO - show details */
135  }
136}
137
138static bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
139  switch (eventKind) {
140      case EK_METHOD_ENTRY:
141      case EK_METHOD_EXIT:
142      case EK_METHOD_EXIT_WITH_RETURN_VALUE:
143      case EK_SINGLE_STEP:
144        return true;
145      default:
146        return false;
147    }
148}
149
150/*
151 * Add an event to the list.  Ordering is not important.
152 *
153 * If something prevents the event from being registered, e.g. it's a
154 * single-step request on a thread that doesn't exist, the event will
155 * not be added to the list, and an appropriate error will be returned.
156 */
157JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
158  CHECK(pEvent != NULL);
159  CHECK(pEvent->prev == NULL);
160  CHECK(pEvent->next == NULL);
161
162  /*
163   * If one or more "break"-type mods are used, register them with
164   * the interpreter.
165   */
166  DeoptimizationRequest req;
167  for (int i = 0; i < pEvent->modCount; i++) {
168    const JdwpEventMod* pMod = &pEvent->mods[i];
169    if (pMod->modKind == MK_LOCATION_ONLY) {
170      /* should only be for Breakpoint, Step, and Exception */
171      Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
172    } else if (pMod->modKind == MK_STEP) {
173      /* should only be for EK_SINGLE_STEP; should only be one */
174      JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
175      JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
176      JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
177      if (status != ERR_NONE) {
178        return status;
179      }
180    } else if (pMod->modKind == MK_FIELD_ONLY) {
181      /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */
182      dumpEvent(pEvent);  /* TODO - need for field watches */
183    }
184  }
185  if (NeedsFullDeoptimization(pEvent->eventKind)) {
186    CHECK_EQ(req.kind, DeoptimizationRequest::kNothing);
187    CHECK(req.method == nullptr);
188    req.kind = DeoptimizationRequest::kFullDeoptimization;
189  }
190
191  {
192    /*
193     * Add to list.
194     */
195    MutexLock mu(Thread::Current(), event_list_lock_);
196    if (event_list_ != NULL) {
197      pEvent->next = event_list_;
198      event_list_->prev = pEvent;
199    }
200    event_list_ = pEvent;
201    ++event_list_size_;
202  }
203
204  // TODO we can do better job here since we should process only one request: the one we just
205  // created.
206  Dbg::RequestDeoptimization(req);
207  Dbg::ManageDeoptimization();
208
209  return ERR_NONE;
210}
211
212/*
213 * Remove an event from the list.  This will also remove the event from
214 * any optimization tables, e.g. breakpoints.
215 *
216 * Does not free the JdwpEvent.
217 *
218 * Grab the eventLock before calling here.
219 */
220void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
221  if (pEvent->prev == NULL) {
222    /* head of the list */
223    CHECK(event_list_ == pEvent);
224
225    event_list_ = pEvent->next;
226  } else {
227    pEvent->prev->next = pEvent->next;
228  }
229
230  if (pEvent->next != NULL) {
231    pEvent->next->prev = pEvent->prev;
232    pEvent->next = NULL;
233  }
234  pEvent->prev = NULL;
235
236  /*
237   * Unhook us from the interpreter, if necessary.
238   */
239  DeoptimizationRequest req;
240  for (int i = 0; i < pEvent->modCount; i++) {
241    JdwpEventMod* pMod = &pEvent->mods[i];
242    if (pMod->modKind == MK_LOCATION_ONLY) {
243      /* should only be for Breakpoint, Step, and Exception */
244      Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
245    }
246    if (pMod->modKind == MK_STEP) {
247      /* should only be for EK_SINGLE_STEP; should only be one */
248      Dbg::UnconfigureStep(pMod->step.threadId);
249    }
250  }
251  if (NeedsFullDeoptimization(pEvent->eventKind)) {
252    CHECK_EQ(req.kind, DeoptimizationRequest::kNothing);
253    CHECK(req.method == nullptr);
254    req.kind = DeoptimizationRequest::kFullUndeoptimization;
255  }
256
257  --event_list_size_;
258  CHECK(event_list_size_ != 0 || event_list_ == NULL);
259
260  Dbg::RequestDeoptimization(req);
261}
262
263/*
264 * Remove the event with the given ID from the list.
265 *
266 * Failure to find the event isn't really an error, but it is a little
267 * weird.  (It looks like Eclipse will try to be extra careful and will
268 * explicitly remove one-off single-step events.)
269 */
270void JdwpState::UnregisterEventById(uint32_t requestId) {
271  bool found = false;
272  {
273    MutexLock mu(Thread::Current(), event_list_lock_);
274
275    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
276      if (pEvent->requestId == requestId) {
277        found = true;
278        UnregisterEvent(pEvent);
279        EventFree(pEvent);
280        break;      /* there can be only one with a given ID */
281      }
282    }
283  }
284
285  if (found) {
286    Dbg::ManageDeoptimization();
287  } else {
288    LOG(DEBUG) << StringPrintf("Odd: no match when removing event reqId=0x%04x", requestId);
289  }
290}
291
292/*
293 * Remove all entries from the event list.
294 */
295void JdwpState::UnregisterAll() {
296  MutexLock mu(Thread::Current(), event_list_lock_);
297
298  JdwpEvent* pEvent = event_list_;
299  while (pEvent != NULL) {
300    JdwpEvent* pNextEvent = pEvent->next;
301
302    UnregisterEvent(pEvent);
303    EventFree(pEvent);
304    pEvent = pNextEvent;
305  }
306
307  event_list_ = NULL;
308}
309
310/*
311 * Allocate a JdwpEvent struct with enough space to hold the specified
312 * number of mod records.
313 */
314JdwpEvent* EventAlloc(int numMods) {
315  JdwpEvent* newEvent;
316  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
317  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
318  memset(newEvent, 0, allocSize);
319  return newEvent;
320}
321
322/*
323 * Free a JdwpEvent.
324 *
325 * Do not call this until the event has been removed from the list.
326 */
327void EventFree(JdwpEvent* pEvent) {
328  if (pEvent == NULL) {
329    return;
330  }
331
332  /* make sure it was removed from the list */
333  CHECK(pEvent->prev == NULL);
334  CHECK(pEvent->next == NULL);
335  /* want to check state->event_list_ != pEvent */
336
337  /*
338   * Free any hairy bits in the mods.
339   */
340  for (int i = 0; i < pEvent->modCount; i++) {
341    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
342      free(pEvent->mods[i].classMatch.classPattern);
343      pEvent->mods[i].classMatch.classPattern = NULL;
344    }
345    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
346      free(pEvent->mods[i].classExclude.classPattern);
347      pEvent->mods[i].classExclude.classPattern = NULL;
348    }
349  }
350
351  free(pEvent);
352}
353
354/*
355 * Allocate storage for matching events.  To keep things simple we
356 * use an array with enough storage for the entire list.
357 *
358 * The state->eventLock should be held before calling.
359 */
360static JdwpEvent** AllocMatchList(size_t event_count) {
361  return new JdwpEvent*[event_count];
362}
363
364/*
365 * Run through the list and remove any entries with an expired "count" mod
366 * from the event list, then free the match list.
367 */
368void JdwpState::CleanupMatchList(JdwpEvent** match_list, int match_count) {
369  JdwpEvent** ppEvent = match_list;
370
371  while (match_count--) {
372    JdwpEvent* pEvent = *ppEvent;
373
374    for (int i = 0; i < pEvent->modCount; i++) {
375      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
376        VLOG(jdwp) << "##### Removing expired event";
377        UnregisterEvent(pEvent);
378        EventFree(pEvent);
379        break;
380      }
381    }
382
383    ppEvent++;
384  }
385
386  delete[] match_list;
387}
388
389/*
390 * Match a string against a "restricted regular expression", which is just
391 * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
392 *
393 * ("Restricted name globbing" might have been a better term.)
394 */
395static bool PatternMatch(const char* pattern, const std::string& target) {
396  size_t patLen = strlen(pattern);
397  if (pattern[0] == '*') {
398    patLen--;
399    if (target.size() < patLen) {
400      return false;
401    }
402    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
403  } else if (pattern[patLen-1] == '*') {
404    return strncmp(pattern, target.c_str(), patLen-1) == 0;
405  } else {
406    return strcmp(pattern, target.c_str()) == 0;
407  }
408}
409
410/*
411 * See if the event's mods match up with the contents of "basket".
412 *
413 * If we find a Count mod before rejecting an event, we decrement it.  We
414 * need to do this even if later mods cause us to ignore the event.
415 */
416static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket)
417    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
418  JdwpEventMod* pMod = pEvent->mods;
419
420  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
421    switch (pMod->modKind) {
422    case MK_COUNT:
423      CHECK_GT(pMod->count.count, 0);
424      pMod->count.count--;
425      break;
426    case MK_CONDITIONAL:
427      CHECK(false);  // should not be getting these
428      break;
429    case MK_THREAD_ONLY:
430      if (pMod->threadOnly.threadId != basket->threadId) {
431        return false;
432      }
433      break;
434    case MK_CLASS_ONLY:
435      if (!Dbg::MatchType(basket->classId, pMod->classOnly.refTypeId)) {
436        return false;
437      }
438      break;
439    case MK_CLASS_MATCH:
440      if (!PatternMatch(pMod->classMatch.classPattern, basket->className)) {
441        return false;
442      }
443      break;
444    case MK_CLASS_EXCLUDE:
445      if (PatternMatch(pMod->classMatch.classPattern, basket->className)) {
446        return false;
447      }
448      break;
449    case MK_LOCATION_ONLY:
450      if (pMod->locationOnly.loc != *basket->pLoc) {
451        return false;
452      }
453      break;
454    case MK_EXCEPTION_ONLY:
455      if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket->excepClassId, pMod->exceptionOnly.refTypeId)) {
456        return false;
457      }
458      if ((basket->caught && !pMod->exceptionOnly.caught) || (!basket->caught && !pMod->exceptionOnly.uncaught)) {
459        return false;
460      }
461      break;
462    case MK_FIELD_ONLY:
463      if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) {
464        return false;
465      }
466      break;
467    case MK_STEP:
468      if (pMod->step.threadId != basket->threadId) {
469        return false;
470      }
471      break;
472    case MK_INSTANCE_ONLY:
473      if (pMod->instanceOnly.objectId != basket->thisPtr) {
474        return false;
475      }
476      break;
477    default:
478      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
479      break;
480    }
481  }
482  return true;
483}
484
485/*
486 * Find all events of type "eventKind" with mods that match up with the
487 * rest of the arguments.
488 *
489 * Found events are appended to "match_list", and "*pMatchCount" is advanced,
490 * so this may be called multiple times for grouped events.
491 *
492 * DO NOT call this multiple times for the same eventKind, as Count mods are
493 * decremented during the scan.
494 */
495void JdwpState::FindMatchingEvents(JdwpEventKind eventKind, ModBasket* basket,
496                                   JdwpEvent** match_list, int* pMatchCount) {
497  /* start after the existing entries */
498  match_list += *pMatchCount;
499
500  JdwpEvent* pEvent = event_list_;
501  while (pEvent != NULL) {
502    if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
503      *match_list++ = pEvent;
504      (*pMatchCount)++;
505    }
506
507    pEvent = pEvent->next;
508  }
509}
510
511/*
512 * Scan through the list of matches and determine the most severe
513 * suspension policy.
514 */
515static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) {
516  JdwpSuspendPolicy policy = SP_NONE;
517
518  while (match_count--) {
519    if ((*match_list)->suspend_policy > policy) {
520      policy = (*match_list)->suspend_policy;
521    }
522    match_list++;
523  }
524
525  return policy;
526}
527
528/*
529 * Three possibilities:
530 *  SP_NONE - do nothing
531 *  SP_EVENT_THREAD - suspend ourselves
532 *  SP_ALL - suspend everybody except JDWP support thread
533 */
534void JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
535  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
536  if (suspend_policy == SP_NONE) {
537    return;
538  }
539
540  if (suspend_policy == SP_ALL) {
541    Dbg::SuspendVM();
542  } else {
543    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
544  }
545
546  /* this is rare but possible -- see CLASS_PREPARE handling */
547  if (thread_self_id == debug_thread_id_) {
548    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
549    return;
550  }
551
552  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
553  while (true) {
554    pReq->ready = true;
555    Dbg::SuspendSelf();
556    pReq->ready = false;
557
558    /*
559     * The JDWP thread has told us (and possibly all other threads) to
560     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
561     */
562    if (!pReq->invoke_needed) {
563      /*LOGD("SuspendByPolicy: no invoke needed");*/
564      break;
565    }
566
567    /* grab this before posting/suspending again */
568    SetWaitForEventThread(thread_self_id);
569
570    /* leave pReq->invoke_needed_ raised so we can check reentrancy */
571    Dbg::ExecuteMethod(pReq);
572
573    pReq->error = ERR_NONE;
574  }
575}
576
577void JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
578                                              ObjectId threadId) {
579  Thread* self = Thread::Current();
580  self->AssertThreadSuspensionIsAllowable();
581  /* send request and possibly suspend ourselves */
582  if (pReq != NULL) {
583    JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
584    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
585    if (suspend_policy != SP_NONE) {
586      SetWaitForEventThread(threadId);
587    }
588    EventFinish(pReq);
589    SuspendByPolicy(suspend_policy, thread_self_id);
590    self->TransitionFromSuspendedToRunnable();
591  }
592}
593
594/*
595 * Determine if there is a method invocation in progress in the current
596 * thread.
597 *
598 * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
599 * state.  If set, we're in the process of invoking a method.
600 */
601bool JdwpState::InvokeInProgress() {
602  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
603  return pReq->invoke_needed;
604}
605
606/*
607 * We need the JDWP thread to hold off on doing stuff while we post an
608 * event and then suspend ourselves.
609 *
610 * Call this with a threadId of zero if you just want to wait for the
611 * current thread operation to complete.
612 *
613 * This could go to sleep waiting for another thread, so it's important
614 * that the thread be marked as VMWAIT before calling here.
615 */
616void JdwpState::SetWaitForEventThread(ObjectId threadId) {
617  bool waited = false;
618
619  /* this is held for very brief periods; contention is unlikely */
620  Thread* self = Thread::Current();
621  MutexLock mu(self, event_thread_lock_);
622
623  /*
624   * If another thread is already doing stuff, wait for it.  This can
625   * go to sleep indefinitely.
626   */
627  while (event_thread_id_ != 0) {
628    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
629                               event_thread_id_, threadId);
630    waited = true;
631    event_thread_cond_.Wait(self);
632  }
633
634  if (waited || threadId != 0) {
635    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
636  }
637  if (threadId != 0) {
638    event_thread_id_ = threadId;
639  }
640}
641
642/*
643 * Clear the threadId and signal anybody waiting.
644 */
645void JdwpState::ClearWaitForEventThread() {
646  /*
647   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
648   * function is called by dvmSuspendSelf(), and the transition back
649   * to RUNNING would confuse it.
650   */
651  Thread* self = Thread::Current();
652  MutexLock mu(self, event_thread_lock_);
653
654  CHECK_NE(event_thread_id_, 0U);
655  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", event_thread_id_);
656
657  event_thread_id_ = 0;
658
659  event_thread_cond_.Signal(self);
660}
661
662
663/*
664 * Prep an event.  Allocates storage for the message and leaves space for
665 * the header.
666 */
667static ExpandBuf* eventPrep() {
668  ExpandBuf* pReq = expandBufAlloc();
669  expandBufAddSpace(pReq, kJDWPHeaderLen);
670  return pReq;
671}
672
673/*
674 * Write the header into the buffer and send the packet off to the debugger.
675 *
676 * Takes ownership of "pReq" (currently discards it).
677 */
678void JdwpState::EventFinish(ExpandBuf* pReq) {
679  uint8_t* buf = expandBufGetBuffer(pReq);
680
681  Set4BE(buf, expandBufGetLength(pReq));
682  Set4BE(buf+4, NextRequestSerial());
683  Set1(buf+8, 0);     /* flags */
684  Set1(buf+9, kJdwpEventCommandSet);
685  Set1(buf+10, kJdwpCompositeCommand);
686
687  // Prevents from interleaving commands and events. Otherwise we could end up in sending an event
688  // before sending the reply of the command being processed and would lead to bad synchronization
689  // between the debugger and the debuggee.
690  WaitForProcessingRequest();
691
692  SendRequest(pReq);
693
694  expandBufFree(pReq);
695}
696
697
698/*
699 * Tell the debugger that we have finished initializing.  This is always
700 * sent, even if the debugger hasn't requested it.
701 *
702 * This should be sent "before the main thread is started and before
703 * any application code has been executed".  The thread ID in the message
704 * must be for the main thread.
705 */
706bool JdwpState::PostVMStart() {
707  JdwpSuspendPolicy suspend_policy;
708  ObjectId threadId = Dbg::GetThreadSelfId();
709
710  if (options_->suspend) {
711    suspend_policy = SP_ALL;
712  } else {
713    suspend_policy = SP_NONE;
714  }
715
716  ExpandBuf* pReq = eventPrep();
717  {
718    MutexLock mu(Thread::Current(), event_list_lock_);  // probably don't need this here
719
720    VLOG(jdwp) << "EVENT: " << EK_VM_START;
721    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
722
723    expandBufAdd1(pReq, suspend_policy);
724    expandBufAdd4BE(pReq, 1);
725
726    expandBufAdd1(pReq, EK_VM_START);
727    expandBufAdd4BE(pReq, 0);       /* requestId */
728    expandBufAdd8BE(pReq, threadId);
729  }
730
731  Dbg::ManageDeoptimization();
732
733  /* send request and possibly suspend ourselves */
734  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
735
736  return true;
737}
738
739/*
740 * A location of interest has been reached.  This handles:
741 *   Breakpoint
742 *   SingleStep
743 *   MethodEntry
744 *   MethodExit
745 * These four types must be grouped together in a single response.  The
746 * "eventFlags" indicates the type of event(s) that have happened.
747 *
748 * Valid mods:
749 *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
750 *   LocationOnly (for breakpoint/step only)
751 *   Step (for step only)
752 *
753 * Interesting test cases:
754 *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
755 *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
756 *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
757 *  - Single-step to a line with a breakpoint.  Should get a single
758 *    event message with both events in it.
759 */
760bool JdwpState::PostLocationEvent(const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags,
761                                  const JValue* returnValue) {
762  ModBasket basket;
763  basket.pLoc = pLoc;
764  basket.classId = pLoc->class_id;
765  basket.thisPtr = thisPtr;
766  basket.threadId = Dbg::GetThreadSelfId();
767  basket.className = Dbg::GetClassName(pLoc->class_id);
768
769  /*
770   * On rare occasions we may need to execute interpreted code in the VM
771   * while handling a request from the debugger.  Don't fire breakpoints
772   * while doing so.  (I don't think we currently do this at all, so
773   * this is mostly paranoia.)
774   */
775  if (basket.threadId == debug_thread_id_) {
776    VLOG(jdwp) << "Ignoring location event in JDWP thread";
777    return false;
778  }
779
780  /*
781   * The debugger variable display tab may invoke the interpreter to format
782   * complex objects.  We want to ignore breakpoints and method entry/exit
783   * traps while working on behalf of the debugger.
784   *
785   * If we don't ignore them, the VM will get hung up, because we'll
786   * suspend on a breakpoint while the debugger is still waiting for its
787   * method invocation to complete.
788   */
789  if (InvokeInProgress()) {
790    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
791    return false;
792  }
793
794  int match_count = 0;
795  ExpandBuf* pReq = NULL;
796  JdwpSuspendPolicy suspend_policy = SP_NONE;
797  {
798    MutexLock mu(Thread::Current(), event_list_lock_);
799    JdwpEvent** match_list = AllocMatchList(event_list_size_);
800    if ((eventFlags & Dbg::kBreakpoint) != 0) {
801      FindMatchingEvents(EK_BREAKPOINT, &basket, match_list, &match_count);
802    }
803    if ((eventFlags & Dbg::kSingleStep) != 0) {
804      FindMatchingEvents(EK_SINGLE_STEP, &basket, match_list, &match_count);
805    }
806    if ((eventFlags & Dbg::kMethodEntry) != 0) {
807      FindMatchingEvents(EK_METHOD_ENTRY, &basket, match_list, &match_count);
808    }
809    if ((eventFlags & Dbg::kMethodExit) != 0) {
810      FindMatchingEvents(EK_METHOD_EXIT, &basket, match_list, &match_count);
811      FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, &basket, match_list, &match_count);
812    }
813    if (match_count != 0) {
814      VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
815                 << basket.className << "." << Dbg::GetMethodName(pLoc->method_id)
816                 << StringPrintf(" thread=%#" PRIx64 "  dex_pc=%#" PRIx64 ")",
817                                 basket.threadId, pLoc->dex_pc);
818
819      suspend_policy = scanSuspendPolicy(match_list, match_count);
820      VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
821
822      pReq = eventPrep();
823      expandBufAdd1(pReq, suspend_policy);
824      expandBufAdd4BE(pReq, match_count);
825
826      for (int i = 0; i < match_count; i++) {
827        expandBufAdd1(pReq, match_list[i]->eventKind);
828        expandBufAdd4BE(pReq, match_list[i]->requestId);
829        expandBufAdd8BE(pReq, basket.threadId);
830        expandBufAddLocation(pReq, *pLoc);
831        if (match_list[i]->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
832          Dbg::OutputMethodReturnValue(pLoc->method_id, returnValue, pReq);
833        }
834      }
835    }
836
837    CleanupMatchList(match_list, match_count);
838  }
839
840  Dbg::ManageDeoptimization();
841
842  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
843  return match_count != 0;
844}
845
846/*
847 * A thread is starting or stopping.
848 *
849 * Valid mods:
850 *  Count, ThreadOnly
851 */
852bool JdwpState::PostThreadChange(ObjectId threadId, bool start) {
853  CHECK_EQ(threadId, Dbg::GetThreadSelfId());
854
855  /*
856   * I don't think this can happen.
857   */
858  if (InvokeInProgress()) {
859    LOG(WARNING) << "Not posting thread change during invoke";
860    return false;
861  }
862
863  ModBasket basket;
864  basket.threadId = threadId;
865
866  ExpandBuf* pReq = NULL;
867  JdwpSuspendPolicy suspend_policy = SP_NONE;
868  int match_count = 0;
869  {
870    // Don't allow the list to be updated while we scan it.
871    MutexLock mu(Thread::Current(), event_list_lock_);
872    JdwpEvent** match_list = AllocMatchList(event_list_size_);
873
874    if (start) {
875      FindMatchingEvents(EK_THREAD_START, &basket, match_list, &match_count);
876    } else {
877      FindMatchingEvents(EK_THREAD_DEATH, &basket, match_list, &match_count);
878    }
879
880    if (match_count != 0) {
881      VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
882                 << StringPrintf("thread=%#" PRIx64, basket.threadId) << ")";
883
884      suspend_policy = scanSuspendPolicy(match_list, match_count);
885      VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
886
887      pReq = eventPrep();
888      expandBufAdd1(pReq, suspend_policy);
889      expandBufAdd4BE(pReq, match_count);
890
891      for (int i = 0; i < match_count; i++) {
892        expandBufAdd1(pReq, match_list[i]->eventKind);
893        expandBufAdd4BE(pReq, match_list[i]->requestId);
894        expandBufAdd8BE(pReq, basket.threadId);
895      }
896    }
897
898    CleanupMatchList(match_list, match_count);
899  }
900
901  Dbg::ManageDeoptimization();
902
903  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
904
905  return match_count != 0;
906}
907
908/*
909 * Send a polite "VM is dying" message to the debugger.
910 *
911 * Skips the usual "event token" stuff.
912 */
913bool JdwpState::PostVMDeath() {
914  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
915
916  ExpandBuf* pReq = eventPrep();
917  expandBufAdd1(pReq, SP_NONE);
918  expandBufAdd4BE(pReq, 1);
919
920  expandBufAdd1(pReq, EK_VM_DEATH);
921  expandBufAdd4BE(pReq, 0);
922  EventFinish(pReq);
923  return true;
924}
925
926/*
927 * An exception has been thrown.  It may or may not have been caught.
928 *
929 * Valid mods:
930 *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
931 *    ExceptionOnly, InstanceOnly
932 *
933 * The "exceptionId" has not been added to the GC-visible object registry,
934 * because there's a pretty good chance that we're not going to send it
935 * up the debugger.
936 */
937bool JdwpState::PostException(const JdwpLocation* pThrowLoc,
938                              ObjectId exceptionId, RefTypeId exceptionClassId,
939                              const JdwpLocation* pCatchLoc, ObjectId thisPtr) {
940  ModBasket basket;
941
942  basket.pLoc = pThrowLoc;
943  basket.classId = pThrowLoc->class_id;
944  basket.threadId = Dbg::GetThreadSelfId();
945  basket.className = Dbg::GetClassName(basket.classId);
946  basket.excepClassId = exceptionClassId;
947  basket.caught = (pCatchLoc->class_id != 0);
948  basket.thisPtr = thisPtr;
949
950  /* don't try to post an exception caused by the debugger */
951  if (InvokeInProgress()) {
952    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
953    return false;
954  }
955
956  int match_count = 0;
957  ExpandBuf* pReq = NULL;
958  JdwpSuspendPolicy suspend_policy = SP_NONE;
959  {
960    MutexLock mu(Thread::Current(), event_list_lock_);
961    JdwpEvent** match_list = AllocMatchList(event_list_size_);
962    FindMatchingEvents(EK_EXCEPTION, &basket, match_list, &match_count);
963    if (match_count != 0) {
964      VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total)"
965                 << StringPrintf(" thread=%#" PRIx64, basket.threadId)
966                 << StringPrintf(" exceptId=%#" PRIx64, exceptionId)
967                 << " caught=" << basket.caught << ")"
968                 << "  throw: " << *pThrowLoc;
969      if (pCatchLoc->class_id == 0) {
970        VLOG(jdwp) << "  catch: (not caught)";
971      } else {
972        VLOG(jdwp) << "  catch: " << *pCatchLoc;
973      }
974
975      suspend_policy = scanSuspendPolicy(match_list, match_count);
976      VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
977
978      pReq = eventPrep();
979      expandBufAdd1(pReq, suspend_policy);
980      expandBufAdd4BE(pReq, match_count);
981
982      for (int i = 0; i < match_count; i++) {
983        expandBufAdd1(pReq, match_list[i]->eventKind);
984        expandBufAdd4BE(pReq, match_list[i]->requestId);
985        expandBufAdd8BE(pReq, basket.threadId);
986
987        expandBufAddLocation(pReq, *pThrowLoc);
988        expandBufAdd1(pReq, JT_OBJECT);
989        expandBufAdd8BE(pReq, exceptionId);
990        expandBufAddLocation(pReq, *pCatchLoc);
991      }
992    }
993
994    CleanupMatchList(match_list, match_count);
995  }
996
997  Dbg::ManageDeoptimization();
998
999  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
1000
1001  return match_count != 0;
1002}
1003
1004/*
1005 * Announce that a class has been loaded.
1006 *
1007 * Valid mods:
1008 *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1009 */
1010bool JdwpState::PostClassPrepare(JdwpTypeTag tag, RefTypeId refTypeId, const std::string& signature,
1011                                 int status) {
1012  ModBasket basket;
1013
1014  basket.classId = refTypeId;
1015  basket.threadId = Dbg::GetThreadSelfId();
1016  basket.className = Dbg::GetClassName(basket.classId);
1017
1018  /* suppress class prep caused by debugger */
1019  if (InvokeInProgress()) {
1020    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
1021    return false;
1022  }
1023
1024  ExpandBuf* pReq = NULL;
1025  JdwpSuspendPolicy suspend_policy = SP_NONE;
1026  int match_count = 0;
1027  {
1028    MutexLock mu(Thread::Current(), event_list_lock_);
1029    JdwpEvent** match_list = AllocMatchList(event_list_size_);
1030    FindMatchingEvents(EK_CLASS_PREPARE, &basket, match_list, &match_count);
1031    if (match_count != 0) {
1032      VLOG(jdwp) << "EVENT: " << match_list[0]->eventKind << "(" << match_count << " total) "
1033                 << StringPrintf("thread=%#" PRIx64, basket.threadId) << ") " << signature;
1034
1035      suspend_policy = scanSuspendPolicy(match_list, match_count);
1036      VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1037
1038      if (basket.threadId == debug_thread_id_) {
1039        /*
1040         * JDWP says that, for a class prep in the debugger thread, we
1041         * should set threadId to null and if any threads were supposed
1042         * to be suspended then we suspend all other threads.
1043         */
1044        VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
1045        basket.threadId = 0;
1046        if (suspend_policy == SP_EVENT_THREAD) {
1047          suspend_policy = SP_ALL;
1048        }
1049      }
1050
1051      pReq = eventPrep();
1052      expandBufAdd1(pReq, suspend_policy);
1053      expandBufAdd4BE(pReq, match_count);
1054
1055      for (int i = 0; i < match_count; i++) {
1056        expandBufAdd1(pReq, match_list[i]->eventKind);
1057        expandBufAdd4BE(pReq, match_list[i]->requestId);
1058        expandBufAdd8BE(pReq, basket.threadId);
1059
1060        expandBufAdd1(pReq, tag);
1061        expandBufAdd8BE(pReq, refTypeId);
1062        expandBufAddUtf8String(pReq, signature);
1063        expandBufAdd4BE(pReq, status);
1064      }
1065    }
1066    CleanupMatchList(match_list, match_count);
1067  }
1068
1069  Dbg::ManageDeoptimization();
1070
1071  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
1072
1073  return match_count != 0;
1074}
1075
1076/*
1077 * Send up a chunk of DDM data.
1078 *
1079 * While this takes the form of a JDWP "event", it doesn't interact with
1080 * other debugger traffic, and can't suspend the VM, so we skip all of
1081 * the fun event token gymnastics.
1082 */
1083void JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1084  uint8_t header[kJDWPHeaderLen + 8];
1085  size_t dataLen = 0;
1086
1087  CHECK(iov != NULL);
1088  CHECK_GT(iov_count, 0);
1089  CHECK_LT(iov_count, 10);
1090
1091  /*
1092   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1093   * this by creating a new copy of the vector with space for the header.
1094   */
1095  std::vector<iovec> wrapiov;
1096  wrapiov.push_back(iovec());
1097  for (int i = 0; i < iov_count; i++) {
1098    wrapiov.push_back(iov[i]);
1099    dataLen += iov[i].iov_len;
1100  }
1101
1102  /* form the header (JDWP plus DDMS) */
1103  Set4BE(header, sizeof(header) + dataLen);
1104  Set4BE(header+4, NextRequestSerial());
1105  Set1(header+8, 0);     /* flags */
1106  Set1(header+9, kJDWPDdmCmdSet);
1107  Set1(header+10, kJDWPDdmCmd);
1108  Set4BE(header+11, type);
1109  Set4BE(header+15, dataLen);
1110
1111  wrapiov[0].iov_base = header;
1112  wrapiov[0].iov_len = sizeof(header);
1113
1114  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
1115  // than mutator for lock ordering reasons.
1116  Thread* self = Thread::Current();
1117  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
1118  if (safe_to_release_mutator_lock_over_send) {
1119    for (size_t i = 0; i < kMutatorLock; ++i) {
1120      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) {
1121        safe_to_release_mutator_lock_over_send = false;
1122        break;
1123      }
1124    }
1125  }
1126  if (safe_to_release_mutator_lock_over_send) {
1127    // Change state to waiting to allow GC, ... while we're sending.
1128    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1129    SendBufferedRequest(type, wrapiov);
1130    self->TransitionFromSuspendedToRunnable();
1131  } else {
1132    // Send and possibly block GC...
1133    SendBufferedRequest(type, wrapiov);
1134  }
1135}
1136
1137}  // namespace JDWP
1138
1139}  // namespace art
1140