A stress test which repeatedly sets and unsets event callbacks while another thread is single stepping
hits the guarantee in make_walkable below:
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
if (walkable()) return;
// Eventually make an assert
guarantee(Thread::current() == (Thread*)thread, "only current thread can flush its registers");
// We always flush in case the profiler wants it but we won't mark
// the windows as flushed unless we have a last_Java_frame
intptr_t* sp = StubRoutines::sparc::flush_callers_register_windows_func()();
if (last_Java_sp() != NULL ) {
capture_last_Java_pc(sp);
}
}
The traceback is below. Dan described it well:
On SPARC one thread cannot flush the register windows of another
thread.
If I understand the mangled names, last_frame() called make_walkable()
which puked on the assertion. Basicly the calling thread tried to do an
operation on the target thread that required access to the
last_frame(). If the target thread isn't walkable, then last_frame()
tries to make it walkable. Bad news if the target thread isn't already
walkable.
The operation that causes the last_frame is part of the complex code that prevents multiple
events when single step is enabled in the presence of breakpoints or code rewriting, etc.
V [libjvm_g.so+0xb6bdb4] ;; __1cHVMErrorOreport_and_die6M_v_+0x804
V [libjvm_g.so+0x48842c] ;; __1cMreport_fatal6Fpkci1_v_+0xa4
V [libjvm_g.so+0x4f2d68] ;; __1cPJavaFrameAnchorNmake_walkable6MpnKJavaThread__v_+0x98
V [libjvm_g.so+0xad1534] ;; __1cKJavaThreadKlast_frame6M_nFframe__+0x44
V [libjvm_g.so+0xac964c] ;; __1cKJavaThreadQlast_java_vframe6MpnLRegisterMap__pnKjavaVFrame__+0x8c
V [libjvm_g.so+0x7cef64] ;; __1cUget_current_location6FpnKJavaThread_ppnK_jmethodID_pi_v_+0x74
V [libjvm_g.so+0x7cf11c] ;; __1cTJvmtiEnvThreadStateWreset_current_location6MnKjvmtiEvent_i_v_+0xec
V [libjvm_g.so+0x7d20bc] ;; __1cbBJvmtiEventControllerPrivatebCrecompute_env_thread_enabled6FipnQJvmtiThreadState__x_+0x33c
V [libjvm_g.so+0x7d229c] ;; __1cbBJvmtiEventControllerPrivateYrecompute_thread_enabled6FpnQJvmtiThreadState__x_+0x9c
V [libjvm_g.so+0x7d276c] ;; __1cbBJvmtiEventControllerPrivateRrecompute_enabled6F_v_+0x354
V [libjvm_g.so+0x7d3944] ;; __1cbBJvmtiEventControllerPrivateTset_event_callbacks6FpnMJvmtiEnvBase_pknTjvmtiEventCallbacks_i_v_+0x1f4
V [libjvm_g.so+0x7d4f00] ;; __1cUJvmtiEventControllerTset_event_callbacks6FpnMJvmtiEnvBase_pknTjvmtiEventCallbacks_i_v_+0xb0
V [libjvm_g.so+0x7b9460] ;; __1cIJvmtiEnvRSetEventCallbacks6MpknTjvmtiEventCallbacks_i_nKjvmtiError__+0x50
V [libjvm_g.so+0x75aec8] ;; jvmti_SetEventCallbacks+0x228
C [libstart_g.so+0x1498] init_callbacks+0xb0
C [libstart_g.so+0xb74] agent_start+0x54
V [libjvm_g.so+0x7f4c68] ;; __1cQJvmtiAgentThreadTcall_start_function6M_v_+0xc0
V [libjvm_g.so+0x7f4b90] ;; __1cQJvmtiAgentThreadWstart_function_wrapper6FpnKJavaThread_pnGThread__v_+0xf0
V [libjvm_g.so+0xac3cf4] ;; __1cKJavaThreadRthread_main_inner6M_v_+0x14c
V [libjvm_g.so+0xac3b90] ;; __1cKJavaThreadDrun6M_v_+0x1b0
V [libjvm_g.so+0x933dc4] ;; _start+0x274