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](https://bugs.openjdk.org/browse/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.

-------------

Commit messages:
 - debug agent class tracking should not piggy back on the cbClassPrepare() 
callback

Changes: https://git.openjdk.org/jdk/pull/10776/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=10776&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8295375
  Stats: 52 lines in 4 files changed: 28 ins; 19 del; 5 mod
  Patch: https://git.openjdk.org/jdk/pull/10776.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/10776/head:pull/10776

PR: https://git.openjdk.org/jdk/pull/10776

Reply via email to