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