Home | History | Annotate | Download | only in jdwp
      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  * Send events to the debugger.
     18  */
     19 #include "jdwp/JdwpPriv.h"
     20 #include "jdwp/JdwpConstants.h"
     21 #include "jdwp/JdwpHandler.h"
     22 #include "jdwp/JdwpEvent.h"
     23 #include "jdwp/ExpandBuf.h"
     24 
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <stddef.h>     /* for offsetof() */
     28 #include <unistd.h>
     29 
     30 /*
     31 General notes:
     32 
     33 The event add/remove stuff usually happens from the debugger thread,
     34 in response to requests from the debugger, but can also happen as the
     35 result of an event in an arbitrary thread (e.g. an event with a "count"
     36 mod expires).  It's important to keep the event list locked when processing
     37 events.
     38 
     39 Event posting can happen from any thread.  The JDWP thread will not usually
     40 post anything but VM start/death, but if a JDWP request causes a class
     41 to be loaded, the ClassPrepare event will come from the JDWP thread.
     42 
     43 
     44 We can have serialization issues when we post an event to the debugger.
     45 For example, a thread could send an "I hit a breakpoint and am suspending
     46 myself" message to the debugger.  Before it manages to suspend itself, the
     47 debugger's response ("not interested, resume thread") arrives and is
     48 processed.  We try to resume a thread that hasn't yet suspended.
     49 
     50 This means that, after posting an event to the debugger, we need to wait
     51 for the event thread to suspend itself (and, potentially, all other threads)
     52 before processing any additional requests from the debugger.  While doing
     53 so we need to be aware that multiple threads may be hitting breakpoints
     54 or other events simultaneously, so we either need to wait for all of them
     55 or serialize the events with each other.
     56 
     57 The current mechanism works like this:
     58   Event thread:
     59    - If I'm going to suspend, grab the "I am posting an event" token.  Wait
     60      for it if it's not currently available.
     61    - Post the event to the debugger.
     62    - If appropriate, suspend others and then myself.  As part of suspending
     63      myself, release the "I am posting" token.
     64   JDWP thread:
     65    - When an event arrives, see if somebody is posting an event.  If so,
     66      sleep until we can acquire the "I am posting an event" token.  Release
     67      it immediately and continue processing -- the event we have already
     68      received should not interfere with other events that haven't yet
     69      been posted.
     70 
     71 Some care must be taken to avoid deadlock:
     72 
     73  - thread A and thread B exit near-simultaneously, and post thread-death
     74    events with a "suspend all" clause
     75  - thread A gets the event token, thread B sits and waits for it
     76  - thread A wants to suspend all other threads, but thread B is waiting
     77    for the token and can't be suspended
     78 
     79 So we need to mark thread B in such a way that thread A doesn't wait for it.
     80 
     81 If we just bracket the "grab event token" call with a change to VMWAIT
     82 before sleeping, the switch back to RUNNING state when we get the token
     83 will cause thread B to suspend (remember, thread A's global suspend is
     84 still in force, even after it releases the token).  Suspending while
     85 holding the event token is very bad, because it prevents the JDWP thread
     86 from processing incoming messages.
     87 
     88 We need to change to VMWAIT state at the *start* of posting an event,
     89 and stay there until we either finish posting the event or decide to
     90 put ourselves to sleep.  That way we don't interfere with anyone else and
     91 don't allow anyone else to interfere with us.
     92 */
     93 
     94 
     95 #define kJdwpEventCommandSet    64
     96 #define kJdwpCompositeCommand   100
     97 
     98 /*
     99  * Stuff to compare against when deciding if a mod matches.  Only the
    100  * values for mods valid for the event being evaluated will be filled in.
    101  * The rest will be zeroed.
    102  */
    103 typedef struct ModBasket {
    104     const JdwpLocation* pLoc;           /* LocationOnly */
    105     const char*         className;      /* ClassMatch/ClassExclude */
    106     ObjectId            threadId;       /* ThreadOnly */
    107     RefTypeId           classId;        /* ClassOnly */
    108     RefTypeId           excepClassId;   /* ExceptionOnly */
    109     bool                caught;         /* ExceptionOnly */
    110     FieldId             field;          /* FieldOnly */
    111     ObjectId            thisPtr;        /* InstanceOnly */
    112     /* nothing for StepOnly -- handled differently */
    113 } ModBasket;
    114 
    115 /*
    116  * Get the next "request" serial number.  We use this when sending
    117  * packets to the debugger.
    118  */
    119 u4 dvmJdwpNextRequestSerial(JdwpState* state)
    120 {
    121     u4 result;
    122 
    123     dvmDbgLockMutex(&state->serialLock);
    124     result = state->requestSerial++;
    125     dvmDbgUnlockMutex(&state->serialLock);
    126 
    127     return result;
    128 }
    129 
    130 /*
    131  * Get the next "event" serial number.  We use this in the response to
    132  * message type EventRequest.Set.
    133  */
    134 u4 dvmJdwpNextEventSerial(JdwpState* state)
    135 {
    136     u4 result;
    137 
    138     dvmDbgLockMutex(&state->serialLock);
    139     result = state->eventSerial++;
    140     dvmDbgUnlockMutex(&state->serialLock);
    141 
    142     return result;
    143 }
    144 
    145 /*
    146  * Lock the "event" mutex, which guards the list of registered events.
    147  */
    148 static void lockEventMutex(JdwpState* state)
    149 {
    150     //dvmDbgThreadWaiting();
    151     dvmDbgLockMutex(&state->eventLock);
    152     //dvmDbgThreadRunning();
    153 }
    154 
    155 /*
    156  * Unlock the "event" mutex.
    157  */
    158 static void unlockEventMutex(JdwpState* state)
    159 {
    160     dvmDbgUnlockMutex(&state->eventLock);
    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  */
    170 JdwpError dvmJdwpRegisterEvent(JdwpState* state, JdwpEvent* pEvent)
    171 {
    172     JdwpError err = ERR_NONE;
    173     int i;
    174 
    175     lockEventMutex(state);
    176 
    177     assert(state != NULL);
    178     assert(pEvent != NULL);
    179     assert(pEvent->prev == NULL);
    180     assert(pEvent->next == NULL);
    181 
    182     /*
    183      * If one or more LocationOnly mods are used, register them with
    184      * the interpreter.
    185      */
    186     for (i = 0; i < pEvent->modCount; i++) {
    187         JdwpEventMod* pMod = &pEvent->mods[i];
    188         if (pMod->modKind == MK_LOCATION_ONLY) {
    189             /* should only be for Breakpoint, Step, and Exception */
    190             dvmDbgWatchLocation(&pMod->locationOnly.loc);
    191         }
    192         if (pMod->modKind == MK_STEP) {
    193             /* should only be for EK_SINGLE_STEP; should only be one */
    194             dvmDbgConfigureStep(pMod->step.threadId, pMod->step.size,
    195                 pMod->step.depth);
    196         }
    197     }
    198 
    199     /*
    200      * Add to list.
    201      */
    202     if (state->eventList != NULL) {
    203         pEvent->next = state->eventList;
    204         state->eventList->prev = pEvent;
    205     }
    206     state->eventList = pEvent;
    207     state->numEvents++;
    208 
    209     unlockEventMutex(state);
    210 
    211     return err;
    212 }
    213 
    214 /*
    215  * Remove an event from the list.  This will also remove the event from
    216  * any optimization tables, e.g. breakpoints.
    217  *
    218  * Does not free the JdwpEvent.
    219  *
    220  * Grab the eventLock before calling here.
    221  */
    222 static void unregisterEvent(JdwpState* state, JdwpEvent* pEvent)
    223 {
    224     int i;
    225 
    226     if (pEvent->prev == NULL) {
    227         /* head of the list */
    228         assert(state->eventList == pEvent);
    229 
    230         state->eventList = pEvent->next;
    231     } else {
    232         pEvent->prev->next = pEvent->next;
    233     }
    234 
    235     if (pEvent->next != NULL) {
    236         pEvent->next->prev = pEvent->prev;
    237         pEvent->next = NULL;
    238     }
    239     pEvent->prev = NULL;
    240 
    241     /*
    242      * Unhook us from the interpreter, if necessary.
    243      */
    244     for (i = 0; i < pEvent->modCount; i++) {
    245         JdwpEventMod* pMod = &pEvent->mods[i];
    246         if (pMod->modKind == MK_LOCATION_ONLY) {
    247             /* should only be for Breakpoint, Step, and Exception */
    248             dvmDbgUnwatchLocation(&pMod->locationOnly.loc);
    249         }
    250         if (pMod->modKind == MK_STEP) {
    251             /* should only be for EK_SINGLE_STEP; should only be one */
    252             dvmDbgUnconfigureStep(pMod->step.threadId);
    253         }
    254     }
    255 
    256     state->numEvents--;
    257     assert(state->numEvents != 0 || state->eventList == NULL);
    258 }
    259 
    260 /*
    261  * Remove the event with the given ID from the list.
    262  *
    263  * Failure to find the event isn't really an error, but it is a little
    264  * weird.  (It looks like Eclipse will try to be extra careful and will
    265  * explicitly remove one-off single-step events.)
    266  */
    267 void dvmJdwpUnregisterEventById(JdwpState* state, u4 requestId)
    268 {
    269     JdwpEvent* pEvent;
    270 
    271     lockEventMutex(state);
    272 
    273     pEvent = state->eventList;
    274     while (pEvent != NULL) {
    275         if (pEvent->requestId == requestId) {
    276             unregisterEvent(state, pEvent);
    277             dvmJdwpEventFree(pEvent);
    278             goto done;      /* there can be only one with a given ID */
    279         }
    280 
    281         pEvent = pEvent->next;
    282     }
    283 
    284     //LOGD("Odd: no match when removing event reqId=0x%04x\n", requestId);
    285 
    286 done:
    287     unlockEventMutex(state);
    288 }
    289 
    290 /*
    291  * Remove all entries from the event list.
    292  */
    293 void dvmJdwpUnregisterAll(JdwpState* state)
    294 {
    295     JdwpEvent* pEvent;
    296     JdwpEvent* pNextEvent;
    297 
    298     lockEventMutex(state);
    299 
    300     pEvent = state->eventList;
    301     while (pEvent != NULL) {
    302         pNextEvent = pEvent->next;
    303 
    304         unregisterEvent(state, pEvent);
    305         dvmJdwpEventFree(pEvent);
    306         pEvent = pNextEvent;
    307     }
    308 
    309     state->eventList = NULL;
    310 
    311     unlockEventMutex(state);
    312 }
    313 
    314 
    315 
    316 /*
    317  * Allocate a JdwpEvent struct with enough space to hold the specified
    318  * number of mod records.
    319  */
    320 JdwpEvent* dvmJdwpEventAlloc(int numMods)
    321 {
    322     JdwpEvent* newEvent;
    323     int allocSize = offsetof(JdwpEvent, mods) +
    324                     numMods * sizeof(newEvent->mods[0]);
    325 
    326     newEvent = (JdwpEvent*)malloc(allocSize);
    327     memset(newEvent, 0, allocSize);
    328     return newEvent;
    329 }
    330 
    331 /*
    332  * Free a JdwpEvent.
    333  *
    334  * Do not call this until the event has been removed from the list.
    335  */
    336 void dvmJdwpEventFree(JdwpEvent* pEvent)
    337 {
    338     int i;
    339 
    340     if (pEvent == NULL)
    341         return;
    342 
    343     /* make sure it was removed from the list */
    344     assert(pEvent->prev == NULL);
    345     assert(pEvent->next == NULL);
    346     /* want to assert state->eventList != pEvent */
    347 
    348     /*
    349      * Free any hairy bits in the mods.
    350      */
    351     for (i = 0; i < pEvent->modCount; i++) {
    352         if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
    353             free(pEvent->mods[i].classMatch.classPattern);
    354             pEvent->mods[i].classMatch.classPattern = NULL;
    355         }
    356         if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
    357             free(pEvent->mods[i].classExclude.classPattern);
    358             pEvent->mods[i].classExclude.classPattern = NULL;
    359         }
    360     }
    361 
    362     free(pEvent);
    363 }
    364 
    365 /*
    366  * Allocate storage for matching events.  To keep things simple we
    367  * use an array with enough storage for the entire list.
    368  *
    369  * The state->eventLock should be held before calling.
    370  */
    371 static JdwpEvent** allocMatchList(JdwpState* state)
    372 {
    373     return (JdwpEvent**) malloc(sizeof(JdwpEvent*) * state->numEvents);
    374 }
    375 
    376 /*
    377  * Run through the list and remove any entries with an expired "count" mod
    378  * from the event list, then free the match list.
    379  */
    380 static void cleanupMatchList(JdwpState* state, JdwpEvent** matchList,
    381     int matchCount)
    382 {
    383     JdwpEvent** ppEvent = matchList;
    384 
    385     while (matchCount--) {
    386         JdwpEvent* pEvent = *ppEvent;
    387         int i;
    388 
    389         for (i = 0; i < pEvent->modCount; i++) {
    390             if (pEvent->mods[i].modKind == MK_COUNT &&
    391                 pEvent->mods[i].count.count == 0)
    392             {
    393                 LOGV("##### Removing expired event\n");
    394                 unregisterEvent(state, pEvent);
    395                 dvmJdwpEventFree(pEvent);
    396                 break;
    397             }
    398         }
    399 
    400         ppEvent++;
    401     }
    402 
    403     free(matchList);
    404 }
    405 
    406 /*
    407  * Match a string against a "restricted regular expression", which is just
    408  * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
    409  *
    410  * ("Restricted name globbing" might have been a better term.)
    411  */
    412 static bool patternMatch(const char* pattern, const char* target)
    413 {
    414     int patLen = strlen(pattern);
    415 
    416     if (pattern[0] == '*') {
    417         int targetLen = strlen(target);
    418         patLen--;
    419         // TODO: remove printf when we find a test case to verify this
    420         LOGE(">>> comparing '%s' to '%s'\n",
    421             pattern+1, target + (targetLen-patLen));
    422 
    423         if (targetLen < patLen)
    424             return false;
    425         return strcmp(pattern+1, target + (targetLen-patLen)) == 0;
    426     } else if (pattern[patLen-1] == '*') {
    427         return strncmp(pattern, target, patLen-1) == 0;
    428     } else {
    429         return strcmp(pattern, target) == 0;
    430     }
    431 }
    432 
    433 /*
    434  * See if two locations are equal.
    435  *
    436  * It's tempting to do a bitwise compare ("struct ==" or memcmp), but if
    437  * the storage wasn't zeroed out there could be undefined values in the
    438  * padding.  Besides, the odds of "idx" being equal while the others aren't
    439  * is very small, so this is usually just a simple integer comparison.
    440  */
    441 static inline bool locationMatch(const JdwpLocation* pLoc1,
    442     const JdwpLocation* pLoc2)
    443 {
    444     return pLoc1->idx == pLoc2->idx &&
    445            pLoc1->methodId == pLoc2->methodId &&
    446            pLoc1->classId == pLoc2->classId &&
    447            pLoc1->typeTag == pLoc2->typeTag;
    448 }
    449 
    450 /*
    451  * See if the event's mods match up with the contents of "basket".
    452  *
    453  * If we find a Count mod before rejecting an event, we decrement it.  We
    454  * need to do this even if later mods cause us to ignore the event.
    455  */
    456 static bool modsMatch(JdwpState* state, JdwpEvent* pEvent, ModBasket* basket)
    457 {
    458     JdwpEventMod* pMod = pEvent->mods;
    459     int i;
    460 
    461     for (i = pEvent->modCount; i > 0; i--, pMod++) {
    462         switch (pMod->modKind) {
    463         case MK_COUNT:
    464             assert(pMod->count.count > 0);
    465             pMod->count.count--;
    466             break;
    467         case MK_CONDITIONAL:
    468             assert(false);  // should not be getting these
    469             break;
    470         case MK_THREAD_ONLY:
    471             if (pMod->threadOnly.threadId != basket->threadId)
    472                 return false;
    473             break;
    474         case MK_CLASS_ONLY:
    475             if (!dvmDbgMatchType(basket->classId,
    476                     pMod->classOnly.referenceTypeId))
    477                 return false;
    478             break;
    479         case MK_CLASS_MATCH:
    480             if (!patternMatch(pMod->classMatch.classPattern,
    481                     basket->className))
    482                 return false;
    483             break;
    484         case MK_CLASS_EXCLUDE:
    485             if (patternMatch(pMod->classMatch.classPattern,
    486                     basket->className))
    487                 return false;
    488             break;
    489         case MK_LOCATION_ONLY:
    490             if (!locationMatch(&pMod->locationOnly.loc, basket->pLoc))
    491                 return false;
    492             break;
    493         case MK_EXCEPTION_ONLY:
    494             if (pMod->exceptionOnly.refTypeId != 0 &&
    495                 !dvmDbgMatchType(basket->excepClassId,
    496                                  pMod->exceptionOnly.refTypeId))
    497                 return false;
    498             if ((basket->caught && !pMod->exceptionOnly.caught) ||
    499                 (!basket->caught && !pMod->exceptionOnly.uncaught))
    500                 return false;
    501             break;
    502         case MK_FIELD_ONLY:
    503             // TODO
    504             break;
    505         case MK_STEP:
    506             if (pMod->step.threadId != basket->threadId)
    507                 return false;
    508             break;
    509         case MK_INSTANCE_ONLY:
    510             if (pMod->instanceOnly.objectId != basket->thisPtr)
    511                 return false;
    512             break;
    513         default:
    514             LOGE("unhandled mod kind %d\n", pMod->modKind);
    515             assert(false);
    516             break;
    517         }
    518     }
    519 
    520     return true;
    521 }
    522 
    523 /*
    524  * Find all events of type "eventKind" with mods that match up with the
    525  * rest of the arguments.
    526  *
    527  * Found events are appended to "matchList", and "*pMatchCount" is advanced,
    528  * so this may be called multiple times for grouped events.
    529  *
    530  * DO NOT call this multiple times for the same eventKind, as Count mods are
    531  * decremented during the scan.
    532  */
    533 static void findMatchingEvents(JdwpState* state, enum JdwpEventKind eventKind,
    534     ModBasket* basket, JdwpEvent** matchList, int* pMatchCount)
    535 {
    536     JdwpEvent* pEvent;
    537 
    538     /* start after the existing entries */
    539     matchList += *pMatchCount;
    540 
    541     pEvent = state->eventList;
    542     while (pEvent != NULL) {
    543         if (pEvent->eventKind == eventKind && modsMatch(state, pEvent, basket))
    544         {
    545             *matchList++ = pEvent;
    546             (*pMatchCount)++;
    547         }
    548 
    549         pEvent = pEvent->next;
    550     }
    551 }
    552 
    553 /*
    554  * Scan through the list of matches and determine the most severe
    555  * suspension policy.
    556  */
    557 static enum JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** matchList,
    558     int matchCount)
    559 {
    560     enum JdwpSuspendPolicy policy = SP_NONE;
    561 
    562     while (matchCount--) {
    563         if ((*matchList)->suspendPolicy > policy)
    564             policy = (*matchList)->suspendPolicy;
    565         matchList++;
    566     }
    567 
    568     return policy;
    569 }
    570 
    571 /*
    572  * Three possibilities:
    573  *  SP_NONE - do nothing
    574  *  SP_EVENT_THREAD - suspend ourselves
    575  *  SP_ALL - suspend everybody except JDWP support thread
    576  */
    577 static void suspendByPolicy(JdwpState* state,
    578     enum JdwpSuspendPolicy suspendPolicy)
    579 {
    580     if (suspendPolicy == SP_NONE)
    581         return;
    582 
    583     if (suspendPolicy == SP_ALL) {
    584         dvmDbgSuspendVM(true);
    585     } else {
    586         assert(suspendPolicy == SP_EVENT_THREAD);
    587     }
    588 
    589     /* this is rare but possible -- see CLASS_PREPARE handling */
    590     if (dvmDbgGetThreadSelfId() == state->debugThreadId) {
    591         LOGI("NOTE: suspendByPolicy not suspending JDWP thread\n");
    592         return;
    593     }
    594 
    595     DebugInvokeReq* pReq = dvmDbgGetInvokeReq();
    596     while (true) {
    597         pReq->ready = true;
    598         dvmDbgSuspendSelf();
    599         pReq->ready = false;
    600 
    601         /*
    602          * The JDWP thread has told us (and possibly all other threads) to
    603          * resume.  See if it has left anything in our DebugInvokeReq mailbox.
    604          */
    605         if (!pReq->invokeNeeded) {
    606             /*LOGD("suspendByPolicy: no invoke needed\n");*/
    607             break;
    608         }
    609 
    610         /* grab this before posting/suspending again */
    611         dvmJdwpSetWaitForEventThread(state, dvmDbgGetThreadSelfId());
    612 
    613         /* leave pReq->invokeNeeded raised so we can check reentrancy */
    614         LOGV("invoking method...\n");
    615         dvmDbgExecuteMethod(pReq);
    616 
    617         pReq->err = ERR_NONE;
    618 
    619         /* clear this before signaling */
    620         pReq->invokeNeeded = false;
    621 
    622         LOGV("invoke complete, signaling and self-suspending\n");
    623         dvmDbgLockMutex(&pReq->lock);
    624         dvmDbgCondSignal(&pReq->cv);
    625         dvmDbgUnlockMutex(&pReq->lock);
    626     }
    627 }
    628 
    629 /*
    630  * Determine if there is a method invocation in progress in the current
    631  * thread.
    632  *
    633  * We look at the "invokeNeeded" flag in the per-thread DebugInvokeReq
    634  * state.  If set, we're in the process of invoking a method.
    635  */
    636 static bool invokeInProgress(JdwpState* state)
    637 {
    638     DebugInvokeReq* pReq = dvmDbgGetInvokeReq();
    639     return pReq->invokeNeeded;
    640 }
    641 
    642 /*
    643  * We need the JDWP thread to hold off on doing stuff while we post an
    644  * event and then suspend ourselves.
    645  *
    646  * Call this with a threadId of zero if you just want to wait for the
    647  * current thread operation to complete.
    648  *
    649  * This could go to sleep waiting for another thread, so it's important
    650  * that the thread be marked as VMWAIT before calling here.
    651  */
    652 void dvmJdwpSetWaitForEventThread(JdwpState* state, ObjectId threadId)
    653 {
    654     bool waited = false;
    655 
    656     /* this is held for very brief periods; contention is unlikely */
    657     dvmDbgLockMutex(&state->eventThreadLock);
    658 
    659     /*
    660      * If another thread is already doing stuff, wait for it.  This can
    661      * go to sleep indefinitely.
    662      */
    663     while (state->eventThreadId != 0) {
    664         LOGV("event in progress (0x%llx), 0x%llx sleeping\n",
    665             state->eventThreadId, threadId);
    666         waited = true;
    667         dvmDbgCondWait(&state->eventThreadCond, &state->eventThreadLock);
    668     }
    669 
    670     if (waited || threadId != 0)
    671         LOGV("event token grabbed (0x%llx)\n", threadId);
    672     if (threadId != 0)
    673         state->eventThreadId = threadId;
    674 
    675     dvmDbgUnlockMutex(&state->eventThreadLock);
    676 }
    677 
    678 /*
    679  * Clear the threadId and signal anybody waiting.
    680  */
    681 void dvmJdwpClearWaitForEventThread(JdwpState* state)
    682 {
    683     /*
    684      * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
    685      * function is called by dvmSuspendSelf(), and the transition back
    686      * to RUNNING would confuse it.
    687      */
    688     dvmDbgLockMutex(&state->eventThreadLock);
    689 
    690     assert(state->eventThreadId != 0);
    691     LOGV("cleared event token (0x%llx)\n", state->eventThreadId);
    692 
    693     state->eventThreadId = 0;
    694 
    695     dvmDbgCondSignal(&state->eventThreadCond);
    696 
    697     dvmDbgUnlockMutex(&state->eventThreadLock);
    698 }
    699 
    700 
    701 /*
    702  * Prep an event.  Allocates storage for the message and leaves space for
    703  * the header.
    704  */
    705 static ExpandBuf* eventPrep(void)
    706 {
    707     ExpandBuf* pReq;
    708 
    709     pReq = expandBufAlloc();
    710     expandBufAddSpace(pReq, kJDWPHeaderLen);
    711 
    712     return pReq;
    713 }
    714 
    715 /*
    716  * Write the header into the buffer and send the packet off to the debugger.
    717  *
    718  * Takes ownership of "pReq" (currently discards it).
    719  */
    720 static void eventFinish(JdwpState* state, ExpandBuf* pReq)
    721 {
    722     u1* buf = expandBufGetBuffer(pReq);
    723 
    724     set4BE(buf, expandBufGetLength(pReq));
    725     set4BE(buf+4, dvmJdwpNextRequestSerial(state));
    726     set1(buf+8, 0);     /* flags */
    727     set1(buf+9, kJdwpEventCommandSet);
    728     set1(buf+10, kJdwpCompositeCommand);
    729 
    730     dvmJdwpSendRequest(state, 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  */
    744 bool dvmJdwpPostVMStart(JdwpState* state, bool suspend)
    745 {
    746     enum JdwpSuspendPolicy suspendPolicy;
    747     ObjectId threadId = dvmDbgGetThreadSelfId();
    748 
    749     if (suspend)
    750         suspendPolicy = SP_ALL;
    751     else
    752         suspendPolicy = SP_NONE;
    753 
    754     /* probably don't need this here */
    755     lockEventMutex(state);
    756 
    757     ExpandBuf* pReq = NULL;
    758     if (true) {
    759         LOGV("EVENT: %s\n", dvmJdwpEventKindStr(EK_VM_START));
    760         LOGV("  suspendPolicy=%s\n", dvmJdwpSuspendPolicyStr(suspendPolicy));
    761 
    762         pReq = eventPrep();
    763         expandBufAdd1(pReq, suspendPolicy);
    764         expandBufAdd4BE(pReq, 1);
    765 
    766         expandBufAdd1(pReq, EK_VM_START);
    767         expandBufAdd4BE(pReq, 0);       /* requestId */
    768         expandBufAdd8BE(pReq, threadId);
    769     }
    770 
    771     unlockEventMutex(state);
    772 
    773     /* send request and possibly suspend ourselves */
    774     if (pReq != NULL) {
    775         int oldStatus = dvmDbgThreadWaiting();
    776         if (suspendPolicy != SP_NONE)
    777             dvmJdwpSetWaitForEventThread(state, threadId);
    778 
    779         eventFinish(state, pReq);
    780 
    781         suspendByPolicy(state, suspendPolicy);
    782         dvmDbgThreadContinuing(oldStatus);
    783     }
    784 
    785     return true;
    786 }
    787 
    788 /*
    789  * A location of interest has been reached.  This handles:
    790  *   Breakpoint
    791  *   SingleStep
    792  *   MethodEntry
    793  *   MethodExit
    794  * These four types must be grouped together in a single response.  The
    795  * "eventFlags" indicates the type of event(s) that have happened.
    796  *
    797  * Valid mods:
    798  *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
    799  *   LocationOnly (for breakpoint/step only)
    800  *   Step (for step only)
    801  *
    802  * Interesting test cases:
    803  *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
    804  *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
    805  *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
    806  *  - Single-step to a line with a breakpoint.  Should get a single
    807  *    event message with both events in it.
    808  */
    809 bool dvmJdwpPostLocationEvent(JdwpState* state, const JdwpLocation* pLoc,
    810     ObjectId thisPtr, int eventFlags)
    811 {
    812     enum JdwpSuspendPolicy suspendPolicy = SP_NONE;
    813     ModBasket basket;
    814     JdwpEvent** matchList;
    815     int matchCount;
    816     char* nameAlloc = NULL;
    817 
    818     memset(&basket, 0, sizeof(basket));
    819     basket.pLoc = pLoc;
    820     basket.classId = pLoc->classId;
    821     basket.thisPtr = thisPtr;
    822     basket.threadId = dvmDbgGetThreadSelfId();
    823     basket.className = nameAlloc =
    824         dvmDescriptorToName(dvmDbgGetClassDescriptor(pLoc->classId));
    825 
    826     /*
    827      * On rare occasions we may need to execute interpreted code in the VM
    828      * while handling a request from the debugger.  Don't fire breakpoints
    829      * while doing so.  (I don't think we currently do this at all, so
    830      * this is mostly paranoia.)
    831      */
    832     if (basket.threadId == state->debugThreadId) {
    833         LOGV("Ignoring location event in JDWP thread\n");
    834         free(nameAlloc);
    835         return false;
    836     }
    837 
    838     /*
    839      * The debugger variable display tab may invoke the interpreter to format
    840      * complex objects.  We want to ignore breakpoints and method entry/exit
    841      * traps while working on behalf of the debugger.
    842      *
    843      * If we don't ignore them, the VM will get hung up, because we'll
    844      * suspend on a breakpoint while the debugger is still waiting for its
    845      * method invocation to complete.
    846      */
    847     if (invokeInProgress(state)) {
    848         LOGV("Not checking breakpoints during invoke (%s)\n", basket.className);
    849         free(nameAlloc);
    850         return false;
    851     }
    852 
    853     /* don't allow the list to be updated while we scan it */
    854     lockEventMutex(state);
    855 
    856     matchList = allocMatchList(state);
    857     matchCount = 0;
    858 
    859     if ((eventFlags & DBG_BREAKPOINT) != 0)
    860         findMatchingEvents(state, EK_BREAKPOINT, &basket, matchList,
    861             &matchCount);
    862     if ((eventFlags & DBG_SINGLE_STEP) != 0)
    863         findMatchingEvents(state, EK_SINGLE_STEP, &basket, matchList,
    864             &matchCount);
    865     if ((eventFlags & DBG_METHOD_ENTRY) != 0)
    866         findMatchingEvents(state, EK_METHOD_ENTRY, &basket, matchList,
    867             &matchCount);
    868     if ((eventFlags & DBG_METHOD_EXIT) != 0)
    869         findMatchingEvents(state, EK_METHOD_EXIT, &basket, matchList,
    870             &matchCount);
    871 
    872     ExpandBuf* pReq = NULL;
    873     if (matchCount != 0) {
    874         int i;
    875 
    876         LOGV("EVENT: %s(%d total) %s.%s thread=%llx code=%llx)\n",
    877             dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount,
    878             basket.className,
    879             dvmDbgGetMethodName(pLoc->classId, pLoc->methodId),
    880             basket.threadId, pLoc->idx);
    881 
    882         suspendPolicy = scanSuspendPolicy(matchList, matchCount);
    883         LOGV("  suspendPolicy=%s\n",
    884             dvmJdwpSuspendPolicyStr(suspendPolicy));
    885 
    886         pReq = eventPrep();
    887         expandBufAdd1(pReq, suspendPolicy);
    888         expandBufAdd4BE(pReq, matchCount);
    889 
    890         for (i = 0; i < matchCount; i++) {
    891             expandBufAdd1(pReq, matchList[i]->eventKind);
    892             expandBufAdd4BE(pReq, matchList[i]->requestId);
    893             expandBufAdd8BE(pReq, basket.threadId);
    894             dvmJdwpAddLocation(pReq, pLoc);
    895         }
    896     }
    897 
    898     cleanupMatchList(state, matchList, matchCount);
    899     unlockEventMutex(state);
    900 
    901     /* send request and possibly suspend ourselves */
    902     if (pReq != NULL) {
    903         int oldStatus = dvmDbgThreadWaiting();
    904         if (suspendPolicy != SP_NONE)
    905             dvmJdwpSetWaitForEventThread(state, basket.threadId);
    906 
    907         eventFinish(state, pReq);
    908 
    909         suspendByPolicy(state, suspendPolicy);
    910         dvmDbgThreadContinuing(oldStatus);
    911     }
    912 
    913     free(nameAlloc);
    914     return matchCount != 0;
    915 }
    916 
    917 /*
    918  * A thread is starting or stopping.
    919  *
    920  * Valid mods:
    921  *  Count, ThreadOnly
    922  */
    923 bool dvmJdwpPostThreadChange(JdwpState* state, ObjectId threadId, bool start)
    924 {
    925     enum JdwpSuspendPolicy suspendPolicy = SP_NONE;
    926     ModBasket basket;
    927     JdwpEvent** matchList;
    928     int matchCount;
    929 
    930     assert(threadId = dvmDbgGetThreadSelfId());
    931 
    932     /*
    933      * I don't think this can happen.
    934      */
    935     if (invokeInProgress(state)) {
    936         LOGW("Not posting thread change during invoke\n");
    937         return false;
    938     }
    939 
    940     memset(&basket, 0, sizeof(basket));
    941     basket.threadId = threadId;
    942 
    943     /* don't allow the list to be updated while we scan it */
    944     lockEventMutex(state);
    945 
    946     matchList = allocMatchList(state);
    947     matchCount = 0;
    948 
    949     if (start)
    950         findMatchingEvents(state, EK_THREAD_START, &basket, matchList,
    951             &matchCount);
    952     else
    953         findMatchingEvents(state, EK_THREAD_DEATH, &basket, matchList,
    954             &matchCount);
    955 
    956     ExpandBuf* pReq = NULL;
    957     if (matchCount != 0) {
    958         int i;
    959 
    960         LOGV("EVENT: %s(%d total) thread=%llx)\n",
    961             dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount,
    962             basket.threadId);
    963 
    964         suspendPolicy = scanSuspendPolicy(matchList, matchCount);
    965         LOGV("  suspendPolicy=%s\n",
    966             dvmJdwpSuspendPolicyStr(suspendPolicy));
    967 
    968         pReq = eventPrep();
    969         expandBufAdd1(pReq, suspendPolicy);
    970         expandBufAdd4BE(pReq, matchCount);
    971 
    972         for (i = 0; i < matchCount; i++) {
    973             expandBufAdd1(pReq, matchList[i]->eventKind);
    974             expandBufAdd4BE(pReq, matchList[i]->requestId);
    975             expandBufAdd8BE(pReq, basket.threadId);
    976         }
    977 
    978     }
    979 
    980     cleanupMatchList(state, matchList, matchCount);
    981     unlockEventMutex(state);
    982 
    983     /* send request and possibly suspend ourselves */
    984     if (pReq != NULL) {
    985         int oldStatus = dvmDbgThreadWaiting();
    986         if (suspendPolicy != SP_NONE)
    987             dvmJdwpSetWaitForEventThread(state, basket.threadId);
    988 
    989         eventFinish(state, pReq);
    990 
    991         suspendByPolicy(state, suspendPolicy);
    992         dvmDbgThreadContinuing(oldStatus);
    993     }
    994 
    995     return matchCount != 0;
    996 }
    997 
    998 /*
    999  * Send a polite "VM is dying" message to the debugger.
   1000  *
   1001  * Skips the usual "event token" stuff.
   1002  */
   1003 bool dvmJdwpPostVMDeath(JdwpState* state)
   1004 {
   1005     ExpandBuf* pReq;
   1006 
   1007     LOGV("EVENT: %s\n", dvmJdwpEventKindStr(EK_VM_DEATH));
   1008 
   1009     pReq = eventPrep();
   1010     expandBufAdd1(pReq, SP_NONE);
   1011     expandBufAdd4BE(pReq, 1);
   1012 
   1013     expandBufAdd1(pReq, EK_VM_DEATH);
   1014     expandBufAdd4BE(pReq, 0);
   1015     eventFinish(state, pReq);
   1016     return true;
   1017 }
   1018 
   1019 
   1020 /*
   1021  * An exception has been thrown.  It may or may not have been caught.
   1022  *
   1023  * Valid mods:
   1024  *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
   1025  *    ExceptionOnly, InstanceOnly
   1026  *
   1027  * The "exceptionId" has not been added to the GC-visible object registry,
   1028  * because there's a pretty good chance that we're not going to send it
   1029  * up the debugger.
   1030  */
   1031 bool dvmJdwpPostException(JdwpState* state, const JdwpLocation* pThrowLoc,
   1032     ObjectId exceptionId, RefTypeId exceptionClassId,
   1033     const JdwpLocation* pCatchLoc, ObjectId thisPtr)
   1034 {
   1035     enum JdwpSuspendPolicy suspendPolicy = SP_NONE;
   1036     ModBasket basket;
   1037     JdwpEvent** matchList;
   1038     int matchCount;
   1039     char* nameAlloc = NULL;
   1040 
   1041     memset(&basket, 0, sizeof(basket));
   1042     basket.pLoc = pThrowLoc;
   1043     basket.classId = pThrowLoc->classId;
   1044     basket.threadId = dvmDbgGetThreadSelfId();
   1045     basket.className = nameAlloc =
   1046         dvmDescriptorToName(dvmDbgGetClassDescriptor(basket.classId));
   1047     basket.excepClassId = exceptionClassId;
   1048     basket.caught = (pCatchLoc->classId != 0);
   1049     basket.thisPtr = thisPtr;
   1050 
   1051     /* don't try to post an exception caused by the debugger */
   1052     if (invokeInProgress(state)) {
   1053         LOGV("Not posting exception hit during invoke (%s)\n",basket.className);
   1054         free(nameAlloc);
   1055         return false;
   1056     }
   1057 
   1058     /* don't allow the list to be updated while we scan it */
   1059     lockEventMutex(state);
   1060 
   1061     matchList = allocMatchList(state);
   1062     matchCount = 0;
   1063 
   1064     findMatchingEvents(state, EK_EXCEPTION, &basket, matchList, &matchCount);
   1065 
   1066     ExpandBuf* pReq = NULL;
   1067     if (matchCount != 0) {
   1068         int i;
   1069 
   1070         LOGV("EVENT: %s(%d total) thread=%llx exceptId=%llx caught=%d)\n",
   1071             dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount,
   1072             basket.threadId, exceptionId, basket.caught);
   1073         LOGV("  throw: %d %llx %x %lld (%s.%s)\n", pThrowLoc->typeTag,
   1074             pThrowLoc->classId, pThrowLoc->methodId, pThrowLoc->idx,
   1075             dvmDbgGetClassDescriptor(pThrowLoc->classId),
   1076             dvmDbgGetMethodName(pThrowLoc->classId, pThrowLoc->methodId));
   1077         if (pCatchLoc->classId == 0) {
   1078             LOGV("  catch: (not caught)\n");
   1079         } else {
   1080             LOGV("  catch: %d %llx %x %lld (%s.%s)\n", pCatchLoc->typeTag,
   1081                 pCatchLoc->classId, pCatchLoc->methodId, pCatchLoc->idx,
   1082                 dvmDbgGetClassDescriptor(pCatchLoc->classId),
   1083                 dvmDbgGetMethodName(pCatchLoc->classId, pCatchLoc->methodId));
   1084         }
   1085 
   1086         suspendPolicy = scanSuspendPolicy(matchList, matchCount);
   1087         LOGV("  suspendPolicy=%s\n",
   1088             dvmJdwpSuspendPolicyStr(suspendPolicy));
   1089 
   1090         pReq = eventPrep();
   1091         expandBufAdd1(pReq, suspendPolicy);
   1092         expandBufAdd4BE(pReq, matchCount);
   1093 
   1094         for (i = 0; i < matchCount; i++) {
   1095             expandBufAdd1(pReq, matchList[i]->eventKind);
   1096             expandBufAdd4BE(pReq, matchList[i]->requestId);
   1097             expandBufAdd8BE(pReq, basket.threadId);
   1098 
   1099             dvmJdwpAddLocation(pReq, pThrowLoc);
   1100             expandBufAdd1(pReq, JT_OBJECT);
   1101             expandBufAdd8BE(pReq, exceptionId);
   1102             dvmJdwpAddLocation(pReq, pCatchLoc);
   1103         }
   1104 
   1105         /* don't let the GC discard it */
   1106         dvmDbgRegisterObjectId(exceptionId);
   1107     }
   1108 
   1109     cleanupMatchList(state, matchList, matchCount);
   1110     unlockEventMutex(state);
   1111 
   1112     /* send request and possibly suspend ourselves */
   1113     if (pReq != NULL) {
   1114         int oldStatus = dvmDbgThreadWaiting();
   1115         if (suspendPolicy != SP_NONE)
   1116             dvmJdwpSetWaitForEventThread(state, basket.threadId);
   1117 
   1118         eventFinish(state, pReq);
   1119 
   1120         suspendByPolicy(state, suspendPolicy);
   1121         dvmDbgThreadContinuing(oldStatus);
   1122     }
   1123 
   1124     free(nameAlloc);
   1125     return matchCount != 0;
   1126 }
   1127 
   1128 /*
   1129  * Announce that a class has been loaded.
   1130  *
   1131  * Valid mods:
   1132  *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
   1133  */
   1134 bool dvmJdwpPostClassPrepare(JdwpState* state, int tag, RefTypeId refTypeId,
   1135     const char* signature, int status)
   1136 {
   1137     enum JdwpSuspendPolicy suspendPolicy = SP_NONE;
   1138     ModBasket basket;
   1139     JdwpEvent** matchList;
   1140     int matchCount;
   1141     char* nameAlloc = NULL;
   1142 
   1143     memset(&basket, 0, sizeof(basket));
   1144     basket.classId = refTypeId;
   1145     basket.threadId = dvmDbgGetThreadSelfId();
   1146     basket.className = nameAlloc =
   1147         dvmDescriptorToName(dvmDbgGetClassDescriptor(basket.classId));
   1148 
   1149     /* suppress class prep caused by debugger */
   1150     if (invokeInProgress(state)) {
   1151         LOGV("Not posting class prep caused by invoke (%s)\n",basket.className);
   1152         free(nameAlloc);
   1153         return false;
   1154     }
   1155 
   1156     /* don't allow the list to be updated while we scan it */
   1157     lockEventMutex(state);
   1158 
   1159     matchList = allocMatchList(state);
   1160     matchCount = 0;
   1161 
   1162     findMatchingEvents(state, EK_CLASS_PREPARE, &basket, matchList,
   1163         &matchCount);
   1164 
   1165     ExpandBuf* pReq = NULL;
   1166     if (matchCount != 0) {
   1167         int i;
   1168 
   1169         LOGV("EVENT: %s(%d total) thread=%llx)\n",
   1170             dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount,
   1171             basket.threadId);
   1172 
   1173         suspendPolicy = scanSuspendPolicy(matchList, matchCount);
   1174         LOGV("  suspendPolicy=%s\n",
   1175             dvmJdwpSuspendPolicyStr(suspendPolicy));
   1176 
   1177         if (basket.threadId == state->debugThreadId) {
   1178             /*
   1179              * JDWP says that, for a class prep in the debugger thread, we
   1180              * should set threadId to null and if any threads were supposed
   1181              * to be suspended then we suspend all other threads.
   1182              */
   1183             LOGV("  NOTE: class prepare in debugger thread!\n");
   1184             basket.threadId = 0;
   1185             if (suspendPolicy == SP_EVENT_THREAD)
   1186                 suspendPolicy = SP_ALL;
   1187         }
   1188 
   1189         pReq = eventPrep();
   1190         expandBufAdd1(pReq, suspendPolicy);
   1191         expandBufAdd4BE(pReq, matchCount);
   1192 
   1193         for (i = 0; i < matchCount; i++) {
   1194             expandBufAdd1(pReq, matchList[i]->eventKind);
   1195             expandBufAdd4BE(pReq, matchList[i]->requestId);
   1196             expandBufAdd8BE(pReq, basket.threadId);
   1197 
   1198             expandBufAdd1(pReq, tag);
   1199             expandBufAdd8BE(pReq, refTypeId);
   1200             expandBufAddUtf8String(pReq, (const u1*) signature);
   1201             expandBufAdd4BE(pReq, status);
   1202         }
   1203     }
   1204 
   1205     cleanupMatchList(state, matchList, matchCount);
   1206 
   1207     unlockEventMutex(state);
   1208 
   1209     /* send request and possibly suspend ourselves */
   1210     if (pReq != NULL) {
   1211         int oldStatus = dvmDbgThreadWaiting();
   1212         if (suspendPolicy != SP_NONE)
   1213             dvmJdwpSetWaitForEventThread(state, basket.threadId);
   1214 
   1215         eventFinish(state, pReq);
   1216 
   1217         suspendByPolicy(state, suspendPolicy);
   1218         dvmDbgThreadContinuing(oldStatus);
   1219     }
   1220 
   1221     free(nameAlloc);
   1222     return matchCount != 0;
   1223 }
   1224 
   1225 /*
   1226  * Unload a class.
   1227  *
   1228  * Valid mods:
   1229  *  Count, ClassMatch, ClassExclude
   1230  */
   1231 bool dvmJdwpPostClassUnload(JdwpState* state, RefTypeId refTypeId)
   1232 {
   1233     assert(false);      // TODO
   1234     return false;
   1235 }
   1236 
   1237 /*
   1238  * Get or set a field.
   1239  *
   1240  * Valid mods:
   1241  *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, FieldOnly,
   1242  *    InstanceOnly
   1243  */
   1244 bool dvmJdwpPostFieldAccess(JdwpState* state, int STUFF, ObjectId thisPtr,
   1245     bool modified)
   1246 {
   1247     assert(false);      // TODO
   1248     return false;
   1249 }
   1250 
   1251 /*
   1252  * Send up a chunk of DDM data.
   1253  *
   1254  * While this takes the form of a JDWP "event", it doesn't interact with
   1255  * other debugger traffic, and can't suspend the VM, so we skip all of
   1256  * the fun event token gymnastics.
   1257  */
   1258 void dvmJdwpDdmSendChunkV(JdwpState* state, int type, const struct iovec* iov,
   1259     int iovcnt)
   1260 {
   1261     u1 header[kJDWPHeaderLen + 8];
   1262     size_t dataLen = 0;
   1263     int i;
   1264 
   1265     assert(iov != NULL);
   1266     assert(iovcnt > 0 && iovcnt < 10);
   1267 
   1268     /*
   1269      * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
   1270      * this by creating a new copy of the vector with space for the header.
   1271      */
   1272     struct iovec wrapiov[iovcnt+1];
   1273     for (i = 0; i < iovcnt; i++) {
   1274         wrapiov[i+1].iov_base = iov[i].iov_base;
   1275         wrapiov[i+1].iov_len = iov[i].iov_len;
   1276         dataLen += iov[i].iov_len;
   1277     }
   1278 
   1279     /* form the header (JDWP plus DDMS) */
   1280     set4BE(header, sizeof(header) + dataLen);
   1281     set4BE(header+4, dvmJdwpNextRequestSerial(state));
   1282     set1(header+8, 0);     /* flags */
   1283     set1(header+9, kJDWPDdmCmdSet);
   1284     set1(header+10, kJDWPDdmCmd);
   1285     set4BE(header+11, type);
   1286     set4BE(header+15, dataLen);
   1287 
   1288     wrapiov[0].iov_base = header;
   1289     wrapiov[0].iov_len = sizeof(header);
   1290 
   1291     dvmJdwpSendBufferedRequest(state, wrapiov, iovcnt+1);
   1292 }
   1293