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