> The segv/eav happens in the case if JvmtiBreakpoint::_method's class > redefined old between getting the Method* from jmethodid in the > JvmtiEnv::SetBreakpoint(Method* method, jlocation location) {..} and > and actual setting breakpoint in the VM operation VM_ChangeBreakpoints. > > Here are details: > The breakpoint is set in 2 steps. > 1) method jvmti_SetBreakpoint(jvmtiEnv* env, jmethodID method, jlocation > location) convert jmethodID to Method* and call > JvmtiEnv::SetBreakpoint(Method* method, jlocation location) > where > JvmtiBreakpoint bp(method, location); > is created with this Method* > Note: it is done while thread is in VM state, so Method can't become is_old > while this is done. > > 2) The VMOp is used to add breakpoint into the list > VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, > &bp); > VMThread::execute(&set_breakpoint); > to call JvmtiBreakpoints::set_at_safepoint() > that can modify JvmtiBreakpoints list and set breakpoint in safepoint without > synchronization. > > So it might be possible that class redefinition VM_RedefineClasses > operation that redefine the class with this breakpoint happens between steps > 1) and 2) > VM_RedefineClasses::redefine_single_class() > clear all class-related breakpoints in the JvmtiBreakpoints, however the > "problematic" breakpoint is in VMThread queue and thus we are still continue > to do this operation. > So in the step 2) the the JvmtiBreakpoint with 'is_old' method is added to > the JvmtiBreakpoints and breakpoint is set. > > Then old method mights be purged any time once they are not on the stack and > any access to this breakpoint could lead to usage of Metthod* _method > pointing to deallocated metaspace. > > The VM_RedefineClasses clear all breakpoints so it is correct just to don't > proceed with current breakpoint also. > > Looks, like very unlikely but reproducing with stress test after some time. > Verified that the crash is not reproduced anymore with corresponding test > after the fix. > > Many thanks to Coleen for detailed explanation of class redefinition.
Leonid Mesnik has updated the pull request incrementally with two additional commits since the last revision: - Update src/hotspot/share/prims/jvmtiImpl.cpp Co-authored-by: Coleen Phillimore <coleen.phillim...@oracle.com> - Update src/hotspot/share/prims/jvmtiImpl.cpp Co-authored-by: Coleen Phillimore <coleen.phillim...@oracle.com> ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26031/files - new: https://git.openjdk.org/jdk/pull/26031/files/c7aaa804..242880c5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26031&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26031&range=02-03 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/26031.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26031/head:pull/26031 PR: https://git.openjdk.org/jdk/pull/26031