Home | History | Annotate | Download | only in back
      1 /*
      2  * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 #include "util.h"
     27 #include "eventHandler.h"
     28 #include "threadControl.h"
     29 #include "commonRef.h"
     30 #include "eventHelper.h"
     31 #include "stepControl.h"
     32 #include "invoker.h"
     33 #include "bag.h"
     34 
     35 #define HANDLING_EVENT(node) ((node)->current_ei != 0)
     36 
     37 /*
     38  * Collection of info for properly handling co-located events.
     39  * If the ei field is non-zero, then one of the possible
     40  * co-located events has been posted and the other fields describe
     41  * the event's location.
     42  */
     43 typedef struct CoLocatedEventInfo_ {
     44     EventIndex ei;
     45     jclass    clazz;
     46     jmethodID method;
     47     jlocation location;
     48 } CoLocatedEventInfo;
     49 
     50 /**
     51  * The main data structure in threadControl is the ThreadNode.
     52  * This is a per-thread structure that is allocated on the
     53  * first event that occurs in a thread. It is freed after the
     54  * thread's thread end event has completed processing. The
     55  * structure contains state information on its thread including
     56  * suspend counts. It also acts as a repository for other
     57  * per-thread state such as the current method invocation or
     58  * current step.
     59  *
     60  * suspendCount is the number of outstanding suspends
     61  * from the debugger. suspends from the app itself are
     62  * not included in this count.
     63  */
     64 typedef struct ThreadNode {
     65     jthread thread;
     66     unsigned int toBeResumed : 1;
     67     unsigned int pendingInterrupt : 1;
     68     unsigned int isDebugThread : 1;
     69     unsigned int suspendOnStart : 1;
     70     unsigned int isStarted : 1;
     71     unsigned int popFrameEvent : 1;
     72     unsigned int popFrameProceed : 1;
     73     unsigned int popFrameThread : 1;
     74     EventIndex current_ei;
     75     jobject pendingStop;
     76     jint suspendCount;
     77     jint resumeFrameDepth; /* !=0 => This thread is in a call to Thread.resume() */
     78     jvmtiEventMode instructionStepMode;
     79     StepRequest currentStep;
     80     InvokeRequest currentInvoke;
     81     struct bag *eventBag;
     82     CoLocatedEventInfo cleInfo;
     83     struct ThreadNode *next;
     84     struct ThreadNode *prev;
     85     jlong frameGeneration;
     86     struct ThreadList *list;  /* Tells us what list this thread is in */
     87 } ThreadNode;
     88 
     89 static jint suspendAllCount;
     90 
     91 typedef struct ThreadList {
     92     ThreadNode *first;
     93 } ThreadList;
     94 
     95 /*
     96  * popFrameEventLock is used to notify that the event has been received
     97  */
     98 static jrawMonitorID popFrameEventLock = NULL;
     99 
    100 /*
    101  * popFrameProceedLock is used to assure that the event thread is
    102  * re-suspended immediately after the event is acknowledged.
    103  */
    104 static jrawMonitorID popFrameProceedLock = NULL;
    105 
    106 static jrawMonitorID threadLock;
    107 static jlocation resumeLocation;
    108 static HandlerNode *breakpointHandlerNode;
    109 static HandlerNode *framePopHandlerNode;
    110 static HandlerNode *catchHandlerNode;
    111 
    112 static jvmtiError threadControl_removeDebugThread(jthread thread);
    113 
    114 /*
    115  * Threads which have issued thread start events and not yet issued thread
    116  * end events are maintained in the "runningThreads" list. All other threads known
    117  * to this module are kept in the "otherThreads" list.
    118  */
    119 static ThreadList runningThreads;
    120 static ThreadList otherThreads;
    121 
    122 #define MAX_DEBUG_THREADS 10
    123 static int debugThreadCount;
    124 static jthread debugThreads[MAX_DEBUG_THREADS];
    125 
    126 typedef struct DeferredEventMode {
    127     EventIndex ei;
    128     jvmtiEventMode mode;
    129     jthread thread;
    130     struct DeferredEventMode *next;
    131 } DeferredEventMode;
    132 
    133 typedef struct {
    134     DeferredEventMode *first;
    135     DeferredEventMode *last;
    136 } DeferredEventModeList;
    137 
    138 static DeferredEventModeList deferredEventModes;
    139 
    140 static jint
    141 getStackDepth(jthread thread)
    142 {
    143     jint count = 0;
    144     jvmtiError error;
    145 
    146     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
    147                         (gdata->jvmti, thread, &count);
    148     if (error != JVMTI_ERROR_NONE) {
    149         EXIT_ERROR(error, "getting frame count");
    150     }
    151     return count;
    152 }
    153 
    154 /* Get the state of the thread direct from JVMTI */
    155 static jvmtiError
    156 threadState(jthread thread, jint *pstate)
    157 {
    158     *pstate = 0;
    159     return JVMTI_FUNC_PTR(gdata->jvmti,GetThreadState)
    160                         (gdata->jvmti, thread, pstate);
    161 }
    162 
    163 /* Set TLS on a specific jthread to the ThreadNode* */
    164 static void
    165 setThreadLocalStorage(jthread thread, ThreadNode *node)
    166 {
    167     jvmtiError  error;
    168 
    169     error = JVMTI_FUNC_PTR(gdata->jvmti,SetThreadLocalStorage)
    170             (gdata->jvmti, thread, (void*)node);
    171     if ( error == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
    172         /* Just return, thread hasn't started yet */
    173         return;
    174     } else if ( error != JVMTI_ERROR_NONE ) {
    175         /* The jthread object must be valid, so this must be a fatal error */
    176         EXIT_ERROR(error, "cannot set thread local storage");
    177     }
    178 }
    179 
    180 /* Get TLS on a specific jthread, which is the ThreadNode* */
    181 static ThreadNode *
    182 getThreadLocalStorage(jthread thread)
    183 {
    184     jvmtiError  error;
    185     ThreadNode *node;
    186 
    187     node = NULL;
    188     error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadLocalStorage)
    189             (gdata->jvmti, thread, (void**)&node);
    190     if ( error == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
    191         /* Just return NULL, thread hasn't started yet */
    192         return NULL;
    193     } else if ( error != JVMTI_ERROR_NONE ) {
    194         /* The jthread object must be valid, so this must be a fatal error */
    195         EXIT_ERROR(error, "cannot get thread local storage");
    196     }
    197     return node;
    198 }
    199 
    200 /* Search list for nodes that don't have TLS set and match this thread.
    201  *   It assumed that this logic is never dealing with terminated threads,
    202  *   since the ThreadEnd events always delete the ThreadNode while the
    203  *   jthread is still alive.  So we can only look at the ThreadNode's that
    204  *   have never had their TLS set, making the search much faster.
    205  *   But keep in mind, this kind of search should rarely be needed.
    206  */
    207 static ThreadNode *
    208 nonTlsSearch(JNIEnv *env, ThreadList *list, jthread thread)
    209 {
    210     ThreadNode *node;
    211 
    212     for (node = list->first; node != NULL; node = node->next) {
    213         if (isSameObject(env, node->thread, thread)) {
    214             break;
    215         }
    216     }
    217     return node;
    218 }
    219 
    220 /*
    221  * These functions maintain the linked list of currently running threads.
    222  * All assume that the threadLock is held before calling.
    223  * If list==NULL, search both lists.
    224  */
    225 static ThreadNode *
    226 findThread(ThreadList *list, jthread thread)
    227 {
    228     ThreadNode *node;
    229 
    230     /* Get thread local storage for quick thread -> node access */
    231     node = getThreadLocalStorage(thread);
    232 
    233     /* In some rare cases we might get NULL, so we check the list manually for
    234      *   any threads that we could match.
    235      */
    236     if ( node == NULL ) {
    237         JNIEnv *env;
    238 
    239         env = getEnv();
    240         if ( list != NULL ) {
    241             node = nonTlsSearch(env, list, thread);
    242         } else {
    243             node = nonTlsSearch(env, &runningThreads, thread);
    244             if ( node == NULL ) {
    245                 node = nonTlsSearch(env, &otherThreads, thread);
    246             }
    247         }
    248         if ( node != NULL ) {
    249             /* Here we make another attempt to set TLS, it's ok if this fails */
    250             setThreadLocalStorage(thread, (void*)node);
    251         }
    252     }
    253 
    254     /* If a list is supplied, only return ones in this list */
    255     if ( node != NULL && list != NULL && node->list != list ) {
    256         return NULL;
    257     }
    258     return node;
    259 }
    260 
    261 /* Remove a ThreadNode from a ThreadList */
    262 static void
    263 removeNode(ThreadList *list, ThreadNode *node)
    264 {
    265     ThreadNode *prev;
    266     ThreadNode *next;
    267 
    268     prev = node->prev;
    269     next = node->next;
    270     if ( prev != NULL ) {
    271         prev->next = next;
    272     }
    273     if ( next != NULL ) {
    274         next->prev = prev;
    275     }
    276     if ( prev == NULL ) {
    277         list->first = next;
    278     }
    279     node->next = NULL;
    280     node->prev = NULL;
    281     node->list = NULL;
    282 }
    283 
    284 /* Add a ThreadNode to a ThreadList */
    285 static void
    286 addNode(ThreadList *list, ThreadNode *node)
    287 {
    288     node->next = NULL;
    289     node->prev = NULL;
    290     node->list = NULL;
    291     if ( list->first == NULL ) {
    292         list->first = node;
    293     } else {
    294         list->first->prev = node;
    295         node->next = list->first;
    296         list->first = node;
    297     }
    298     node->list = list;
    299 }
    300 
    301 static ThreadNode *
    302 insertThread(JNIEnv *env, ThreadList *list, jthread thread)
    303 {
    304     ThreadNode *node;
    305     struct bag *eventBag;
    306 
    307     node = findThread(list, thread);
    308     if (node == NULL) {
    309         node = jvmtiAllocate(sizeof(*node));
    310         if (node == NULL) {
    311             EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"thread table entry");
    312             return NULL;
    313         }
    314         (void)memset(node, 0, sizeof(*node));
    315         eventBag = eventHelper_createEventBag();
    316         if (eventBag == NULL) {
    317             jvmtiDeallocate(node);
    318             EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"thread table entry");
    319             return NULL;
    320         }
    321 
    322         /*
    323          * Init all flags false, all refs NULL, all counts 0
    324          */
    325 
    326         saveGlobalRef(env, thread, &(node->thread));
    327         if (node->thread == NULL) {
    328             jvmtiDeallocate(node);
    329             bagDestroyBag(eventBag);
    330             EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"thread table entry");
    331             return NULL;
    332         }
    333         /*
    334          * Remember if it is a debug thread
    335          */
    336         if (threadControl_isDebugThread(node->thread)) {
    337             node->isDebugThread = JNI_TRUE;
    338         } else if (suspendAllCount > 0){
    339             /*
    340              * If there is a pending suspendAll, all new threads should
    341              * be initialized as if they were suspended by the suspendAll,
    342              * and the thread will need to be suspended when it starts.
    343              */
    344             node->suspendCount = suspendAllCount;
    345             node->suspendOnStart = JNI_TRUE;
    346         }
    347         node->current_ei = 0;
    348         node->instructionStepMode = JVMTI_DISABLE;
    349         node->eventBag = eventBag;
    350         addNode(list, node);
    351 
    352         /* Set thread local storage for quick thread -> node access.
    353          *   Some threads may not be in a state that allows setting of TLS,
    354          *   which is ok, see findThread, it deals with threads without TLS set.
    355          */
    356         setThreadLocalStorage(node->thread, (void*)node);
    357     }
    358 
    359     return node;
    360 }
    361 
    362 static void
    363 clearThread(JNIEnv *env, ThreadNode *node)
    364 {
    365     if (node->pendingStop != NULL) {
    366         tossGlobalRef(env, &(node->pendingStop));
    367     }
    368     stepControl_clearRequest(node->thread, &node->currentStep);
    369     if (node->isDebugThread) {
    370         (void)threadControl_removeDebugThread(node->thread);
    371     }
    372     /* Clear out TLS on this thread (just a cleanup action) */
    373     setThreadLocalStorage(node->thread, NULL);
    374     tossGlobalRef(env, &(node->thread));
    375     bagDestroyBag(node->eventBag);
    376     jvmtiDeallocate(node);
    377 }
    378 
    379 static void
    380 removeThread(JNIEnv *env, ThreadList *list, jthread thread)
    381 {
    382     ThreadNode *node;
    383 
    384     node = findThread(list, thread);
    385     if (node != NULL) {
    386         removeNode(list, node);
    387         clearThread(env, node);
    388     }
    389 }
    390 
    391 static void
    392 removeResumed(JNIEnv *env, ThreadList *list)
    393 {
    394     ThreadNode *node;
    395 
    396     node = list->first;
    397     while (node != NULL) {
    398         ThreadNode *temp = node->next;
    399         if (node->suspendCount == 0) {
    400             removeThread(env, list, node->thread);
    401         }
    402         node = temp;
    403     }
    404 }
    405 
    406 static void
    407 moveNode(ThreadList *source, ThreadList *dest, ThreadNode *node)
    408 {
    409     removeNode(source, node);
    410     JDI_ASSERT(findThread(dest, node->thread) == NULL);
    411     addNode(dest, node);
    412 }
    413 
    414 typedef jvmtiError (*ThreadEnumerateFunction)(JNIEnv *, ThreadNode *, void *);
    415 
    416 static jvmtiError
    417 enumerateOverThreadList(JNIEnv *env, ThreadList *list,
    418                         ThreadEnumerateFunction function, void *arg)
    419 {
    420     ThreadNode *node;
    421     jvmtiError error = JVMTI_ERROR_NONE;
    422 
    423     for (node = list->first; node != NULL; node = node->next) {
    424         error = (*function)(env, node, arg);
    425         if ( error != JVMTI_ERROR_NONE ) {
    426             break;
    427         }
    428     }
    429     return error;
    430 }
    431 
    432 static void
    433 insertEventMode(DeferredEventModeList *list, DeferredEventMode *eventMode)
    434 {
    435     if (list->last != NULL) {
    436         list->last->next = eventMode;
    437     } else {
    438         list->first = eventMode;
    439     }
    440     list->last = eventMode;
    441 }
    442 
    443 static void
    444 removeEventMode(DeferredEventModeList *list, DeferredEventMode *eventMode, DeferredEventMode *prev)
    445 {
    446     if (prev == NULL) {
    447         list->first = eventMode->next;
    448     } else {
    449         prev->next = eventMode->next;
    450     }
    451     if (eventMode->next == NULL) {
    452         list->last = prev;
    453     }
    454 }
    455 
    456 static jvmtiError
    457 addDeferredEventMode(JNIEnv *env, jvmtiEventMode mode, EventIndex ei, jthread thread)
    458 {
    459     DeferredEventMode *eventMode;
    460 
    461     /*LINTED*/
    462     eventMode = jvmtiAllocate((jint)sizeof(DeferredEventMode));
    463     if (eventMode == NULL) {
    464         return AGENT_ERROR_OUT_OF_MEMORY;
    465     }
    466     eventMode->thread = NULL;
    467     saveGlobalRef(env, thread, &(eventMode->thread));
    468     eventMode->mode = mode;
    469     eventMode->ei = ei;
    470     eventMode->next = NULL;
    471     insertEventMode(&deferredEventModes, eventMode);
    472     return JVMTI_ERROR_NONE;
    473 }
    474 
    475 static void
    476 freeDeferredEventModes(JNIEnv *env)
    477 {
    478     DeferredEventMode *eventMode;
    479     eventMode = deferredEventModes.first;
    480     while (eventMode != NULL) {
    481         DeferredEventMode *next;
    482         next = eventMode->next;
    483         tossGlobalRef(env, &(eventMode->thread));
    484         jvmtiDeallocate(eventMode);
    485         eventMode = next;
    486     }
    487     deferredEventModes.first = NULL;
    488     deferredEventModes.last = NULL;
    489 }
    490 
    491 static jvmtiError
    492 threadSetEventNotificationMode(ThreadNode *node,
    493         jvmtiEventMode mode, EventIndex ei, jthread thread)
    494 {
    495     jvmtiError error;
    496 
    497     /* record single step mode */
    498     if (ei == EI_SINGLE_STEP) {
    499         node->instructionStepMode = mode;
    500     }
    501     error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
    502         (gdata->jvmti, mode, eventIndex2jvmti(ei), thread);
    503     return error;
    504 }
    505 
    506 static void
    507 processDeferredEventModes(JNIEnv *env, jthread thread, ThreadNode *node)
    508 {
    509     jvmtiError error;
    510     DeferredEventMode *eventMode;
    511     DeferredEventMode *prev;
    512 
    513     prev = NULL;
    514     eventMode = deferredEventModes.first;
    515     while (eventMode != NULL) {
    516         DeferredEventMode *next = eventMode->next;
    517         if (isSameObject(env, thread, eventMode->thread)) {
    518             error = threadSetEventNotificationMode(node,
    519                     eventMode->mode, eventMode->ei, eventMode->thread);
    520             if (error != JVMTI_ERROR_NONE) {
    521                 EXIT_ERROR(error, "cannot process deferred thread event notifications at thread start");
    522             }
    523             removeEventMode(&deferredEventModes, eventMode, prev);
    524             tossGlobalRef(env, &(eventMode->thread));
    525             jvmtiDeallocate(eventMode);
    526         } else {
    527             prev = eventMode;
    528         }
    529         eventMode = next;
    530     }
    531 }
    532 
    533 static void
    534 getLocks(void)
    535 {
    536     /*
    537      * Anything which might be locked as part of the handling of
    538      * a JVMTI event (which means: might be locked by an application
    539      * thread) needs to be grabbed here. This allows thread control
    540      * code to safely suspend and resume the application threads
    541      * while ensuring they don't hold a critical lock.
    542      */
    543 
    544     eventHandler_lock();
    545     invoker_lock();
    546     eventHelper_lock();
    547     stepControl_lock();
    548     commonRef_lock();
    549     debugMonitorEnter(threadLock);
    550 
    551 }
    552 
    553 static void
    554 releaseLocks(void)
    555 {
    556     debugMonitorExit(threadLock);
    557     commonRef_unlock();
    558     stepControl_unlock();
    559     eventHelper_unlock();
    560     invoker_unlock();
    561     eventHandler_unlock();
    562 }
    563 
    564 void
    565 threadControl_initialize(void)
    566 {
    567     jlocation unused;
    568     jvmtiError error;
    569 
    570     suspendAllCount = 0;
    571     runningThreads.first = NULL;
    572     otherThreads.first = NULL;
    573     debugThreadCount = 0;
    574     threadLock = debugMonitorCreate("JDWP Thread Lock");
    575     if (gdata->threadClass==NULL) {
    576         EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "no java.lang.thread class");
    577     }
    578     if (gdata->threadResume==0) {
    579         EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "cannot resume thread");
    580     }
    581     /* Get the java.lang.Thread.resume() method beginning location */
    582     error = methodLocation(gdata->threadResume, &resumeLocation, &unused);
    583     if (error != JVMTI_ERROR_NONE) {
    584         EXIT_ERROR(error, "getting method location");
    585     }
    586 }
    587 
    588 static jthread
    589 getResumee(jthread resumingThread)
    590 {
    591     jthread resumee = NULL;
    592     jvmtiError error;
    593     jobject object;
    594     FrameNumber fnum = 0;
    595 
    596     // ANDROID-CHANGED: On ART 'this' is not always in register 0. We just use GetLocalInstance in
    597     // all cases.
    598     error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInstance)
    599                     (gdata->jvmti, resumingThread, fnum, &object);
    600     if (error == JVMTI_ERROR_NONE) {
    601         resumee = object;
    602     }
    603     return resumee;
    604 }
    605 
    606 
    607 static jboolean
    608 pendingAppResume(jboolean includeSuspended)
    609 {
    610     ThreadList *list;
    611     ThreadNode *node;
    612 
    613     list = &runningThreads;
    614     node = list->first;
    615     while (node != NULL) {
    616         if (node->resumeFrameDepth > 0) {
    617             if (includeSuspended) {
    618                 return JNI_TRUE;
    619             } else {
    620                 jvmtiError error;
    621                 jint       state;
    622 
    623                 error = threadState(node->thread, &state);
    624                 if (error != JVMTI_ERROR_NONE) {
    625                     EXIT_ERROR(error, "getting thread state");
    626                 }
    627                 if (!(state & JVMTI_THREAD_STATE_SUSPENDED)) {
    628                     return JNI_TRUE;
    629                 }
    630             }
    631         }
    632         node = node->next;
    633     }
    634     return JNI_FALSE;
    635 }
    636 
    637 static void
    638 notifyAppResumeComplete(void)
    639 {
    640     debugMonitorNotifyAll(threadLock);
    641     if (!pendingAppResume(JNI_TRUE)) {
    642         if (framePopHandlerNode != NULL) {
    643             (void)eventHandler_free(framePopHandlerNode);
    644             framePopHandlerNode = NULL;
    645         }
    646         if (catchHandlerNode != NULL) {
    647             (void)eventHandler_free(catchHandlerNode);
    648             catchHandlerNode = NULL;
    649         }
    650     }
    651 }
    652 
    653 static void
    654 handleAppResumeCompletion(JNIEnv *env, EventInfo *evinfo,
    655                           HandlerNode *handlerNode,
    656                           struct bag *eventBag)
    657 {
    658     ThreadNode *node;
    659     jthread     thread;
    660 
    661     thread = evinfo->thread;
    662 
    663     debugMonitorEnter(threadLock);
    664 
    665     node = findThread(&runningThreads, thread);
    666     if (node != NULL) {
    667         if (node->resumeFrameDepth > 0) {
    668             jint compareDepth = getStackDepth(thread);
    669             if (evinfo->ei == EI_FRAME_POP) {
    670                 compareDepth--;
    671             }
    672             if (compareDepth < node->resumeFrameDepth) {
    673                 node->resumeFrameDepth = 0;
    674                 notifyAppResumeComplete();
    675             }
    676         }
    677     }
    678 
    679     debugMonitorExit(threadLock);
    680 }
    681 
    682 static void
    683 blockOnDebuggerSuspend(jthread thread)
    684 {
    685     ThreadNode *node;
    686 
    687     node = findThread(NULL, thread);
    688     if (node != NULL) {
    689         while (node && node->suspendCount > 0) {
    690             debugMonitorWait(threadLock);
    691             node = findThread(NULL, thread);
    692         }
    693     }
    694 }
    695 
    696 static void
    697 trackAppResume(jthread thread)
    698 {
    699     jvmtiError  error;
    700     FrameNumber fnum;
    701     ThreadNode *node;
    702 
    703     fnum = 0;
    704     node = findThread(&runningThreads, thread);
    705     if (node != NULL) {
    706         JDI_ASSERT(node->resumeFrameDepth == 0);
    707         error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)
    708                         (gdata->jvmti, thread, fnum);
    709         if (error == JVMTI_ERROR_NONE) {
    710             jint frameDepth = getStackDepth(thread);
    711             if ((frameDepth > 0) && (framePopHandlerNode == NULL)) {
    712                 framePopHandlerNode = eventHandler_createInternalThreadOnly(
    713                                            EI_FRAME_POP,
    714                                            handleAppResumeCompletion,
    715                                            thread);
    716                 catchHandlerNode = eventHandler_createInternalThreadOnly(
    717                                            EI_EXCEPTION_CATCH,
    718                                            handleAppResumeCompletion,
    719                                            thread);
    720                 if ((framePopHandlerNode == NULL) ||
    721                     (catchHandlerNode == NULL)) {
    722                     (void)eventHandler_free(framePopHandlerNode);
    723                     framePopHandlerNode = NULL;
    724                     (void)eventHandler_free(catchHandlerNode);
    725                     catchHandlerNode = NULL;
    726                 }
    727             }
    728             if ((framePopHandlerNode != NULL) &&
    729                 (catchHandlerNode != NULL) &&
    730                 (frameDepth > 0)) {
    731                 node->resumeFrameDepth = frameDepth;
    732             }
    733         }
    734     }
    735 }
    736 
    737 static void
    738 handleAppResumeBreakpoint(JNIEnv *env, EventInfo *evinfo,
    739                           HandlerNode *handlerNode,
    740                           struct bag *eventBag)
    741 {
    742     jthread resumer = evinfo->thread;
    743     jthread resumee = getResumee(resumer);
    744 
    745     debugMonitorEnter(threadLock);
    746     if (resumee != NULL) {
    747         /*
    748          * Hold up any attempt to resume as long as the debugger
    749          * has suspended the resumee.
    750          */
    751         blockOnDebuggerSuspend(resumee);
    752     }
    753 
    754     if (resumer != NULL) {
    755         /*
    756          * Track the resuming thread by marking it as being within
    757          * a resume and by setting up for notification on
    758          * a frame pop or exception. We won't allow the debugger
    759          * to suspend threads while any thread is within a
    760          * call to resume. This (along with the block above)
    761          * ensures that when the debugger
    762          * suspends a thread it will remain suspended.
    763          */
    764         trackAppResume(resumer);
    765     }
    766 
    767     debugMonitorExit(threadLock);
    768 }
    769 
    770 void
    771 threadControl_onConnect(void)
    772 {
    773     breakpointHandlerNode = eventHandler_createInternalBreakpoint(
    774                  handleAppResumeBreakpoint, NULL,
    775                  gdata->threadClass, gdata->threadResume, resumeLocation);
    776 }
    777 
    778 void
    779 threadControl_onDisconnect(void)
    780 {
    781     if (breakpointHandlerNode != NULL) {
    782         (void)eventHandler_free(breakpointHandlerNode);
    783         breakpointHandlerNode = NULL;
    784     }
    785     if (framePopHandlerNode != NULL) {
    786         (void)eventHandler_free(framePopHandlerNode);
    787         framePopHandlerNode = NULL;
    788     }
    789     if (catchHandlerNode != NULL) {
    790         (void)eventHandler_free(catchHandlerNode);
    791         catchHandlerNode = NULL;
    792     }
    793 }
    794 
    795 void
    796 threadControl_onHook(void)
    797 {
    798     /*
    799      * As soon as the event hook is in place, we need to initialize
    800      * the thread list with already-existing threads. The threadLock
    801      * has been held since initialize, so we don't need to worry about
    802      * insertions or deletions from the event handlers while we do this
    803      */
    804     JNIEnv *env;
    805 
    806     env = getEnv();
    807 
    808     /*
    809      * Prevent any event processing until OnHook has been called
    810      */
    811     debugMonitorEnter(threadLock);
    812 
    813     WITH_LOCAL_REFS(env, 1) {
    814 
    815         jint threadCount;
    816         jthread *threads;
    817 
    818         threads = allThreads(&threadCount);
    819         if (threads == NULL) {
    820             EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"thread table");
    821         } else {
    822 
    823             int i;
    824 
    825             for (i = 0; i < threadCount; i++) {
    826                 ThreadNode *node;
    827                 jthread thread = threads[i];
    828                 node = insertThread(env, &runningThreads, thread);
    829 
    830                 /*
    831                  * This is a tiny bit risky. We have to assume that the
    832                  * pre-existing threads have been started because we
    833                  * can't rely on a thread start event for them. The chances
    834                  * of a problem related to this are pretty slim though, and
    835                  * there's really no choice because without setting this flag
    836                  * there is no way to enable stepping and other events on
    837                  * the threads that already exist (e.g. the finalizer thread).
    838                  */
    839                 node->isStarted = JNI_TRUE;
    840             }
    841         }
    842 
    843     } END_WITH_LOCAL_REFS(env)
    844 
    845     debugMonitorExit(threadLock);
    846 }
    847 
    848 static jvmtiError
    849 commonSuspendByNode(ThreadNode *node)
    850 {
    851     jvmtiError error;
    852 
    853     LOG_MISC(("thread=%p suspended", node->thread));
    854     error = JVMTI_FUNC_PTR(gdata->jvmti,SuspendThread)
    855                 (gdata->jvmti, node->thread);
    856 
    857     /*
    858      * Mark for resume only if suspend succeeded
    859      */
    860     if (error == JVMTI_ERROR_NONE) {
    861         node->toBeResumed = JNI_TRUE;
    862     }
    863 
    864     /*
    865      * If the thread was suspended by another app thread,
    866      * do nothing and report no error (we won't resume it later).
    867      */
    868      if (error == JVMTI_ERROR_THREAD_SUSPENDED) {
    869         error = JVMTI_ERROR_NONE;
    870      }
    871 
    872      return error;
    873 }
    874 
    875 /*
    876  * Deferred suspends happen when the suspend is attempted on a thread
    877  * that is not started. Bookkeeping (suspendCount,etc.)
    878  * is handled by the original request, and once the thread actually
    879  * starts, an actual suspend is attempted. This function does the
    880  * deferred suspend without changing the bookkeeping that is already
    881  * in place.
    882  */
    883 static jint
    884 deferredSuspendThreadByNode(ThreadNode *node)
    885 {
    886     jvmtiError error;
    887 
    888     error = JVMTI_ERROR_NONE;
    889     if (node->isDebugThread) {
    890         /* Ignore requests for suspending debugger threads */
    891         return JVMTI_ERROR_NONE;
    892     }
    893 
    894     /*
    895      * Do the actual suspend only if a subsequent resume hasn't
    896      * made it irrelevant.
    897      */
    898     if (node->suspendCount > 0) {
    899         error = commonSuspendByNode(node);
    900 
    901         /*
    902          * Attempt to clean up from any error by decrementing the
    903          * suspend count. This compensates for the increment that
    904          * happens when suspendOnStart is set to true.
    905          */
    906         if (error != JVMTI_ERROR_NONE) {
    907           node->suspendCount--;
    908         }
    909     }
    910 
    911     node->suspendOnStart = JNI_FALSE;
    912 
    913     debugMonitorNotifyAll(threadLock);
    914 
    915     return error;
    916 }
    917 
    918 static jvmtiError
    919 suspendThreadByNode(ThreadNode *node)
    920 {
    921     jvmtiError error = JVMTI_ERROR_NONE;
    922     if (node->isDebugThread) {
    923         /* Ignore requests for suspending debugger threads */
    924         return JVMTI_ERROR_NONE;
    925     }
    926 
    927     /*
    928      * Just increment the suspend count if we are waiting
    929      * for a deferred suspend.
    930      */
    931     if (node->suspendOnStart) {
    932         node->suspendCount++;
    933         return JVMTI_ERROR_NONE;
    934     }
    935 
    936     if (node->suspendCount == 0) {
    937         error = commonSuspendByNode(node);
    938 
    939         if (error == JVMTI_ERROR_THREAD_NOT_ALIVE) {
    940             /*
    941              * This error means that the thread is either a zombie or not yet
    942              * started. In either case, we ignore the error. If the thread
    943              * is a zombie, suspend/resume are no-ops. If the thread is not
    944              * started, it will be suspended for real during the processing
    945              * of its thread start event.
    946              */
    947             node->suspendOnStart = JNI_TRUE;
    948             error = JVMTI_ERROR_NONE;
    949         }
    950     }
    951 
    952     if (error == JVMTI_ERROR_NONE) {
    953         node->suspendCount++;
    954     }
    955 
    956     debugMonitorNotifyAll(threadLock);
    957 
    958     return error;
    959 }
    960 
    961 static jvmtiError
    962 resumeThreadByNode(ThreadNode *node)
    963 {
    964     jvmtiError error = JVMTI_ERROR_NONE;
    965 
    966     if (node->isDebugThread) {
    967         /* never suspended by debugger => don't ever try to resume */
    968         return JVMTI_ERROR_NONE;
    969     }
    970     if (node->suspendCount > 0) {
    971         node->suspendCount--;
    972         debugMonitorNotifyAll(threadLock);
    973         if ((node->suspendCount == 0) && node->toBeResumed &&
    974             !node->suspendOnStart) {
    975             LOG_MISC(("thread=%p resumed", node->thread));
    976             error = JVMTI_FUNC_PTR(gdata->jvmti,ResumeThread)
    977                         (gdata->jvmti, node->thread);
    978             node->frameGeneration++; /* Increment on each resume */
    979             node->toBeResumed = JNI_FALSE;
    980             if (error == JVMTI_ERROR_THREAD_NOT_ALIVE && !node->isStarted) {
    981                 /*
    982                  * We successfully "suspended" this thread, but
    983                  * we never received a THREAD_START event for it.
    984                  * Since the thread never ran, we can ignore our
    985                  * failure to resume the thread.
    986                  */
    987                 error = JVMTI_ERROR_NONE;
    988             }
    989         }
    990     }
    991 
    992     return error;
    993 }
    994 
    995 /*
    996  * Functions which respond to user requests to suspend/resume
    997  * threads.
    998  * Suspends and resumes add and subtract from a count respectively.
    999  * The thread is only suspended when the count goes from 0 to 1 and
   1000  * resumed only when the count goes from 1 to 0.
   1001  *
   1002  * These functions suspend and resume application threads
   1003  * without changing the
   1004  * state of threads that were already suspended beforehand.
   1005  * They must not be called from an application thread because
   1006  * that thread may be suspended somewhere in the  middle of things.
   1007  */
   1008 static void
   1009 preSuspend(void)
   1010 {
   1011     getLocks();                     /* Avoid debugger deadlocks */
   1012 
   1013     /*
   1014      * Delay any suspend while a call to java.lang.Thread.resume is in
   1015      * progress (not including those in suspended threads). The wait is
   1016      * timed because the threads suspended through
   1017      * java.lang.Thread.suspend won't result in a notify even though
   1018      * it may change the result of pendingAppResume()
   1019      */
   1020     while (pendingAppResume(JNI_FALSE)) {
   1021         /*
   1022          * This is ugly but we need to release the locks from getLocks
   1023          * or else the notify will never happen. The locks must be
   1024          * released and reacquired in the right order. else deadlocks
   1025          * can happen. It is possible that, during this dance, the
   1026          * notify will be missed, but since the wait needs to be timed
   1027          * anyway, it won't be a disaster. Note that this code will
   1028          * execute only on very rare occasions anyway.
   1029          */
   1030         releaseLocks();
   1031 
   1032         debugMonitorEnter(threadLock);
   1033         debugMonitorTimedWait(threadLock, 1000);
   1034         debugMonitorExit(threadLock);
   1035 
   1036         getLocks();
   1037     }
   1038 }
   1039 
   1040 static void
   1041 postSuspend(void)
   1042 {
   1043     releaseLocks();
   1044 }
   1045 
   1046 /*
   1047  * This function must be called after preSuspend and before postSuspend.
   1048  */
   1049 static jvmtiError
   1050 commonSuspend(JNIEnv *env, jthread thread, jboolean deferred)
   1051 {
   1052     ThreadNode *node;
   1053 
   1054     /*
   1055      * If the thread is not between its start and end events, we should
   1056      * still suspend it. To keep track of things, add the thread
   1057      * to a separate list of threads so that we'll resume it later.
   1058      */
   1059     node = findThread(&runningThreads, thread);
   1060     if (node == NULL) {
   1061         node = insertThread(env, &otherThreads, thread);
   1062     }
   1063 
   1064     if ( deferred ) {
   1065         return deferredSuspendThreadByNode(node);
   1066     } else {
   1067         return suspendThreadByNode(node);
   1068     }
   1069 }
   1070 
   1071 
   1072 static jvmtiError
   1073 resumeCopyHelper(JNIEnv *env, ThreadNode *node, void *arg)
   1074 {
   1075     if (node->isDebugThread) {
   1076         /* never suspended by debugger => don't ever try to resume */
   1077         return JVMTI_ERROR_NONE;
   1078     }
   1079 
   1080     if (node->suspendCount > 1) {
   1081         node->suspendCount--;
   1082         /* nested suspend so just undo one level */
   1083         return JVMTI_ERROR_NONE;
   1084     }
   1085 
   1086     /*
   1087      * This thread was marked for suspension since its THREAD_START
   1088      * event came in during a suspendAll, but the helper hasn't
   1089      * completed the job yet. We decrement the count so the helper
   1090      * won't suspend this thread after we are done with the resumeAll.
   1091      * Another case to be handled here is when the debugger suspends
   1092      * the thread while the app has it suspended. In this case,
   1093      * the toBeResumed flag has been cleared indicating that
   1094      * the thread should not be resumed when the debugger does a resume.
   1095      * In this case, we also have to decrement the suspend count.
   1096      * If we don't then when the app resumes the thread and our Thread.resume
   1097      * bkpt handler is called, blockOnDebuggerSuspend will not resume
   1098      * the thread because suspendCount will be 1 meaning that the
   1099      * debugger has the thread suspended.  See bug 6224859.
   1100      */
   1101     if (node->suspendCount == 1 && (!node->toBeResumed || node->suspendOnStart)) {
   1102         node->suspendCount--;
   1103         return JVMTI_ERROR_NONE;
   1104     }
   1105 
   1106     if (arg == NULL) {
   1107         /* nothing to hard resume so we're done */
   1108         return JVMTI_ERROR_NONE;
   1109     }
   1110 
   1111     /*
   1112      * This is tricky. A suspendCount of 1 and toBeResumed means that
   1113      * JVM/DI SuspendThread() or JVM/DI SuspendThreadList() was called
   1114      * on this thread. The check for !suspendOnStart is paranoia that
   1115      * we inherited from resumeThreadByNode().
   1116      */
   1117     if (node->suspendCount == 1 && node->toBeResumed && !node->suspendOnStart) {
   1118         jthread **listPtr = (jthread **)arg;
   1119 
   1120         **listPtr = node->thread;
   1121         (*listPtr)++;
   1122     }
   1123     return JVMTI_ERROR_NONE;
   1124 }
   1125 
   1126 
   1127 static jvmtiError
   1128 resumeCountHelper(JNIEnv *env, ThreadNode *node, void *arg)
   1129 {
   1130     if (node->isDebugThread) {
   1131         /* never suspended by debugger => don't ever try to resume */
   1132         return JVMTI_ERROR_NONE;
   1133     }
   1134 
   1135     /*
   1136      * This is tricky. A suspendCount of 1 and toBeResumed means that
   1137      * JVM/DI SuspendThread() or JVM/DI SuspendThreadList() was called
   1138      * on this thread. The check for !suspendOnStart is paranoia that
   1139      * we inherited from resumeThreadByNode().
   1140      */
   1141     if (node->suspendCount == 1 && node->toBeResumed && !node->suspendOnStart) {
   1142         jint *counter = (jint *)arg;
   1143 
   1144         (*counter)++;
   1145     }
   1146     return JVMTI_ERROR_NONE;
   1147 }
   1148 
   1149 static void *
   1150 newArray(jint length, size_t nbytes)
   1151 {
   1152     void *ptr;
   1153     ptr = jvmtiAllocate(length*(jint)nbytes);
   1154     if ( ptr != NULL ) {
   1155         (void)memset(ptr, 0, length*nbytes);
   1156     }
   1157     return ptr;
   1158 }
   1159 
   1160 static void
   1161 deleteArray(void *ptr)
   1162 {
   1163     jvmtiDeallocate(ptr);
   1164 }
   1165 
   1166 /*
   1167  * This function must be called with the threadLock held.
   1168  *
   1169  * Two facts conspire to make this routine complicated:
   1170  *
   1171  * 1) the VM doesn't support nested external suspend
   1172  * 2) the original resumeAll code structure doesn't retrieve the
   1173  *    entire thread list from JVMTI so we use the runningThreads
   1174  *    list and two helpers to get the job done.
   1175  *
   1176  * Because we hold the threadLock, state seen by resumeCountHelper()
   1177  * is the same state seen in resumeCopyHelper(). resumeCountHelper()
   1178  * just counts up the number of threads to be hard resumed.
   1179  * resumeCopyHelper() does the accounting for nested suspends and
   1180  * special cases and, finally, populates the list of hard resume
   1181  * threads to be passed to ResumeThreadList().
   1182  *
   1183  * At first glance, you might think that the accounting could be done
   1184  * in resumeCountHelper(), but then resumeCopyHelper() would see
   1185  * "post-resume" state in the accounting values (suspendCount and
   1186  * toBeResumed) and would not be able to distinguish between a thread
   1187  * that needs a hard resume versus a thread that is already running.
   1188  */
   1189 static jvmtiError
   1190 commonResumeList(JNIEnv *env)
   1191 {
   1192     jvmtiError   error;
   1193     jint         i;
   1194     jint         reqCnt;
   1195     jthread     *reqList;
   1196     jthread     *reqPtr;
   1197     jvmtiError  *results;
   1198 
   1199     reqCnt = 0;
   1200 
   1201     /* count number of threads to hard resume */
   1202     (void) enumerateOverThreadList(env, &runningThreads, resumeCountHelper,
   1203                                    &reqCnt);
   1204     if (reqCnt == 0) {
   1205         /* nothing to hard resume so do just the accounting part */
   1206         (void) enumerateOverThreadList(env, &runningThreads, resumeCopyHelper,
   1207                                        NULL);
   1208         return JVMTI_ERROR_NONE;
   1209     }
   1210 
   1211     /*LINTED*/
   1212     reqList = newArray(reqCnt, sizeof(jthread));
   1213     if (reqList == NULL) {
   1214         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"resume request list");
   1215     }
   1216     /*LINTED*/
   1217     results = newArray(reqCnt, sizeof(jvmtiError));
   1218     if (results == NULL) {
   1219         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"resume list");
   1220     }
   1221 
   1222     /* copy the jthread values for threads to hard resume */
   1223     reqPtr = reqList;
   1224     (void) enumerateOverThreadList(env, &runningThreads, resumeCopyHelper,
   1225                                    &reqPtr);
   1226 
   1227     error = JVMTI_FUNC_PTR(gdata->jvmti,ResumeThreadList)
   1228                 (gdata->jvmti, reqCnt, reqList, results);
   1229     for (i = 0; i < reqCnt; i++) {
   1230         ThreadNode *node;
   1231 
   1232         node = findThread(&runningThreads, reqList[i]);
   1233         if (node == NULL) {
   1234             EXIT_ERROR(AGENT_ERROR_INVALID_THREAD,"missing entry in running thread table");
   1235         }
   1236         LOG_MISC(("thread=%p resumed as part of list", node->thread));
   1237 
   1238         /*
   1239          * resumeThreadByNode() assumes that JVM/DI ResumeThread()
   1240          * always works and does all the accounting updates. We do
   1241          * the same here. We also don't clear the error.
   1242          */
   1243         node->suspendCount--;
   1244         node->toBeResumed = JNI_FALSE;
   1245         node->frameGeneration++; /* Increment on each resume */
   1246     }
   1247     deleteArray(results);
   1248     deleteArray(reqList);
   1249 
   1250     debugMonitorNotifyAll(threadLock);
   1251 
   1252     return error;
   1253 }
   1254 
   1255 
   1256 /*
   1257  * This function must be called after preSuspend and before postSuspend.
   1258  */
   1259 static jvmtiError
   1260 commonSuspendList(JNIEnv *env, jint initCount, jthread *initList)
   1261 {
   1262     jvmtiError  error;
   1263     jint        i;
   1264     jint        reqCnt;
   1265     jthread    *reqList;
   1266 
   1267     error   = JVMTI_ERROR_NONE;
   1268     reqCnt  = 0;
   1269     reqList = newArray(initCount, sizeof(jthread));
   1270     if (reqList == NULL) {
   1271         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"request list");
   1272     }
   1273 
   1274     /*
   1275      * Go through the initial list and see if we have anything to suspend.
   1276      */
   1277     for (i = 0; i < initCount; i++) {
   1278         ThreadNode *node;
   1279 
   1280         /*
   1281          * If the thread is not between its start and end events, we should
   1282          * still suspend it. To keep track of things, add the thread
   1283          * to a separate list of threads so that we'll resume it later.
   1284          */
   1285         node = findThread(&runningThreads, initList[i]);
   1286         if (node == NULL) {
   1287             node = insertThread(env, &otherThreads, initList[i]);
   1288         }
   1289 
   1290         if (node->isDebugThread) {
   1291             /* Ignore requests for suspending debugger threads */
   1292             continue;
   1293         }
   1294 
   1295         /*
   1296          * Just increment the suspend count if we are waiting
   1297          * for a deferred suspend or if this is a nested suspend.
   1298          */
   1299         if (node->suspendOnStart || node->suspendCount > 0) {
   1300             node->suspendCount++;
   1301             continue;
   1302         }
   1303 
   1304         if (node->suspendCount == 0) {
   1305             /* thread is not suspended yet so put it on the request list */
   1306             reqList[reqCnt++] = initList[i];
   1307         }
   1308     }
   1309 
   1310     if (reqCnt > 0) {
   1311         jvmtiError *results = newArray(reqCnt, sizeof(jvmtiError));
   1312 
   1313         if (results == NULL) {
   1314             EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"suspend list results");
   1315         }
   1316 
   1317         /*
   1318          * We have something to suspend so try to do it.
   1319          */
   1320         error = JVMTI_FUNC_PTR(gdata->jvmti,SuspendThreadList)
   1321                         (gdata->jvmti, reqCnt, reqList, results);
   1322         for (i = 0; i < reqCnt; i++) {
   1323             ThreadNode *node;
   1324 
   1325             node = findThread(NULL, reqList[i]);
   1326             if (node == NULL) {
   1327                 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD,"missing entry in thread tables");
   1328             }
   1329             LOG_MISC(("thread=%p suspended as part of list", node->thread));
   1330 
   1331             if (results[i] == JVMTI_ERROR_NONE) {
   1332                 /* thread was suspended as requested */
   1333                 node->toBeResumed = JNI_TRUE;
   1334             } else if (results[i] == JVMTI_ERROR_THREAD_SUSPENDED) {
   1335                 /*
   1336                  * If the thread was suspended by another app thread,
   1337                  * do nothing and report no error (we won't resume it later).
   1338                  */
   1339                 results[i] = JVMTI_ERROR_NONE;
   1340             } else if (results[i] == JVMTI_ERROR_THREAD_NOT_ALIVE) {
   1341                 /*
   1342                  * This error means that the suspend request failed
   1343                  * because the thread is either a zombie or not yet
   1344                  * started. In either case, we ignore the error. If the
   1345                  * thread is a zombie, suspend/resume are no-ops. If the
   1346                  * thread is not started, it will be suspended for real
   1347                  * during the processing of its thread start event.
   1348                  */
   1349                 node->suspendOnStart = JNI_TRUE;
   1350                 results[i] = JVMTI_ERROR_NONE;
   1351             }
   1352 
   1353             /* count real, app and deferred (suspendOnStart) suspensions */
   1354             if (results[i] == JVMTI_ERROR_NONE) {
   1355                 node->suspendCount++;
   1356             }
   1357         }
   1358         deleteArray(results);
   1359     }
   1360     deleteArray(reqList);
   1361 
   1362     debugMonitorNotifyAll(threadLock);
   1363 
   1364     return error;
   1365 }
   1366 
   1367 
   1368 static jvmtiError
   1369 commonResume(jthread thread)
   1370 {
   1371     jvmtiError  error;
   1372     ThreadNode *node;
   1373 
   1374     /*
   1375      * The thread is normally between its start and end events, but if
   1376      * not, check the auxiliary list used by threadControl_suspendThread.
   1377      */
   1378     node = findThread(NULL, thread);
   1379 
   1380     /*
   1381      * If the node is in neither list, the debugger never suspended
   1382      * this thread, so do nothing.
   1383      */
   1384     error = JVMTI_ERROR_NONE;
   1385     if (node != NULL) {
   1386         error = resumeThreadByNode(node);
   1387     }
   1388     return error;
   1389 }
   1390 
   1391 
   1392 jvmtiError
   1393 threadControl_suspendThread(jthread thread, jboolean deferred)
   1394 {
   1395     jvmtiError error;
   1396     JNIEnv    *env;
   1397 
   1398     env = getEnv();
   1399 
   1400     log_debugee_location("threadControl_suspendThread()", thread, NULL, 0);
   1401 
   1402     preSuspend();
   1403     error = commonSuspend(env, thread, deferred);
   1404     postSuspend();
   1405 
   1406     return error;
   1407 }
   1408 
   1409 jvmtiError
   1410 threadControl_resumeThread(jthread thread, jboolean do_unblock)
   1411 {
   1412     jvmtiError error;
   1413     JNIEnv    *env;
   1414 
   1415     env = getEnv();
   1416 
   1417     log_debugee_location("threadControl_resumeThread()", thread, NULL, 0);
   1418 
   1419     eventHandler_lock(); /* for proper lock order */
   1420     debugMonitorEnter(threadLock);
   1421     error = commonResume(thread);
   1422     removeResumed(env, &otherThreads);
   1423     debugMonitorExit(threadLock);
   1424     eventHandler_unlock();
   1425 
   1426     if (do_unblock) {
   1427         /* let eventHelper.c: commandLoop() know we resumed one thread */
   1428         unblockCommandLoop();
   1429     }
   1430 
   1431     return error;
   1432 }
   1433 
   1434 jvmtiError
   1435 threadControl_suspendCount(jthread thread, jint *count)
   1436 {
   1437     jvmtiError  error;
   1438     ThreadNode *node;
   1439 
   1440     debugMonitorEnter(threadLock);
   1441 
   1442     node = findThread(&runningThreads, thread);
   1443     if (node == NULL) {
   1444         node = findThread(&otherThreads, thread);
   1445     }
   1446 
   1447     error = JVMTI_ERROR_NONE;
   1448     if (node != NULL) {
   1449         *count = node->suspendCount;
   1450     } else {
   1451         /*
   1452          * If the node is in neither list, the debugger never suspended
   1453          * this thread, so the suspend count is 0.
   1454          */
   1455         *count = 0;
   1456     }
   1457 
   1458     debugMonitorExit(threadLock);
   1459 
   1460     return error;
   1461 }
   1462 
   1463 static jboolean
   1464 contains(JNIEnv *env, jthread *list, jint count, jthread item)
   1465 {
   1466     int i;
   1467 
   1468     for (i = 0; i < count; i++) {
   1469         if (isSameObject(env, list[i], item)) {
   1470             return JNI_TRUE;
   1471         }
   1472     }
   1473     return JNI_FALSE;
   1474 }
   1475 
   1476 
   1477 typedef struct {
   1478     jthread *list;
   1479     jint count;
   1480 } SuspendAllArg;
   1481 
   1482 static jvmtiError
   1483 suspendAllHelper(JNIEnv *env, ThreadNode *node, void *arg)
   1484 {
   1485     SuspendAllArg *saArg = (SuspendAllArg *)arg;
   1486     jvmtiError error = JVMTI_ERROR_NONE;
   1487     jthread *list = saArg->list;
   1488     jint count = saArg->count;
   1489     if (!contains(env, list, count, node->thread)) {
   1490         error = commonSuspend(env, node->thread, JNI_FALSE);
   1491     }
   1492     return error;
   1493 }
   1494 
   1495 jvmtiError
   1496 threadControl_suspendAll(void)
   1497 {
   1498     jvmtiError error;
   1499     JNIEnv    *env;
   1500 
   1501     env = getEnv();
   1502 
   1503     log_debugee_location("threadControl_suspendAll()", NULL, NULL, 0);
   1504 
   1505     preSuspend();
   1506 
   1507     /*
   1508      * Get a list of all threads and suspend them.
   1509      */
   1510     WITH_LOCAL_REFS(env, 1) {
   1511 
   1512         jthread *threads;
   1513         jint count;
   1514 
   1515         threads = allThreads(&count);
   1516         if (threads == NULL) {
   1517             error = AGENT_ERROR_OUT_OF_MEMORY;
   1518             goto err;
   1519         }
   1520         if (canSuspendResumeThreadLists()) {
   1521             error = commonSuspendList(env, count, threads);
   1522             if (error != JVMTI_ERROR_NONE) {
   1523                 goto err;
   1524             }
   1525         } else {
   1526 
   1527             int i;
   1528 
   1529             for (i = 0; i < count; i++) {
   1530                 error = commonSuspend(env, threads[i], JNI_FALSE);
   1531 
   1532                 if (error != JVMTI_ERROR_NONE) {
   1533                     goto err;
   1534                 }
   1535             }
   1536         }
   1537 
   1538         /*
   1539          * Update the suspend count of any threads not yet (or no longer)
   1540          * in the thread list above.
   1541          */
   1542         {
   1543             SuspendAllArg arg;
   1544             arg.list = threads;
   1545             arg.count = count;
   1546             error = enumerateOverThreadList(env, &otherThreads,
   1547                                             suspendAllHelper, &arg);
   1548         }
   1549 
   1550         if (error == JVMTI_ERROR_NONE) {
   1551             suspendAllCount++;
   1552         }
   1553 
   1554     err: ;
   1555 
   1556     } END_WITH_LOCAL_REFS(env)
   1557 
   1558     postSuspend();
   1559 
   1560     return error;
   1561 }
   1562 
   1563 static jvmtiError
   1564 resumeHelper(JNIEnv *env, ThreadNode *node, void *ignored)
   1565 {
   1566     /*
   1567      * Since this helper is called with the threadLock held, we
   1568      * don't need to recheck to see if the node is still on one
   1569      * of the two thread lists.
   1570      */
   1571     return resumeThreadByNode(node);
   1572 }
   1573 
   1574 jvmtiError
   1575 threadControl_resumeAll(void)
   1576 {
   1577     jvmtiError error;
   1578     JNIEnv    *env;
   1579 
   1580     env = getEnv();
   1581 
   1582     log_debugee_location("threadControl_resumeAll()", NULL, NULL, 0);
   1583 
   1584     eventHandler_lock(); /* for proper lock order */
   1585     debugMonitorEnter(threadLock);
   1586 
   1587     /*
   1588      * Resume only those threads that the debugger has suspended. All
   1589      * such threads must have a node in one of the thread lists, so there's
   1590      * no need to get the whole thread list from JVMTI (unlike
   1591      * suspendAll).
   1592      */
   1593     if (canSuspendResumeThreadLists()) {
   1594         error = commonResumeList(env);
   1595     } else {
   1596         error = enumerateOverThreadList(env, &runningThreads,
   1597                                         resumeHelper, NULL);
   1598     }
   1599     if ((error == JVMTI_ERROR_NONE) && (otherThreads.first != NULL)) {
   1600         error = enumerateOverThreadList(env, &otherThreads,
   1601                                         resumeHelper, NULL);
   1602         removeResumed(env, &otherThreads);
   1603     }
   1604 
   1605     if (suspendAllCount > 0) {
   1606         suspendAllCount--;
   1607     }
   1608 
   1609     debugMonitorExit(threadLock);
   1610     eventHandler_unlock();
   1611     /* let eventHelper.c: commandLoop() know we are resuming */
   1612     unblockCommandLoop();
   1613 
   1614     return error;
   1615 }
   1616 
   1617 
   1618 StepRequest *
   1619 threadControl_getStepRequest(jthread thread)
   1620 {
   1621     ThreadNode  *node;
   1622     StepRequest *step;
   1623 
   1624     step = NULL;
   1625 
   1626     debugMonitorEnter(threadLock);
   1627 
   1628     node = findThread(&runningThreads, thread);
   1629     if (node != NULL) {
   1630         step = &node->currentStep;
   1631     }
   1632 
   1633     debugMonitorExit(threadLock);
   1634 
   1635     return step;
   1636 }
   1637 
   1638 InvokeRequest *
   1639 threadControl_getInvokeRequest(jthread thread)
   1640 {
   1641     ThreadNode    *node;
   1642     InvokeRequest *request;
   1643 
   1644     request = NULL;
   1645 
   1646     debugMonitorEnter(threadLock);
   1647 
   1648     node = findThread(&runningThreads, thread);
   1649     if (node != NULL) {
   1650          request = &node->currentInvoke;
   1651     }
   1652 
   1653     debugMonitorExit(threadLock);
   1654 
   1655     return request;
   1656 }
   1657 
   1658 jvmtiError
   1659 threadControl_addDebugThread(jthread thread)
   1660 {
   1661     jvmtiError error;
   1662 
   1663     debugMonitorEnter(threadLock);
   1664     if (debugThreadCount >= MAX_DEBUG_THREADS) {
   1665         error = AGENT_ERROR_OUT_OF_MEMORY;
   1666     } else {
   1667         JNIEnv    *env;
   1668 
   1669         env = getEnv();
   1670         debugThreads[debugThreadCount] = NULL;
   1671         saveGlobalRef(env, thread, &(debugThreads[debugThreadCount]));
   1672         if (debugThreads[debugThreadCount] == NULL) {
   1673             error = AGENT_ERROR_OUT_OF_MEMORY;
   1674         } else {
   1675             debugThreadCount++;
   1676             error = JVMTI_ERROR_NONE;
   1677         }
   1678     }
   1679     debugMonitorExit(threadLock);
   1680     return error;
   1681 }
   1682 
   1683 static jvmtiError
   1684 threadControl_removeDebugThread(jthread thread)
   1685 {
   1686     jvmtiError error;
   1687     JNIEnv    *env;
   1688     int        i;
   1689 
   1690     error = AGENT_ERROR_INVALID_THREAD;
   1691     env   = getEnv();
   1692 
   1693     debugMonitorEnter(threadLock);
   1694     for (i = 0; i< debugThreadCount; i++) {
   1695         if (isSameObject(env, thread, debugThreads[i])) {
   1696             int j;
   1697 
   1698             tossGlobalRef(env, &(debugThreads[i]));
   1699             for (j = i+1; j < debugThreadCount; j++) {
   1700                 debugThreads[j-1] = debugThreads[j];
   1701             }
   1702             debugThreadCount--;
   1703             error = JVMTI_ERROR_NONE;
   1704             break;
   1705         }
   1706     }
   1707     debugMonitorExit(threadLock);
   1708     return error;
   1709 }
   1710 
   1711 jboolean
   1712 threadControl_isDebugThread(jthread thread)
   1713 {
   1714     int      i;
   1715     jboolean rc;
   1716     JNIEnv  *env;
   1717 
   1718     rc  = JNI_FALSE;
   1719     env = getEnv();
   1720 
   1721     debugMonitorEnter(threadLock);
   1722     for (i = 0; i < debugThreadCount; i++) {
   1723         if (isSameObject(env, thread, debugThreads[i])) {
   1724             rc = JNI_TRUE;
   1725             break;
   1726         }
   1727     }
   1728     debugMonitorExit(threadLock);
   1729     return rc;
   1730 }
   1731 
   1732 static void
   1733 initLocks(void)
   1734 {
   1735     if (popFrameEventLock == NULL) {
   1736         popFrameEventLock = debugMonitorCreate("JDWP PopFrame Event Lock");
   1737         popFrameProceedLock = debugMonitorCreate("JDWP PopFrame Proceed Lock");
   1738     }
   1739 }
   1740 
   1741 static jboolean
   1742 getPopFrameThread(jthread thread)
   1743 {
   1744     jboolean popFrameThread;
   1745 
   1746     debugMonitorEnter(threadLock);
   1747     {
   1748         ThreadNode *node;
   1749 
   1750         node = findThread(NULL, thread);
   1751         if (node == NULL) {
   1752             popFrameThread = JNI_FALSE;
   1753         } else {
   1754             popFrameThread = node->popFrameThread;
   1755         }
   1756     }
   1757     debugMonitorExit(threadLock);
   1758 
   1759     return popFrameThread;
   1760 }
   1761 
   1762 static void
   1763 setPopFrameThread(jthread thread, jboolean value)
   1764 {
   1765     debugMonitorEnter(threadLock);
   1766     {
   1767         ThreadNode *node;
   1768 
   1769         node = findThread(NULL, thread);
   1770         if (node == NULL) {
   1771             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"entry in thread table");
   1772         } else {
   1773             node->popFrameThread = value;
   1774         }
   1775     }
   1776     debugMonitorExit(threadLock);
   1777 }
   1778 
   1779 static jboolean
   1780 getPopFrameEvent(jthread thread)
   1781 {
   1782     jboolean popFrameEvent;
   1783 
   1784     debugMonitorEnter(threadLock);
   1785     {
   1786         ThreadNode *node;
   1787 
   1788         node = findThread(NULL, thread);
   1789         if (node == NULL) {
   1790             popFrameEvent = JNI_FALSE;
   1791             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"entry in thread table");
   1792         } else {
   1793             popFrameEvent = node->popFrameEvent;
   1794         }
   1795     }
   1796     debugMonitorExit(threadLock);
   1797 
   1798     return popFrameEvent;
   1799 }
   1800 
   1801 static void
   1802 setPopFrameEvent(jthread thread, jboolean value)
   1803 {
   1804     debugMonitorEnter(threadLock);
   1805     {
   1806         ThreadNode *node;
   1807 
   1808         node = findThread(NULL, thread);
   1809         if (node == NULL) {
   1810             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"entry in thread table");
   1811         } else {
   1812             node->popFrameEvent = value;
   1813             node->frameGeneration++; /* Increment on each resume */
   1814         }
   1815     }
   1816     debugMonitorExit(threadLock);
   1817 }
   1818 
   1819 static jboolean
   1820 getPopFrameProceed(jthread thread)
   1821 {
   1822     jboolean popFrameProceed;
   1823 
   1824     debugMonitorEnter(threadLock);
   1825     {
   1826         ThreadNode *node;
   1827 
   1828         node = findThread(NULL, thread);
   1829         if (node == NULL) {
   1830             popFrameProceed = JNI_FALSE;
   1831             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"entry in thread table");
   1832         } else {
   1833             popFrameProceed = node->popFrameProceed;
   1834         }
   1835     }
   1836     debugMonitorExit(threadLock);
   1837 
   1838     return popFrameProceed;
   1839 }
   1840 
   1841 static void
   1842 setPopFrameProceed(jthread thread, jboolean value)
   1843 {
   1844     debugMonitorEnter(threadLock);
   1845     {
   1846         ThreadNode *node;
   1847 
   1848         node = findThread(NULL, thread);
   1849         if (node == NULL) {
   1850             EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"entry in thread table");
   1851         } else {
   1852             node->popFrameProceed = value;
   1853         }
   1854     }
   1855     debugMonitorExit(threadLock);
   1856 }
   1857 
   1858 /**
   1859  * Special event handler for events on the popped thread
   1860  * that occur during the pop operation.
   1861  */
   1862 static void
   1863 popFrameCompleteEvent(jthread thread)
   1864 {
   1865       debugMonitorEnter(popFrameProceedLock);
   1866       {
   1867           /* notify that we got the event */
   1868           debugMonitorEnter(popFrameEventLock);
   1869           {
   1870               setPopFrameEvent(thread, JNI_TRUE);
   1871               debugMonitorNotify(popFrameEventLock);
   1872           }
   1873           debugMonitorExit(popFrameEventLock);
   1874 
   1875           /* make sure we get suspended again */
   1876           setPopFrameProceed(thread, JNI_FALSE);
   1877           while (getPopFrameProceed(thread) == JNI_FALSE) {
   1878               debugMonitorWait(popFrameProceedLock);
   1879           }
   1880       }
   1881       debugMonitorExit(popFrameProceedLock);
   1882 }
   1883 
   1884 /**
   1885  * Pop one frame off the stack of thread.
   1886  * popFrameEventLock is already held
   1887  */
   1888 static jvmtiError
   1889 popOneFrame(jthread thread)
   1890 {
   1891     jvmtiError error;
   1892 
   1893     error = JVMTI_FUNC_PTR(gdata->jvmti,PopFrame)(gdata->jvmti, thread);
   1894     if (error != JVMTI_ERROR_NONE) {
   1895         return error;
   1896     }
   1897 
   1898     /* resume the popped thread so that the pop occurs and so we */
   1899     /* will get the event (step or method entry) after the pop */
   1900     LOG_MISC(("thread=%p resumed in popOneFrame", thread));
   1901     error = JVMTI_FUNC_PTR(gdata->jvmti,ResumeThread)(gdata->jvmti, thread);
   1902     if (error != JVMTI_ERROR_NONE) {
   1903         return error;
   1904     }
   1905 
   1906     /* wait for the event to occur */
   1907     setPopFrameEvent(thread, JNI_FALSE);
   1908     while (getPopFrameEvent(thread) == JNI_FALSE) {
   1909         debugMonitorWait(popFrameEventLock);
   1910     }
   1911 
   1912     /* make sure not to suspend until the popped thread is on the wait */
   1913     debugMonitorEnter(popFrameProceedLock);
   1914     {
   1915         /* return popped thread to suspended state */
   1916         LOG_MISC(("thread=%p suspended in popOneFrame", thread));
   1917         error = JVMTI_FUNC_PTR(gdata->jvmti,SuspendThread)(gdata->jvmti, thread);
   1918 
   1919         /* notify popped thread so it can proceed when resumed */
   1920         setPopFrameProceed(thread, JNI_TRUE);
   1921         debugMonitorNotify(popFrameProceedLock);
   1922     }
   1923     debugMonitorExit(popFrameProceedLock);
   1924 
   1925     return error;
   1926 }
   1927 
   1928 /**
   1929  * pop frames of the stack of 'thread' until 'frame' is popped.
   1930  */
   1931 jvmtiError
   1932 threadControl_popFrames(jthread thread, FrameNumber fnum)
   1933 {
   1934     jvmtiError error;
   1935     jvmtiEventMode prevStepMode;
   1936     jint framesPopped = 0;
   1937     jint popCount;
   1938     jboolean prevInvokeRequestMode;
   1939 
   1940     log_debugee_location("threadControl_popFrames()", thread, NULL, 0);
   1941 
   1942     initLocks();
   1943 
   1944     /* compute the number of frames to pop */
   1945     popCount = fnum+1;
   1946     if (popCount < 1) {
   1947         return AGENT_ERROR_NO_MORE_FRAMES;
   1948     }
   1949 
   1950     /* enable instruction level single step, but first note prev value */
   1951     prevStepMode = threadControl_getInstructionStepMode(thread);
   1952 
   1953     /*
   1954      * Fix bug 6517249.  The pop processing will disable invokes,
   1955      * so remember if invokes are enabled now and restore
   1956      * that state after we finish popping.
   1957      */
   1958     prevInvokeRequestMode = invoker_isEnabled(thread);
   1959 
   1960     error = threadControl_setEventMode(JVMTI_ENABLE,
   1961                                        EI_SINGLE_STEP, thread);
   1962     if (error != JVMTI_ERROR_NONE) {
   1963         return error;
   1964     }
   1965 
   1966     /* Inform eventHandler logic we are in a popFrame for this thread */
   1967     debugMonitorEnter(popFrameEventLock);
   1968     {
   1969         setPopFrameThread(thread, JNI_TRUE);
   1970         /* pop frames using single step */
   1971         while (framesPopped++ < popCount) {
   1972             error = popOneFrame(thread);
   1973             if (error != JVMTI_ERROR_NONE) {
   1974                 break;
   1975             }
   1976         }
   1977         setPopFrameThread(thread, JNI_FALSE);
   1978     }
   1979     debugMonitorExit(popFrameEventLock);
   1980 
   1981     /*  Reset StepRequest info (fromLine and stackDepth) after popframes
   1982      *  only if stepping is enabled.
   1983      */
   1984     if (prevStepMode == JVMTI_ENABLE) {
   1985         stepControl_resetRequest(thread);
   1986     }
   1987 
   1988     if (prevInvokeRequestMode) {
   1989         invoker_enableInvokeRequests(thread);
   1990     }
   1991 
   1992     /* restore state */
   1993     (void)threadControl_setEventMode(prevStepMode,
   1994                                EI_SINGLE_STEP, thread);
   1995 
   1996     return error;
   1997 }
   1998 
   1999 /* Check to see if any events are being consumed by a popFrame(). */
   2000 static jboolean
   2001 checkForPopFrameEvents(JNIEnv *env, EventIndex ei, jthread thread)
   2002 {
   2003     if ( getPopFrameThread(thread) ) {
   2004         switch (ei) {
   2005             case EI_THREAD_START:
   2006                 /* Excuse me? */
   2007                 EXIT_ERROR(AGENT_ERROR_INTERNAL, "thread start during pop frame");
   2008                 break;
   2009             case EI_THREAD_END:
   2010                 /* Thread wants to end? let it. */
   2011                 setPopFrameThread(thread, JNI_FALSE);
   2012                 popFrameCompleteEvent(thread);
   2013                 break;
   2014             case EI_SINGLE_STEP:
   2015                 /* This is an event we requested to mark the */
   2016                 /*        completion of the pop frame */
   2017                 popFrameCompleteEvent(thread);
   2018                 return JNI_TRUE;
   2019             case EI_BREAKPOINT:
   2020             case EI_EXCEPTION:
   2021             case EI_FIELD_ACCESS:
   2022             case EI_FIELD_MODIFICATION:
   2023             case EI_METHOD_ENTRY:
   2024             case EI_METHOD_EXIT:
   2025                 /* Tell event handler to assume event has been consumed. */
   2026                 return JNI_TRUE;
   2027             default:
   2028                 break;
   2029         }
   2030     }
   2031     /* Pretend we were never called */
   2032     return JNI_FALSE;
   2033 }
   2034 
   2035 struct bag *
   2036 threadControl_onEventHandlerEntry(jbyte sessionID, EventIndex ei, jthread thread, jobject currentException)
   2037 {
   2038     ThreadNode *node;
   2039     JNIEnv     *env;
   2040     struct bag *eventBag;
   2041     jthread     threadToSuspend;
   2042     jboolean    consumed;
   2043 
   2044     env             = getEnv();
   2045     threadToSuspend = NULL;
   2046 
   2047     log_debugee_location("threadControl_onEventHandlerEntry()", thread, NULL, 0);
   2048 
   2049     /* Events during pop commands may need to be ignored here. */
   2050     consumed = checkForPopFrameEvents(env, ei, thread);
   2051     if ( consumed ) {
   2052         /* Always restore any exception (see below). */
   2053         if (currentException != NULL) {
   2054             JNI_FUNC_PTR(env,Throw)(env, currentException);
   2055         } else {
   2056             JNI_FUNC_PTR(env,ExceptionClear)(env);
   2057         }
   2058         return NULL;
   2059     }
   2060 
   2061     debugMonitorEnter(threadLock);
   2062 
   2063     /*
   2064      * Check the list of unknown threads maintained by suspend
   2065      * and resume. If this thread is currently present in the
   2066      * list, it should be
   2067      * moved to the runningThreads list, since it is a
   2068      * well-known thread now.
   2069      */
   2070     node = findThread(&otherThreads, thread);
   2071     if (node != NULL) {
   2072         moveNode(&otherThreads, &runningThreads, node);
   2073     } else {
   2074         /*
   2075          * Get a thread node for the reporting thread. For thread start
   2076          * events, or if this event precedes a thread start event,
   2077          * the thread node may need to be created.
   2078          *
   2079          * It is possible for certain events (notably method entry/exit)
   2080          * to precede thread start for some VM implementations.
   2081          */
   2082         node = insertThread(env, &runningThreads, thread);
   2083     }
   2084 
   2085     if (ei == EI_THREAD_START) {
   2086         node->isStarted = JNI_TRUE;
   2087         processDeferredEventModes(env, thread, node);
   2088     }
   2089 
   2090     node->current_ei = ei;
   2091     eventBag = node->eventBag;
   2092     if (node->suspendOnStart) {
   2093         threadToSuspend = node->thread;
   2094     }
   2095     debugMonitorExit(threadLock);
   2096 
   2097     if (threadToSuspend != NULL) {
   2098         /*
   2099          * An attempt was made to suspend this thread before it started.
   2100          * We must suspend it now, before it starts to run. This must
   2101          * be done with no locks held.
   2102          */
   2103         eventHelper_suspendThread(sessionID, threadToSuspend);
   2104     }
   2105 
   2106     return eventBag;
   2107 }
   2108 
   2109 static void
   2110 doPendingTasks(JNIEnv *env, ThreadNode *node)
   2111 {
   2112     /*
   2113      * Take care of any pending interrupts/stops, and clear out
   2114      * info on pending interrupts/stops.
   2115      */
   2116     if (node->pendingInterrupt) {
   2117         JVMTI_FUNC_PTR(gdata->jvmti,InterruptThread)
   2118                         (gdata->jvmti, node->thread);
   2119         /*
   2120          * TO DO: Log error
   2121          */
   2122         node->pendingInterrupt = JNI_FALSE;
   2123     }
   2124 
   2125     if (node->pendingStop != NULL) {
   2126         JVMTI_FUNC_PTR(gdata->jvmti,StopThread)
   2127                         (gdata->jvmti, node->thread, node->pendingStop);
   2128         /*
   2129          * TO DO: Log error
   2130          */
   2131         tossGlobalRef(env, &(node->pendingStop));
   2132     }
   2133 }
   2134 
   2135 void
   2136 threadControl_onEventHandlerExit(EventIndex ei, jthread thread,
   2137                                  struct bag *eventBag)
   2138 {
   2139     ThreadNode *node;
   2140 
   2141     log_debugee_location("threadControl_onEventHandlerExit()", thread, NULL, 0);
   2142 
   2143     if (ei == EI_THREAD_END) {
   2144         eventHandler_lock(); /* for proper lock order */
   2145     }
   2146     debugMonitorEnter(threadLock);
   2147 
   2148     node = findThread(&runningThreads, thread);
   2149     if (node == NULL) {
   2150         EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"thread list corrupted");
   2151     } else {
   2152         JNIEnv *env;
   2153 
   2154         env = getEnv();
   2155         if (ei == EI_THREAD_END) {
   2156             jboolean inResume = (node->resumeFrameDepth > 0);
   2157             removeThread(env, &runningThreads, thread);
   2158             node = NULL;   /* has been freed */
   2159 
   2160             /*
   2161              * Clean up mechanism used to detect end of
   2162              * resume.
   2163              */
   2164             if (inResume) {
   2165                 notifyAppResumeComplete();
   2166             }
   2167         } else {
   2168             /* No point in doing this if the thread is about to die.*/
   2169             doPendingTasks(env, node);
   2170             node->eventBag = eventBag;
   2171             node->current_ei = 0;
   2172         }
   2173     }
   2174 
   2175     debugMonitorExit(threadLock);
   2176     if (ei == EI_THREAD_END) {
   2177         eventHandler_unlock();
   2178     }
   2179 }
   2180 
   2181 /* Returns JDWP flavored status and status flags. */
   2182 jvmtiError
   2183 threadControl_applicationThreadStatus(jthread thread,
   2184                         jdwpThreadStatus *pstatus, jint *statusFlags)
   2185 {
   2186     ThreadNode *node;
   2187     jvmtiError  error;
   2188     jint        state;
   2189 
   2190     log_debugee_location("threadControl_applicationThreadStatus()", thread, NULL, 0);
   2191 
   2192     debugMonitorEnter(threadLock);
   2193 
   2194     error = threadState(thread, &state);
   2195     *pstatus = map2jdwpThreadStatus(state);
   2196     *statusFlags = map2jdwpSuspendStatus(state);
   2197 
   2198     if (error == JVMTI_ERROR_NONE) {
   2199         node = findThread(&runningThreads, thread);
   2200         if ((node != NULL) && HANDLING_EVENT(node)) {
   2201             /*
   2202              * While processing an event, an application thread is always
   2203              * considered to be running even if its handler happens to be
   2204              * cond waiting on an internal debugger monitor, etc.
   2205              *
   2206              * Leave suspend status untouched since it is not possible
   2207              * to distinguish debugger suspends from app suspends.
   2208              */
   2209             *pstatus = JDWP_THREAD_STATUS(RUNNING);
   2210         }
   2211     }
   2212 
   2213     debugMonitorExit(threadLock);
   2214 
   2215     return error;
   2216 }
   2217 
   2218 jvmtiError
   2219 threadControl_interrupt(jthread thread)
   2220 {
   2221     ThreadNode *node;
   2222     jvmtiError  error;
   2223 
   2224     error = JVMTI_ERROR_NONE;
   2225 
   2226     log_debugee_location("threadControl_interrupt()", thread, NULL, 0);
   2227 
   2228     debugMonitorEnter(threadLock);
   2229 
   2230     node = findThread(&runningThreads, thread);
   2231     if ((node == NULL) || !HANDLING_EVENT(node)) {
   2232         error = JVMTI_FUNC_PTR(gdata->jvmti,InterruptThread)
   2233                         (gdata->jvmti, thread);
   2234     } else {
   2235         /*
   2236          * Hold any interrupts until after the event is processed.
   2237          */
   2238         node->pendingInterrupt = JNI_TRUE;
   2239     }
   2240 
   2241     debugMonitorExit(threadLock);
   2242 
   2243     return error;
   2244 }
   2245 
   2246 void
   2247 threadControl_clearCLEInfo(JNIEnv *env, jthread thread)
   2248 {
   2249     ThreadNode *node;
   2250 
   2251     debugMonitorEnter(threadLock);
   2252 
   2253     node = findThread(&runningThreads, thread);
   2254     if (node != NULL) {
   2255         node->cleInfo.ei = 0;
   2256         if (node->cleInfo.clazz != NULL) {
   2257             tossGlobalRef(env, &(node->cleInfo.clazz));
   2258         }
   2259     }
   2260 
   2261     debugMonitorExit(threadLock);
   2262 }
   2263 
   2264 jboolean
   2265 threadControl_cmpCLEInfo(JNIEnv *env, jthread thread, jclass clazz,
   2266                          jmethodID method, jlocation location)
   2267 {
   2268     ThreadNode *node;
   2269     jboolean    result;
   2270 
   2271     result = JNI_FALSE;
   2272 
   2273     debugMonitorEnter(threadLock);
   2274 
   2275     node = findThread(&runningThreads, thread);
   2276     if (node != NULL && node->cleInfo.ei != 0 &&
   2277         node->cleInfo.method == method &&
   2278         node->cleInfo.location == location &&
   2279         (isSameObject(env, node->cleInfo.clazz, clazz))) {
   2280         result = JNI_TRUE; /* we have a match */
   2281     }
   2282 
   2283     debugMonitorExit(threadLock);
   2284 
   2285     return result;
   2286 }
   2287 
   2288 void
   2289 threadControl_saveCLEInfo(JNIEnv *env, jthread thread, EventIndex ei,
   2290                           jclass clazz, jmethodID method, jlocation location)
   2291 {
   2292     ThreadNode *node;
   2293 
   2294     debugMonitorEnter(threadLock);
   2295 
   2296     node = findThread(&runningThreads, thread);
   2297     if (node != NULL) {
   2298         node->cleInfo.ei = ei;
   2299         /* Create a class ref that will live beyond */
   2300         /* the end of this call */
   2301         saveGlobalRef(env, clazz, &(node->cleInfo.clazz));
   2302         /* if returned clazz is NULL, we just won't match */
   2303         node->cleInfo.method    = method;
   2304         node->cleInfo.location  = location;
   2305     }
   2306 
   2307     debugMonitorExit(threadLock);
   2308 }
   2309 
   2310 void
   2311 threadControl_setPendingInterrupt(jthread thread)
   2312 {
   2313     ThreadNode *node;
   2314 
   2315     debugMonitorEnter(threadLock);
   2316 
   2317     node = findThread(&runningThreads, thread);
   2318     if (node != NULL) {
   2319         node->pendingInterrupt = JNI_TRUE;
   2320     }
   2321 
   2322     debugMonitorExit(threadLock);
   2323 }
   2324 
   2325 jvmtiError
   2326 threadControl_stop(jthread thread, jobject throwable)
   2327 {
   2328     ThreadNode *node;
   2329     jvmtiError  error;
   2330 
   2331     error = JVMTI_ERROR_NONE;
   2332 
   2333     log_debugee_location("threadControl_stop()", thread, NULL, 0);
   2334 
   2335     debugMonitorEnter(threadLock);
   2336 
   2337     node = findThread(&runningThreads, thread);
   2338     if ((node == NULL) || !HANDLING_EVENT(node)) {
   2339         error = JVMTI_FUNC_PTR(gdata->jvmti,StopThread)
   2340                         (gdata->jvmti, thread, throwable);
   2341     } else {
   2342         JNIEnv *env;
   2343 
   2344         /*
   2345          * Hold any stops until after the event is processed.
   2346          */
   2347         env = getEnv();
   2348         saveGlobalRef(env, throwable, &(node->pendingStop));
   2349     }
   2350 
   2351     debugMonitorExit(threadLock);
   2352 
   2353     return error;
   2354 }
   2355 
   2356 static jvmtiError
   2357 detachHelper(JNIEnv *env, ThreadNode *node, void *arg)
   2358 {
   2359     invoker_detach(&node->currentInvoke);
   2360     return JVMTI_ERROR_NONE;
   2361 }
   2362 
   2363 void
   2364 threadControl_detachInvokes(void)
   2365 {
   2366     JNIEnv *env;
   2367 
   2368     env = getEnv();
   2369     invoker_lock(); /* for proper lock order */
   2370     debugMonitorEnter(threadLock);
   2371     (void)enumerateOverThreadList(env, &runningThreads, detachHelper, NULL);
   2372     debugMonitorExit(threadLock);
   2373     invoker_unlock();
   2374 }
   2375 
   2376 static jvmtiError
   2377 resetHelper(JNIEnv *env, ThreadNode *node, void *arg)
   2378 {
   2379     if (node->toBeResumed) {
   2380         LOG_MISC(("thread=%p resumed", node->thread));
   2381         (void)JVMTI_FUNC_PTR(gdata->jvmti,ResumeThread)(gdata->jvmti, node->thread);
   2382         node->frameGeneration++; /* Increment on each resume */
   2383     }
   2384     stepControl_clearRequest(node->thread, &node->currentStep);
   2385     node->toBeResumed = JNI_FALSE;
   2386     node->suspendCount = 0;
   2387     node->suspendOnStart = JNI_FALSE;
   2388 
   2389     return JVMTI_ERROR_NONE;
   2390 }
   2391 
   2392 void
   2393 threadControl_reset(void)
   2394 {
   2395     JNIEnv *env;
   2396 
   2397     env = getEnv();
   2398     eventHandler_lock(); /* for proper lock order */
   2399     debugMonitorEnter(threadLock);
   2400     (void)enumerateOverThreadList(env, &runningThreads, resetHelper, NULL);
   2401     (void)enumerateOverThreadList(env, &otherThreads, resetHelper, NULL);
   2402 
   2403     removeResumed(env, &otherThreads);
   2404 
   2405     freeDeferredEventModes(env);
   2406 
   2407     suspendAllCount = 0;
   2408 
   2409     /* Everything should have been resumed */
   2410     JDI_ASSERT(otherThreads.first == NULL);
   2411 
   2412     debugMonitorExit(threadLock);
   2413     eventHandler_unlock();
   2414 }
   2415 
   2416 jvmtiEventMode
   2417 threadControl_getInstructionStepMode(jthread thread)
   2418 {
   2419     ThreadNode    *node;
   2420     jvmtiEventMode mode;
   2421 
   2422     mode = JVMTI_DISABLE;
   2423 
   2424     debugMonitorEnter(threadLock);
   2425     node = findThread(&runningThreads, thread);
   2426     if (node != NULL) {
   2427         mode = node->instructionStepMode;
   2428     }
   2429     debugMonitorExit(threadLock);
   2430     return mode;
   2431 }
   2432 
   2433 jvmtiError
   2434 threadControl_setEventMode(jvmtiEventMode mode, EventIndex ei, jthread thread)
   2435 {
   2436     jvmtiError error;
   2437 
   2438     /* Global event */
   2439     if ( thread == NULL ) {
   2440         error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
   2441                     (gdata->jvmti, mode, eventIndex2jvmti(ei), thread);
   2442     } else {
   2443         /* Thread event */
   2444         ThreadNode *node;
   2445 
   2446         debugMonitorEnter(threadLock);
   2447         {
   2448             node = findThread(&runningThreads, thread);
   2449             if ((node == NULL) || (!node->isStarted)) {
   2450                 JNIEnv *env;
   2451 
   2452                 env = getEnv();
   2453                 error = addDeferredEventMode(env, mode, ei, thread);
   2454             } else {
   2455                 error = threadSetEventNotificationMode(node,
   2456                         mode, ei, thread);
   2457             }
   2458         }
   2459         debugMonitorExit(threadLock);
   2460 
   2461     }
   2462     return error;
   2463 }
   2464 
   2465 /*
   2466  * Returns the current thread, if the thread has generated at least
   2467  * one event, and has not generated a thread end event.
   2468  */
   2469 jthread threadControl_currentThread(void)
   2470 {
   2471     jthread thread;
   2472 
   2473     debugMonitorEnter(threadLock);
   2474     {
   2475         ThreadNode *node;
   2476 
   2477         node = findThread(&runningThreads, NULL);
   2478         thread = (node == NULL) ? NULL : node->thread;
   2479     }
   2480     debugMonitorExit(threadLock);
   2481 
   2482     return thread;
   2483 }
   2484 
   2485 jlong
   2486 threadControl_getFrameGeneration(jthread thread)
   2487 {
   2488     jlong frameGeneration = -1;
   2489 
   2490     debugMonitorEnter(threadLock);
   2491     {
   2492         ThreadNode *node;
   2493 
   2494         node = findThread(NULL, thread);
   2495 
   2496         if (node != NULL) {
   2497             frameGeneration = node->frameGeneration;
   2498         }
   2499     }
   2500     debugMonitorExit(threadLock);
   2501 
   2502     return frameGeneration;
   2503 }
   2504