Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8295375

debug agent class tracking should not piggy back on the cbClassPrepare() callback



    • Enhancement
    • Resolution: Fixed
    • P4
    • 20
    • 20
    • core-svc
    • b21


      The debug agent needs to keep track of all loaded classes, and also be notified when they are unloaded. It tracks classes loading by getting CLASS_PREPARE events and it tracks their unloading by tagging them, which triggers OBJECT_FREE events when they are unloaded. The tagging and OBJECT_FREE events are handled by a separate JVMTIEnv from the one that does main event handling, mostly in support of the attached debugger. However, the CLASS_PREPARE events are piggy backed on the main event handler. As a result, we have this special check in filterAndHandleEvent():

              /* We must keep track of all classes prepared to know what's unloaded */
              if (evinfo->ei == EI_CLASS_PREPARE) {
                  classTrack_addPreparedClass(env, evinfo->clazz);

      We also have to always keep CLASS_PREPARE events enabled on the main event handler, even if the debugger is not requesting them. The main event handler has a lot of overhead that isn't necessary when simply wanting to use the CLASS_PREPARE event for class tracking.

      Another downside of this piggy backing is it causes problems for addressing JDK-8295376, which is attempting to not track virtual threads when the debugger is not attached (no VIRTUAL_THREAD_START and VIRTUAL_THREAD_END events). The problem is when the debugger is not attached and a CLASS_PREPARE event comes in on a virtual thread, the debug agent unnecessarily creates a ThreadNode for it. Since there won't be a corresponding VIRTUAL_THREAD_END event when the virtual thread is destroyed (as long as the debugger is not attached), the debug agent ends up keeping this ThreadNode around even after the thread is gone. This usually eventually leads to an assert.

      The fix for this is pretty simple. We already have the separate JVMTIEnv that the class tracker uses to handle OBJECT_FREE. This is easily purposed to also handle CLASS_PREPARE events. By doing so we can get rid of the special CLASS_PREPARE code above in filterAndHandleEvent(), and we also only need to enable CLASS_PREPARE events for the main event handler when a debugger is attached and is requesting them.


        Issue Links



              cjplummer Chris Plummer
              cjplummer Chris Plummer
              0 Vote for this issue
              3 Start watching this issue