< prev index next >

src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c

Print this page


   1 /*
   2  * Copyright (c) 1998, 2017, 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


 251 
 252     chain = getHandlerChain(ei);
 253     node = chain->first;
 254     env = getEnv();
 255 
 256     if ( func == NULL ) {
 257         EXIT_ERROR(AGENT_ERROR_INTERNAL,"iterator function NULL");
 258     }
 259 
 260     while (node != NULL) {
 261         if (((func)(env, node, arg))) {
 262             return JNI_TRUE;
 263         }
 264         node = NEXT(node);
 265     }
 266     return JNI_FALSE;
 267 }
 268 
 269 /* BREAKPOINT, METHOD_ENTRY and SINGLE_STEP events are covered by
 270  * the co-location of events policy. Of these three co-located
 271  * events, METHOD_ENTRY is  always reported first and BREAKPOINT
 272  * is always reported last. Here are the possible combinations and
 273  * their order:
 274  *
 275  * (p1) METHOD_ENTRY, BREAKPOINT (existing)
 276  * (p2) METHOD_ENTRY, BREAKPOINT (new)
 277  * (p1) METHOD_ENTRY, SINGLE_STEP
 278  * (p1) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (existing)
 279  * (p1/p2) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (new)
 280  * (p1) SINGLE_STEP, BREAKPOINT (existing)
 281  * (p2) SINGLE_STEP, BREAKPOINT (new)
 282  *
 283  * BREAKPOINT (existing) indicates a BREAKPOINT that is set before
 284  * the other co-located event is posted. BREAKPOINT (new) indicates
 285  * a BREAKPOINT that is set after the other co-located event is
 286  * posted and before the thread has resumed execution.
 287  *
 288  * Co-location of events policy used to be implemented via
 289  * temporary BREAKPOINTs along with deferring the reporting of
 290  * non-BREAKPOINT co-located events, but the temporary BREAKPOINTs
 291  * caused performance problems on VMs where setting or clearing


 516 
 517     if (eventBag != NULL) {
 518         reportEvents(env, eventSessionID, (jthread)NULL, 0,
 519                             (jclass)NULL, (jmethodID)NULL, 0, eventBag);
 520 
 521         /*
 522          * bag was created locally, destroy it here.
 523          */
 524         bagDestroyBag(eventBag);
 525     }
 526 
 527     jvmtiDeallocate(signature);
 528     jvmtiDeallocate(classname);
 529 
 530     return JNI_TRUE;
 531 }
 532 
 533 /* Garbage Collection Happened */
 534 static unsigned int garbageCollected = 0;
 535 
 536 /* The JVMTI generic event callback. Each event is passed to a sequence of










































































































































 537  * handlers in a chain until the chain ends or one handler
 538  * consumes the event.
 539  */
 540 static void
 541 event_callback(JNIEnv *env, EventInfo *evinfo)
 542 {
 543     struct bag *eventBag;
 544     jbyte eventSessionID = currentSessionID; /* session could change */
 545     jthrowable currentException;
 546     jthread thread;

 547 
 548     LOG_MISC(("event_callback(): ei=%s", eventText(evinfo->ei)));
 549     log_debugee_location("event_callback()", evinfo->thread, evinfo->method, evinfo->location);
 550 
















 551     /* We want to preserve any current exception that might get
 552      * wiped out during event handling (e.g. JNI calls). We have
 553      * to rely on space for the local reference on the current
 554      * frame because doing a PushLocalFrame here might itself
 555      * generate an exception.
 556      */
 557     currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
 558     JNI_FUNC_PTR(env,ExceptionClear)(env);
 559 
 560     /* See if a garbage collection finish event happened earlier.
 561      *
 562      * Note: The "if" is an optimization to avoid entering the lock on every
 563      *       event; garbageCollected may be zapped before we enter
 564      *       the lock but then this just becomes one big no-op.
 565      */
 566     if ( garbageCollected > 0 ) {
 567         struct bag *unloadedSignatures = NULL;
 568 
 569         /* We want to compact the hash table of all
 570          * objects sent to the front end by removing objects that have


 577         debugMonitorEnter(handlerLock);
 578 
 579         /* Clear garbage collection counter */
 580         garbageCollected = 0;
 581 
 582         /* Analyze which class unloads occurred */
 583         unloadedSignatures = classTrack_processUnloads(env);
 584 
 585         debugMonitorExit(handlerLock);
 586 
 587         /* Generate the synthetic class unload events and/or just cleanup.  */
 588         if ( unloadedSignatures != NULL ) {
 589             (void)bagEnumerateOver(unloadedSignatures, synthesizeUnloadEvent,
 590                              (void *)env);
 591             bagDestroyBag(unloadedSignatures);
 592         }
 593     }
 594 
 595     thread = evinfo->thread;
 596     if (thread != NULL) {










 597         /*
 598          * Record the fact that we're entering an event
 599          * handler so that thread operations (status, interrupt,
 600          * stop) can be done correctly and so that thread
 601          * resources can be allocated.  This must be done before
 602          * grabbing any locks.
 603          */
 604         eventBag = threadControl_onEventHandlerEntry(eventSessionID,
 605                                  evinfo->ei, thread, currentException);
 606         if ( eventBag == NULL ) {
 607             jboolean invoking;
 608             do {
 609                 /* The event has been 'handled' and this
 610                  * thread is about to continue, but it may
 611                  * have been started up just to perform a
 612                  * requested method invocation. If so, we do
 613                  * the invoke now and then stop again waiting
 614                  * for another continue. By then another
 615                  * invoke request can be in place, so there is
 616                  * a loop around this code.
 617                  */
 618                 invoking = invoker_doInvoke(thread);
 619                 if (invoking) {
 620                     eventHelper_reportInvokeDone(eventSessionID, thread);
 621                 }
 622             } while (invoking);
 623             return; /* Do nothing, event was consumed */
 624         }
 625     } else {
 626         eventBag = eventHelper_createEventBag();
 627         if (eventBag == NULL) {
 628             /*
 629              * TO DO: Report, but don't die
 630              */
 631             eventBag = NULL;  /* to shut up lint */
 632         }
 633     }
 634 
 635     debugMonitorEnter(handlerLock);
 636     {
 637         HandlerNode *node;
 638         char        *classname;
 639 
 640         /* We must keep track of all classes prepared to know what's unloaded */
 641         if (evinfo->ei == EI_CLASS_PREPARE) {
 642             classTrack_addPreparedClass(env, evinfo->clazz);
 643         }
 644 
 645         node = getHandlerChain(evinfo->ei)->first;
 646         classname = getClassname(evinfo->clazz);
 647 
 648         while (node != NULL) {
 649             /* save next so handlers can remove themselves */
 650             HandlerNode *next = NEXT(node);
 651             jboolean shouldDelete;
 652 
 653             if (eventFilterRestricted_passesFilter(env, classname,
 654                                                    evinfo, node,
 655                                                    &shouldDelete)) {
 656                 HandlerFunction func;
 657 
 658                 func = HANDLER_FUNCTION(node);
 659                 if ( func == NULL ) {
 660                     EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL");
 661                 }
 662                 (*func)(env, evinfo, node, eventBag);
 663             }
 664             if (shouldDelete) {
 665                 /* We can safely free the node now that we are done
 666                  * using it.
 667                  */
 668                 (void)freeHandler(node);
 669             }
 670             node = next;
 671         }
 672         jvmtiDeallocate(classname);
 673     }
 674     debugMonitorExit(handlerLock);
 675 
 676     if (eventBag != NULL) {
 677         reportEvents(env, eventSessionID, thread, evinfo->ei,
 678                 evinfo->clazz, evinfo->method, evinfo->location, eventBag);
 679     }
 680 
 681     /* we are continuing after VMDeathEvent - now we are dead */
 682     if (evinfo->ei == EI_VM_DEATH) {
 683         gdata->vmDead = JNI_TRUE;
 684     }
 685 
 686     /*
 687      * If the bag was created locally, destroy it here.
 688      */
 689     if (thread == NULL) {
 690         bagDestroyBag(eventBag);
 691     }
 692 
 693     /* Always restore any exception that was set beforehand.  If
 694      * there is a pending async exception, StopThread will be
 695      * called from threadControl_onEventHandlerExit immediately
 696      * below.  Depending on VM implementation and state, the async
 697      * exception might immediately overwrite the currentException,
 698      * or it might be delayed until later.  */
 699     if (currentException != NULL) {
 700         JNI_FUNC_PTR(env,Throw)(env, currentException);
 701     } else {
 702         JNI_FUNC_PTR(env,ExceptionClear)(env);
 703     }
 704 
 705     /*
 706      * Release thread resources and perform any delayed operations.
 707      */
 708     if (thread != NULL) {
 709         threadControl_onEventHandlerExit(evinfo->ei, thread, eventBag);
 710     }
 711 }
 712 










 713 /* Returns a local ref to the declaring class for an object. */
 714 static jclass
 715 getObjectClass(jobject object)
 716 {
 717     jclass clazz;
 718     JNIEnv *env = getEnv();
 719 
 720     clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
 721 
 722     return clazz;
 723 }
 724 
 725 /* Returns a local ref to the declaring class for a method, or NULL. */
 726 jclass
 727 getMethodClass(jvmtiEnv *jvmti_env, jmethodID method)
 728 {
 729     jclass clazz = NULL;
 730     jvmtiError error;
 731 
 732     if ( method == NULL ) {


1277         event_callback(env, &info);
1278 
1279         /* Here we unblock all the callbacks and let them return to the
1280          *   VM.  It's not clear this is necessary, but leaving threads
1281          *   blocked doesn't seem like a good idea. They don't have much
1282          *   life left anyway.
1283          */
1284     } debugMonitorExit(callbackBlock);
1285 
1286     /*
1287      * The VM will die soon after the completion of this callback -
1288      * we synchronize with both the command loop and the debug loop
1289      * for a more orderly shutdown.
1290      */
1291     commandLoop_sync();
1292     debugLoop_sync();
1293 
1294     LOG_MISC(("END cbVMDeath"));
1295 }
1296 






















































































































































1297 /**
1298  * Delete this handler (do not delete permanent handlers):
1299  * Deinsert handler from active list,
1300  * make it inactive, and free it's memory
1301  * Assumes handlerLock held.
1302  */
1303 static jvmtiError
1304 freeHandler(HandlerNode *node) {
1305     jvmtiError error = JVMTI_ERROR_NONE;
1306 
1307     /* deinsert the handler node before disableEvents() to make
1308      * sure the event will be disabled when no other event
1309      * handlers are installed.
1310      */
1311     if (node != NULL && (!node->permanent)) {
1312         deinsert(node);
1313         error = eventFilterRestricted_deinstall(node);
1314         jvmtiDeallocate(node);
1315     }
1316 


1465     error = threadControl_setEventMode(JVMTI_ENABLE,
1466                                       EI_THREAD_START, NULL);
1467     if (error != JVMTI_ERROR_NONE) {
1468         EXIT_ERROR(error,"Can't enable thread start events");
1469     }
1470     error = threadControl_setEventMode(JVMTI_ENABLE,
1471                                        EI_THREAD_END, NULL);
1472     if (error != JVMTI_ERROR_NONE) {
1473         EXIT_ERROR(error,"Can't enable thread end events");
1474     }
1475     error = threadControl_setEventMode(JVMTI_ENABLE,
1476                                        EI_CLASS_PREPARE, NULL);
1477     if (error != JVMTI_ERROR_NONE) {
1478         EXIT_ERROR(error,"Can't enable class prepare events");
1479     }
1480     error = threadControl_setEventMode(JVMTI_ENABLE,
1481                                        EI_GC_FINISH, NULL);
1482     if (error != JVMTI_ERROR_NONE) {
1483         EXIT_ERROR(error,"Can't enable garbage collection finish events");
1484     }

































1485 
1486     (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
1487     /* Event callback for JVMTI_EVENT_SINGLE_STEP */
1488     gdata->callbacks.SingleStep                 = &cbSingleStep;
1489     /* Event callback for JVMTI_EVENT_BREAKPOINT */
1490     gdata->callbacks.Breakpoint                 = &cbBreakpoint;
1491     /* Event callback for JVMTI_EVENT_FRAME_POP */
1492     gdata->callbacks.FramePop                   = &cbFramePop;
1493     /* Event callback for JVMTI_EVENT_EXCEPTION */
1494     gdata->callbacks.Exception                  = &cbException;
1495     /* Event callback for JVMTI_EVENT_THREAD_START */
1496     gdata->callbacks.ThreadStart                = &cbThreadStart;
1497     /* Event callback for JVMTI_EVENT_THREAD_END */
1498     gdata->callbacks.ThreadEnd                  = &cbThreadEnd;
1499     /* Event callback for JVMTI_EVENT_CLASS_PREPARE */
1500     gdata->callbacks.ClassPrepare               = &cbClassPrepare;
1501     /* Event callback for JVMTI_EVENT_CLASS_LOAD */
1502     gdata->callbacks.ClassLoad                  = &cbClassLoad;
1503     /* Event callback for JVMTI_EVENT_FIELD_ACCESS */
1504     gdata->callbacks.FieldAccess                = &cbFieldAccess;


1507     /* Event callback for JVMTI_EVENT_EXCEPTION_CATCH */
1508     gdata->callbacks.ExceptionCatch             = &cbExceptionCatch;
1509     /* Event callback for JVMTI_EVENT_METHOD_ENTRY */
1510     gdata->callbacks.MethodEntry                = &cbMethodEntry;
1511     /* Event callback for JVMTI_EVENT_METHOD_EXIT */
1512     gdata->callbacks.MethodExit                 = &cbMethodExit;
1513     /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
1514     gdata->callbacks.MonitorContendedEnter      = &cbMonitorContendedEnter;
1515     /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
1516     gdata->callbacks.MonitorContendedEntered    = &cbMonitorContendedEntered;
1517     /* Event callback for JVMTI_EVENT_MONITOR_WAIT */
1518     gdata->callbacks.MonitorWait                = &cbMonitorWait;
1519     /* Event callback for JVMTI_EVENT_MONITOR_WAITED */
1520     gdata->callbacks.MonitorWaited              = &cbMonitorWaited;
1521     /* Event callback for JVMTI_EVENT_VM_INIT */
1522     gdata->callbacks.VMInit                     = &cbVMInit;
1523     /* Event callback for JVMTI_EVENT_VM_DEATH */
1524     gdata->callbacks.VMDeath                    = &cbVMDeath;
1525     /* Event callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
1526     gdata->callbacks.GarbageCollectionFinish    = &cbGarbageCollectionFinish;












1527 
1528     error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
1529                 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
1530     if (error != JVMTI_ERROR_NONE) {
1531         EXIT_ERROR(error,"Can't set event callbacks");
1532     }
1533 
1534     /* Notify other modules that the event callbacks are in place */
1535     threadControl_onHook();
1536 
1537     /* Get the event helper thread initialized */
1538     eventHelper_initialize(sessionID);
1539 }
1540 
1541 void
1542 eventHandler_reset(jbyte sessionID)
1543 {
1544     int i;
1545 
1546     debugMonitorEnter(handlerLock);


1691                           NULL, NULL, 0, JNI_FALSE);
1692 }
1693 
1694 HandlerNode *
1695 eventHandler_createInternalBreakpoint(HandlerFunction func,
1696                                       jthread thread,
1697                                       jclass clazz,
1698                                       jmethodID method,
1699                                       jlocation location)
1700 {
1701     return createInternal(EI_BREAKPOINT, func, thread,
1702                           clazz, method, location, JNI_FALSE);
1703 }
1704 
1705 jvmtiError
1706 eventHandler_installExternal(HandlerNode *node)
1707 {
1708     return installHandler(node,
1709                           standardHandlers_defaultHandler(node->ei),
1710                           JNI_TRUE);








































1711 }
   1 /*
   2  * Copyright (c) 1998, 2019, 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


 251 
 252     chain = getHandlerChain(ei);
 253     node = chain->first;
 254     env = getEnv();
 255 
 256     if ( func == NULL ) {
 257         EXIT_ERROR(AGENT_ERROR_INTERNAL,"iterator function NULL");
 258     }
 259 
 260     while (node != NULL) {
 261         if (((func)(env, node, arg))) {
 262             return JNI_TRUE;
 263         }
 264         node = NEXT(node);
 265     }
 266     return JNI_FALSE;
 267 }
 268 
 269 /* BREAKPOINT, METHOD_ENTRY and SINGLE_STEP events are covered by
 270  * the co-location of events policy. Of these three co-located
 271  * events, METHOD_ENTRY is always reported first and BREAKPOINT
 272  * is always reported last. Here are the possible combinations and
 273  * their order:
 274  *
 275  * (p1) METHOD_ENTRY, BREAKPOINT (existing)
 276  * (p2) METHOD_ENTRY, BREAKPOINT (new)
 277  * (p1) METHOD_ENTRY, SINGLE_STEP
 278  * (p1) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (existing)
 279  * (p1/p2) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (new)
 280  * (p1) SINGLE_STEP, BREAKPOINT (existing)
 281  * (p2) SINGLE_STEP, BREAKPOINT (new)
 282  *
 283  * BREAKPOINT (existing) indicates a BREAKPOINT that is set before
 284  * the other co-located event is posted. BREAKPOINT (new) indicates
 285  * a BREAKPOINT that is set after the other co-located event is
 286  * posted and before the thread has resumed execution.
 287  *
 288  * Co-location of events policy used to be implemented via
 289  * temporary BREAKPOINTs along with deferring the reporting of
 290  * non-BREAKPOINT co-located events, but the temporary BREAKPOINTs
 291  * caused performance problems on VMs where setting or clearing


 516 
 517     if (eventBag != NULL) {
 518         reportEvents(env, eventSessionID, (jthread)NULL, 0,
 519                             (jclass)NULL, (jmethodID)NULL, 0, eventBag);
 520 
 521         /*
 522          * bag was created locally, destroy it here.
 523          */
 524         bagDestroyBag(eventBag);
 525     }
 526 
 527     jvmtiDeallocate(signature);
 528     jvmtiDeallocate(classname);
 529 
 530     return JNI_TRUE;
 531 }
 532 
 533 /* Garbage Collection Happened */
 534 static unsigned int garbageCollected = 0;
 535 
 536 /*
 537  * Run the event through each HandlerNode's filter, and if it passes, call the HandlerNode's
 538  * HandlerFunction for the event, and then report all accumulated events to the debugger.
 539  */
 540 static void
 541 filterAndHandleEvent(JNIEnv *env, EventInfo *evinfo, EventIndex ei,
 542                      struct bag *eventBag, jbyte eventSessionID)
 543 {
 544     debugMonitorEnter(handlerLock);
 545     {
 546         HandlerNode *node;
 547         char        *classname;
 548 
 549         /* We must keep track of all classes prepared to know what's unloaded */
 550         if (evinfo->ei == EI_CLASS_PREPARE) {
 551             classTrack_addPreparedClass(env, evinfo->clazz);
 552         }
 553 
 554         node = getHandlerChain(ei)->first;
 555         classname = getClassname(evinfo->clazz);
 556 
 557         /* Filter the event over each handler node. */
 558         while (node != NULL) {
 559             /* Save next so handlers can remove themselves. */
 560             HandlerNode *next = NEXT(node);
 561             jboolean shouldDelete;
 562 
 563             /* passesFilter() will set evinfo->matchesFiber true if appropriate. */
 564             if (eventFilterRestricted_passesFilter(env, classname,
 565                                                    evinfo, node,
 566                                                    &shouldDelete, JNI_FALSE /* filterOnly */)) {
 567                 HandlerFunction func = HANDLER_FUNCTION(node);
 568                 if (func == NULL) {
 569                     EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL");
 570                 }
 571                 /* Handle the event by calling the event handler. */
 572                 (*func)(env, evinfo, node, eventBag);
 573             }
 574             if (shouldDelete) {
 575                 /* We can safely free the node now that we are done using it. */
 576                 (void)freeHandler(node);
 577             }
 578             node = next;
 579         }
 580         jvmtiDeallocate(classname);
 581     }
 582     debugMonitorExit(handlerLock);
 583 
 584     /*
 585      * The events destined for the debugger were accumulated in eventBag. Report all these events.
 586      */
 587     if (eventBag != NULL) {
 588         reportEvents(env, eventSessionID, evinfo->thread, evinfo->ei,
 589                      evinfo->clazz, evinfo->method, evinfo->location, eventBag);
 590     }
 591 }
 592 
 593 /*
 594  * Called when we are not notifying the debugging of all fibers, and we are seeing an event
 595  * on a fiber that we have not notified the debugger about yet. If the event passes the event
 596  * filters, then we will notify the debugger with a THREAD_START and add it to our list of
 597  * fibers. Otherwise we ignore it.
 598  */
 599 static void
 600 filterAndAddFiber(JNIEnv *env, EventInfo *evinfo, EventIndex ei, jbyte eventSessionID,
 601                   jthread thread, jthread fiber)
 602 {
 603     jboolean needToAddFiber = JNI_FALSE; /* Assume we won't need to add the fiber. */;
 604 
 605     /*
 606      * Although we have received a JVMTI event for a fiber that we have not added yet,
 607      * we only need to add it if we are going to pass the fiber on to the debugger. This
 608      * might not end up happening due to event filtering. For example, we got a breakpoint
 609      * on a carrier thread running a fiber, but the breakpoint HandlerNode specifies that
 610      * event must be on a certain thread, so the event may end up being dropped. Therefore
 611      * we need to do a dry run with the filtering to see if we really need to add this fiber.
 612      */
 613     {
 614         HandlerNode *node = getHandlerChain(ei)->first;
 615         char        *classname  = getClassname(evinfo->clazz);
 616 
 617         debugMonitorEnter(handlerLock);
 618 
 619         /* Filter the event over each handler node. */
 620         while (node != NULL) {
 621             /* Save next so handlers can remove themselves */
 622             HandlerNode *next = NEXT(node);
 623             jboolean shouldDelete;
 624 
 625             /* passesFilter() will set evinfo->matchesFiber true if appropriate. */
 626             if (eventFilterRestricted_passesFilter(env, classname,
 627                                                    evinfo, node,
 628                                                    &shouldDelete, JNI_TRUE /* filterOnly */)) {
 629                 if (evinfo->matchesFiber) {
 630                     /* If we match even one filter and it matches on the fiber, then we need
 631                      * to add the fiber. */
 632                     needToAddFiber = JNI_TRUE;
 633                     break;
 634                 }
 635             }
 636             JDI_ASSERT(!shouldDelete);
 637             node = next;
 638         }
 639 
 640         debugMonitorExit(handlerLock);
 641         jvmtiDeallocate(classname);
 642     }
 643 
 644     if (needToAddFiber) {
 645         /* Make sure this fiber gets added to the fibers list. */
 646         threadControl_addFiber(fiber);
 647 
 648         /*
 649          * When the FIBER_SCHEDULED event arrived for this fiber, we ignored it since we don't
 650          * want to notify the debugger about fibers until there is a non-fiber event that
 651          * arrives on it (like a breakpoint). Now that this has happened, we need to send
 652          * a FIBER_SCHEDULED event (which will be converted into a THREAD_START event) so
 653          * the debugger will know about the fiber. Otherwise it will be unhappy when it gets
 654          * an event for a fiber that it never got a THREAD_START event for.
 655          */
 656         EventInfo info;
 657         struct bag *eventBag = eventHelper_createEventBag();
 658 
 659         JDI_ASSERT(evinfo->fiber != NULL);
 660         (void)memset(&info,0,sizeof(info));
 661         info.ei         = EI_FIBER_SCHEDULED;
 662         info.thread     = thread;
 663         info.fiber      = fiber;
 664         info.matchesFiber = JNI_TRUE;
 665 
 666         /* Note: filterAndHandleEvent() expects EI_THREAD_START instead of EI_FIBER_SCHEDULED. */
 667         filterAndHandleEvent(env, &info, EI_THREAD_START, eventBag, eventSessionID);
 668         JDI_ASSERT(bagSize(eventBag) == 0);
 669         bagDestroyBag(eventBag);
 670     }
 671 }
 672 
 673 /*
 674  * The JVMTI generic event callback. Each event is passed to a sequence of
 675  * handlers in a chain until the chain ends or one handler
 676  * consumes the event.
 677  */
 678 static void
 679 event_callback_helper(JNIEnv *env, EventInfo *evinfo)
 680 {
 681     struct bag *eventBag;
 682     jbyte eventSessionID = currentSessionID; /* session could change */
 683     jthrowable currentException;
 684     jthread thread;
 685     EventIndex ei = evinfo->ei;
 686 
 687     LOG_MISC(("event_callback(): ei=%s", eventText(ei)));
 688     log_debugee_location("event_callback()", evinfo->thread, evinfo->method, evinfo->location);
 689 
 690     if (evinfo->thread != NULL) {
 691         /* fiber fixme: ignore all events on the fiber helper thread. Remove this when
 692          * the need for helper threads goes away.
 693          */
 694         jclass threadClass = JNI_FUNC_PTR(env, GetObjectClass)(env, evinfo->thread);
 695         if (JNI_FUNC_PTR(env, IsSameObject)(env, threadClass, gdata->innocuousThreadClass)) {
 696             return;
 697         }
 698     }
 699 
 700     /* fiber fixme: little hack to ignore THREAD_START events while we are creating a fiber
 701      * helper thread. The need for this will eventually go away. */
 702     if (gdata->ignoreEvents) {
 703         return;
 704     }
 705 
 706     /* We want to preserve any current exception that might get
 707      * wiped out during event handling (e.g. JNI calls). We have
 708      * to rely on space for the local reference on the current
 709      * frame because doing a PushLocalFrame here might itself
 710      * generate an exception.
 711      */
 712     currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
 713     JNI_FUNC_PTR(env,ExceptionClear)(env);
 714 
 715     /* See if a garbage collection finish event happened earlier.
 716      *
 717      * Note: The "if" is an optimization to avoid entering the lock on every
 718      *       event; garbageCollected may be zapped before we enter
 719      *       the lock but then this just becomes one big no-op.
 720      */
 721     if ( garbageCollected > 0 ) {
 722         struct bag *unloadedSignatures = NULL;
 723 
 724         /* We want to compact the hash table of all
 725          * objects sent to the front end by removing objects that have


 732         debugMonitorEnter(handlerLock);
 733 
 734         /* Clear garbage collection counter */
 735         garbageCollected = 0;
 736 
 737         /* Analyze which class unloads occurred */
 738         unloadedSignatures = classTrack_processUnloads(env);
 739 
 740         debugMonitorExit(handlerLock);
 741 
 742         /* Generate the synthetic class unload events and/or just cleanup.  */
 743         if ( unloadedSignatures != NULL ) {
 744             (void)bagEnumerateOver(unloadedSignatures, synthesizeUnloadEvent,
 745                              (void *)env);
 746             bagDestroyBag(unloadedSignatures);
 747         }
 748     }
 749 
 750     thread = evinfo->thread;
 751     if (thread != NULL) {
 752         if (gdata->fibersSupported) {
 753             /*
 754              * Get the event fiber if one is running on this thread and has not already
 755              * been set, which is the case for fiber related JVMTI events.
 756              */
 757             if (evinfo->fiber == NULL) {
 758                 evinfo->fiber = getThreadFiber(thread);
 759             }
 760         }
 761 
 762         /*
 763          * Record the fact that we're entering an event
 764          * handler so that thread operations (status, interrupt,
 765          * stop) can be done correctly and so that thread
 766          * resources can be allocated.  This must be done before
 767          * grabbing any locks.
 768          */
 769         eventBag = threadControl_onEventHandlerEntry(
 770             eventSessionID, evinfo, currentException);
 771         if ( eventBag == NULL ) {
 772             jboolean invoking;
 773             do {
 774                 /* The event has been 'handled' and this
 775                  * thread is about to continue, but it may
 776                  * have been started up just to perform a
 777                  * requested method invocation. If so, we do
 778                  * the invoke now and then stop again waiting
 779                  * for another continue. By then another
 780                  * invoke request can be in place, so there is
 781                  * a loop around this code.
 782                  */
 783                 invoking = invoker_doInvoke(thread);
 784                 if (invoking) {
 785                     eventHelper_reportInvokeDone(eventSessionID, thread);
 786                 }
 787             } while (invoking);
 788             return; /* Do nothing, event was consumed */
 789         }
 790     } else {
 791         eventBag = eventHelper_createEventBag();
 792         if (eventBag == NULL) {
 793             /*
 794              * TO DO: Report, but don't die
 795              */
 796             eventBag = NULL;  /* to shut up lint */
 797         }
 798     }
 799 
 800     /* We want the fiber scheduled/terminated events to mimic thread start/end events */
 801     if (ei == EI_FIBER_SCHEDULED) {
 802         ei = EI_THREAD_START;
 803     }
 804     if (ei == EI_FIBER_TERMINATED) {
 805         ei = EI_THREAD_END;
 806     }
 807 
 808     if (gdata->fibersSupported) {
 809         /* Add the fiber if we haven't added it before. */
 810         if (evinfo->fiber != NULL && !threadControl_isKnownFiber(evinfo->fiber)) {
 811             if (gdata->notifyDebuggerOfAllFibers) {
 812                 /* Make sure this fiber gets added to the fibers list. */
 813                 threadControl_addFiber(evinfo->fiber);
 814             } else {
 815                 /* Add this fiber if it passes the event filters. */
 816                 filterAndAddFiber(env, evinfo, ei, eventSessionID, thread, evinfo->fiber);

















 817             }

 818         }

 819     }

 820 
 821     filterAndHandleEvent(env, evinfo, ei, eventBag, eventSessionID);



 822 
 823     /* we are continuing after VMDeathEvent - now we are dead */
 824     if (evinfo->ei == EI_VM_DEATH) {
 825         gdata->vmDead = JNI_TRUE;
 826     }
 827 
 828     /*
 829      * If the bag was created locally, destroy it here.
 830      */
 831     if (thread == NULL) {
 832         bagDestroyBag(eventBag);
 833     }
 834 
 835     /* Always restore any exception that was set beforehand.  If
 836      * there is a pending async exception, StopThread will be
 837      * called from threadControl_onEventHandlerExit immediately
 838      * below.  Depending on VM implementation and state, the async
 839      * exception might immediately overwrite the currentException,
 840      * or it might be delayed until later.  */
 841     if (currentException != NULL) {
 842         JNI_FUNC_PTR(env,Throw)(env, currentException);
 843     } else {
 844         JNI_FUNC_PTR(env,ExceptionClear)(env);
 845     }
 846 
 847     /*
 848      * Release thread resources and perform any delayed operations.
 849      */
 850     if (thread != NULL) {
 851         threadControl_onEventHandlerExit(evinfo->ei, thread, eventBag);
 852     }
 853 }
 854 
 855 static void
 856 event_callback(JNIEnv *env, EventInfo *evinfo)
 857 {
 858     /* fiber fixme: There are a bunch of WITH_LOCAL_REFS that we can remove now that
 859      * we are doing one here. */
 860     WITH_LOCAL_REFS(env, 64) {
 861         event_callback_helper(env, evinfo);
 862     } END_WITH_LOCAL_REFS(env);
 863 }
 864 
 865 /* Returns a local ref to the declaring class for an object. */
 866 static jclass
 867 getObjectClass(jobject object)
 868 {
 869     jclass clazz;
 870     JNIEnv *env = getEnv();
 871 
 872     clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
 873 
 874     return clazz;
 875 }
 876 
 877 /* Returns a local ref to the declaring class for a method, or NULL. */
 878 jclass
 879 getMethodClass(jvmtiEnv *jvmti_env, jmethodID method)
 880 {
 881     jclass clazz = NULL;
 882     jvmtiError error;
 883 
 884     if ( method == NULL ) {


1429         event_callback(env, &info);
1430 
1431         /* Here we unblock all the callbacks and let them return to the
1432          *   VM.  It's not clear this is necessary, but leaving threads
1433          *   blocked doesn't seem like a good idea. They don't have much
1434          *   life left anyway.
1435          */
1436     } debugMonitorExit(callbackBlock);
1437 
1438     /*
1439      * The VM will die soon after the completion of this callback -
1440      * we synchronize with both the command loop and the debug loop
1441      * for a more orderly shutdown.
1442      */
1443     commandLoop_sync();
1444     debugLoop_sync();
1445 
1446     LOG_MISC(("END cbVMDeath"));
1447 }
1448 
1449 /* Event callback for JVMTI_EVENT_FIBER_SCHEDULED */
1450 static void JNICALL
1451 cbFiberScheduled(jvmtiEnv *jvmti_env, JNIEnv *env,
1452                  jthread thread, jthread fiber)
1453 {
1454     EventInfo info;
1455 
1456     LOG_CB(("cbFiberScheduled: thread=%p", thread));
1457     /*tty_message("cbFiberScheduled: thread=%p", thread);*/
1458     JDI_ASSERT(gdata->fibersSupported);
1459 
1460     /*
1461      * Now would be a good time to cache the ThreadGroup for fibers (carrier threads)
1462      * if we haven't already.
1463      *
1464      * fiber fixme: the is kind of a hack. What happens if custom
1465      * scheduler uses carrier threads in multple group? What if as a result of this a
1466      * Fiber can move between thread groups? We should have a dedicated
1467      * thread group for all fibers, or allow a fiber to set its ThreadGroup.
1468      */
1469     if (gdata->fiberThreadGroup == NULL) {
1470         jvmtiThreadInfo info;
1471         jvmtiError error;
1472 
1473         (void)memset(&info, 0, sizeof(info));
1474         error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
1475             (gdata->jvmti, thread, &info);
1476 
1477         if (error != JVMTI_ERROR_NONE) {
1478             EXIT_ERROR(error, "could not get fiber ThreadGroup");
1479         } else {
1480             debugMonitorEnter(callbackBlock); /* fiber fixme: any monitor will do, but there probably is a better choice. */
1481             /* Make sure there wasn't a race before setting. saveGlobalRef() will assert if the
1482              * target is not NULL. */
1483             if (gdata->fiberThreadGroup == NULL) {
1484                 saveGlobalRef(env, info.thread_group, &gdata->fiberThreadGroup);
1485             }
1486             debugMonitorExit(callbackBlock);
1487         }
1488     }
1489 
1490     /* Ignore FIBER_SCHEDULED events unless we are notifying the debugger of all fibers. */
1491     if (!gdata->notifyDebuggerOfAllFibers) {
1492         return;
1493     }
1494 
1495     BEGIN_CALLBACK() {
1496         (void)memset(&info,0,sizeof(info));
1497         info.ei         = EI_FIBER_SCHEDULED;
1498         info.thread     = thread;
1499         info.fiber      = fiber;
1500         event_callback(env, &info);
1501     } END_CALLBACK();
1502 
1503     LOG_MISC(("END cbFiberScheduled"));
1504 }
1505 
1506 /* Event callback for JVMTI_EVENT_FIBER_TERMINATED */
1507 static void JNICALL
1508 cbFiberTerminated(jvmtiEnv *jvmti_env, JNIEnv *env,
1509                   jthread thread, jthread fiber)
1510 {
1511     EventInfo info;
1512 
1513     LOG_CB(("cbFiberTerminated: thread=%p", thread));
1514     /*tty_message("cbFiberTerminated: thread=%p", thread);*/
1515     JDI_ASSERT(gdata->fibersSupported);
1516 
1517     if (!gdata->notifyDebuggerOfAllFibers && !threadControl_isKnownFiber(fiber)) {
1518         /* This is not a fiber we are tracking, so don't deliver a FIBER_TERMINATED event for it. */
1519         return;
1520     }
1521 
1522     BEGIN_CALLBACK() {
1523         (void)memset(&info,0,sizeof(info));
1524         info.ei         = EI_FIBER_TERMINATED;
1525         info.thread     = thread;
1526         info.fiber      = fiber;
1527         event_callback(env, &info);
1528     } END_CALLBACK();
1529 
1530     LOG_MISC(("END cbFiberTerminated"));
1531 }
1532 
1533 /* Event callback for JVMTI_EVENT_FIBER_MOUNT */
1534 static void JNICALL
1535 cbFiberMount(jvmtiEnv *jvmti_env, JNIEnv *env,
1536              jthread thread, jthread fiber)
1537 {
1538     LOG_CB(("cbFiberMount: thread=%p", thread));
1539     /*tty_message("cbFiberMount: thread=%p", thread);*/
1540     JDI_ASSERT(gdata->fibersSupported);
1541 
1542     /* Ignore FIBER_MOUNT events unless we are doing fiber debugging. */
1543     if (!gdata->fibersSupported) {
1544         return;
1545     }
1546 
1547     threadControl_mountFiber(fiber, thread, currentSessionID);
1548 
1549     LOG_MISC(("END cbFiberMount"));
1550 }
1551 
1552 /* Event callback for JVMTI_EVENT_FIBER_UNMOUNT */
1553 static void JNICALL
1554 cbFiberUnmount(jvmtiEnv *jvmti_env, JNIEnv *env,
1555                jthread thread, jthread fiber)
1556 {
1557     LOG_CB(("cbFiberUnmount: thread=%p", thread));
1558     /*tty_message("cbFiberUnmount: thread=%p", thread);*/
1559     JDI_ASSERT(gdata->fibersSupported);
1560 
1561     /* Ignore FIBER_UNMOUNT events unless we are doing fiber debugging. */
1562     if (!gdata->fibersSupported) {
1563         return;
1564     }
1565 
1566     threadControl_unmountFiber(fiber, thread);
1567 
1568     LOG_MISC(("END cbFiberUnmount"));
1569 }
1570 
1571 /* Event callback for JVMTI_EVENT_CONTINUATION_RUN */
1572 static void JNICALL
1573 cbContinuationRun(jvmtiEnv *jvmti_env, JNIEnv *env,
1574                   jthread thread, jint continuation_frame_count)
1575 {
1576     LOG_CB(("cbContinuationRun: thread=%p", thread));
1577     //tty_message("cbContinuationRun: thread=%p continuation_frame_count=%d", thread, continuation_frame_count);
1578     JDI_ASSERT(gdata->fibersSupported);
1579 
1580     threadControl_continuationRun(thread, continuation_frame_count);
1581 
1582     LOG_MISC(("END cbContinuationRun"));
1583 }
1584 
1585 /* Event callback for JVMTI_EVENT_CONTINUATION_YIELD */
1586 static void JNICALL
1587 cbContinuationYield(jvmtiEnv *jvmti_env, JNIEnv *env,
1588                     jthread thread, jint continuation_frame_count)
1589 {
1590     LOG_CB(("cbContinuationYield: thread=%p", thread));
1591     //tty_message("cbContinuationYield: thread=%p continuation_frame_count=%d", thread, continuation_frame_count);
1592     JDI_ASSERT(gdata->fibersSupported);
1593 
1594     threadControl_continuationYield(thread, continuation_frame_count);
1595 
1596     LOG_MISC(("END cbContinuationYield"));
1597 }
1598 
1599 /**
1600  * Delete this handler (do not delete permanent handlers):
1601  * Deinsert handler from active list,
1602  * make it inactive, and free it's memory
1603  * Assumes handlerLock held.
1604  */
1605 static jvmtiError
1606 freeHandler(HandlerNode *node) {
1607     jvmtiError error = JVMTI_ERROR_NONE;
1608 
1609     /* deinsert the handler node before disableEvents() to make
1610      * sure the event will be disabled when no other event
1611      * handlers are installed.
1612      */
1613     if (node != NULL && (!node->permanent)) {
1614         deinsert(node);
1615         error = eventFilterRestricted_deinstall(node);
1616         jvmtiDeallocate(node);
1617     }
1618 


1767     error = threadControl_setEventMode(JVMTI_ENABLE,
1768                                       EI_THREAD_START, NULL);
1769     if (error != JVMTI_ERROR_NONE) {
1770         EXIT_ERROR(error,"Can't enable thread start events");
1771     }
1772     error = threadControl_setEventMode(JVMTI_ENABLE,
1773                                        EI_THREAD_END, NULL);
1774     if (error != JVMTI_ERROR_NONE) {
1775         EXIT_ERROR(error,"Can't enable thread end events");
1776     }
1777     error = threadControl_setEventMode(JVMTI_ENABLE,
1778                                        EI_CLASS_PREPARE, NULL);
1779     if (error != JVMTI_ERROR_NONE) {
1780         EXIT_ERROR(error,"Can't enable class prepare events");
1781     }
1782     error = threadControl_setEventMode(JVMTI_ENABLE,
1783                                        EI_GC_FINISH, NULL);
1784     if (error != JVMTI_ERROR_NONE) {
1785         EXIT_ERROR(error,"Can't enable garbage collection finish events");
1786     }
1787     /* Only enable fiber events if fiber support is enabled. */
1788     if (gdata->fibersSupported) {
1789         error = threadControl_setEventMode(JVMTI_ENABLE,
1790                                            EI_FIBER_SCHEDULED, NULL);
1791         if (error != JVMTI_ERROR_NONE) {
1792             EXIT_ERROR(error,"Can't enable fiber scheduled events");
1793         }
1794         error = threadControl_setEventMode(JVMTI_ENABLE,
1795                                            EI_FIBER_TERMINATED, NULL);
1796         if (error != JVMTI_ERROR_NONE) {
1797             EXIT_ERROR(error,"Can't enable fiber terminated events");
1798         }
1799         error = threadControl_setEventMode(JVMTI_ENABLE,
1800                                            EI_FIBER_MOUNT, NULL);
1801         if (error != JVMTI_ERROR_NONE) {
1802             EXIT_ERROR(error,"Can't enable fiber mount events");
1803         }
1804         error = threadControl_setEventMode(JVMTI_ENABLE,
1805                                            EI_FIBER_UNMOUNT, NULL);
1806         if (error != JVMTI_ERROR_NONE) {
1807             EXIT_ERROR(error,"Can't enable fiber unmount events");
1808         }
1809         error = threadControl_setEventMode(JVMTI_ENABLE,
1810                                            EI_CONTINUATION_RUN, NULL);
1811         if (error != JVMTI_ERROR_NONE) {
1812             EXIT_ERROR(error,"Can't enable continuation run events");
1813         }
1814         error = threadControl_setEventMode(JVMTI_ENABLE,
1815                                            EI_CONTINUATION_YIELD, NULL);
1816         if (error != JVMTI_ERROR_NONE) {
1817             EXIT_ERROR(error,"Can't enable continuation yield events");
1818         }
1819     }
1820 
1821     (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
1822     /* Event callback for JVMTI_EVENT_SINGLE_STEP */
1823     gdata->callbacks.SingleStep                 = &cbSingleStep;
1824     /* Event callback for JVMTI_EVENT_BREAKPOINT */
1825     gdata->callbacks.Breakpoint                 = &cbBreakpoint;
1826     /* Event callback for JVMTI_EVENT_FRAME_POP */
1827     gdata->callbacks.FramePop                   = &cbFramePop;
1828     /* Event callback for JVMTI_EVENT_EXCEPTION */
1829     gdata->callbacks.Exception                  = &cbException;
1830     /* Event callback for JVMTI_EVENT_THREAD_START */
1831     gdata->callbacks.ThreadStart                = &cbThreadStart;
1832     /* Event callback for JVMTI_EVENT_THREAD_END */
1833     gdata->callbacks.ThreadEnd                  = &cbThreadEnd;
1834     /* Event callback for JVMTI_EVENT_CLASS_PREPARE */
1835     gdata->callbacks.ClassPrepare               = &cbClassPrepare;
1836     /* Event callback for JVMTI_EVENT_CLASS_LOAD */
1837     gdata->callbacks.ClassLoad                  = &cbClassLoad;
1838     /* Event callback for JVMTI_EVENT_FIELD_ACCESS */
1839     gdata->callbacks.FieldAccess                = &cbFieldAccess;


1842     /* Event callback for JVMTI_EVENT_EXCEPTION_CATCH */
1843     gdata->callbacks.ExceptionCatch             = &cbExceptionCatch;
1844     /* Event callback for JVMTI_EVENT_METHOD_ENTRY */
1845     gdata->callbacks.MethodEntry                = &cbMethodEntry;
1846     /* Event callback for JVMTI_EVENT_METHOD_EXIT */
1847     gdata->callbacks.MethodExit                 = &cbMethodExit;
1848     /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
1849     gdata->callbacks.MonitorContendedEnter      = &cbMonitorContendedEnter;
1850     /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
1851     gdata->callbacks.MonitorContendedEntered    = &cbMonitorContendedEntered;
1852     /* Event callback for JVMTI_EVENT_MONITOR_WAIT */
1853     gdata->callbacks.MonitorWait                = &cbMonitorWait;
1854     /* Event callback for JVMTI_EVENT_MONITOR_WAITED */
1855     gdata->callbacks.MonitorWaited              = &cbMonitorWaited;
1856     /* Event callback for JVMTI_EVENT_VM_INIT */
1857     gdata->callbacks.VMInit                     = &cbVMInit;
1858     /* Event callback for JVMTI_EVENT_VM_DEATH */
1859     gdata->callbacks.VMDeath                    = &cbVMDeath;
1860     /* Event callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
1861     gdata->callbacks.GarbageCollectionFinish    = &cbGarbageCollectionFinish;
1862     /* Event callback for JVMTI_EVENT_FIBER_SCHEDULED */
1863     gdata->callbacks.FiberScheduled             = &cbFiberScheduled;
1864     /* Event callback for JVMTI_EVENT_FIBER_TERMINATED */
1865     gdata->callbacks.FiberTerminated            = &cbFiberTerminated;
1866     /* Event callback for JVMTI_EVENT_FIBER_MOUNT */
1867     gdata->callbacks.FiberMount                 = &cbFiberMount;
1868     /* Event callback for JVMTI_EVENT_FIBER_UNMOUNT */
1869     gdata->callbacks.FiberUnmount               = &cbFiberUnmount;
1870     /* Event callback for JVMTI_EVENT_CONTINUATION_RUN */
1871     gdata->callbacks.ContinuationRun            = &cbContinuationRun;
1872     /* Event callback for JVMTI_EVENT_CONTINUATION_YIELD */
1873     gdata->callbacks.ContinuationYield          = &cbContinuationYield;
1874 
1875     error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
1876                 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
1877     if (error != JVMTI_ERROR_NONE) {
1878         EXIT_ERROR(error,"Can't set event callbacks");
1879     }
1880 
1881     /* Notify other modules that the event callbacks are in place */
1882     threadControl_onHook();
1883 
1884     /* Get the event helper thread initialized */
1885     eventHelper_initialize(sessionID);
1886 }
1887 
1888 void
1889 eventHandler_reset(jbyte sessionID)
1890 {
1891     int i;
1892 
1893     debugMonitorEnter(handlerLock);


2038                           NULL, NULL, 0, JNI_FALSE);
2039 }
2040 
2041 HandlerNode *
2042 eventHandler_createInternalBreakpoint(HandlerFunction func,
2043                                       jthread thread,
2044                                       jclass clazz,
2045                                       jmethodID method,
2046                                       jlocation location)
2047 {
2048     return createInternal(EI_BREAKPOINT, func, thread,
2049                           clazz, method, location, JNI_FALSE);
2050 }
2051 
2052 jvmtiError
2053 eventHandler_installExternal(HandlerNode *node)
2054 {
2055     return installHandler(node,
2056                           standardHandlers_defaultHandler(node->ei),
2057                           JNI_TRUE);
2058 }
2059 
2060 /***** debugging *****/
2061 
2062 void
2063 eventHandler_dumpAllHandlers(jboolean dumpPermanent)
2064 {
2065     int ei;
2066     for (ei = EI_min; ei <= EI_max; ++ei) {
2067         eventHandler_dumpHandlers(ei, dumpPermanent);
2068     }
2069 }
2070 
2071 void
2072 eventHandler_dumpHandlers(EventIndex ei, jboolean dumpPermanent)
2073 {
2074   HandlerNode *nextNode;
2075   nextNode = getHandlerChain(ei)->first;
2076   if (nextNode != NULL) {
2077       tty_message("\nHandlers for %s(%d)", eventIndex2EventName(ei), ei);
2078       while (nextNode != NULL) {
2079           HandlerNode *node = nextNode;
2080           nextNode = NEXT(node);
2081           
2082           if (node->permanent && !dumpPermanent) {
2083               continue; // ignore permanent handlers
2084           }
2085 
2086           tty_message("node(%p) handlerID(%d) suspendPolicy(%d) permanent(%d)",
2087                       node, node->handlerID, node->suspendPolicy, node->permanent);
2088           eventFilter_dumpHandlerFilters(node);
2089       }
2090   }
2091 }
2092 
2093 void
2094 eventHandler_dumpHandler(HandlerNode *node)
2095 {
2096   tty_message("Handler for %s(%d)\n", eventIndex2EventName(node->ei), node->ei);
2097   eventFilter_dumpHandlerFilters(node);
2098 }
< prev index next >