8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
Summary: Fix a race between VMOp_GetCurrentLocation reaching a safepoint and arget thread exiting from Java execution
Reviewed-by: sla, dholmes, dsamersoff
Contributed-by: serguei.spitsyn@oracle.com
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp Tue Dec 03 08:36:15 2013 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp Tue Dec 03 15:41:35 2013 -0800
@@ -269,11 +269,20 @@
void doit() {
ResourceMark rmark; // _thread != Thread::current()
RegisterMap rm(_thread, false);
- javaVFrame* vf = _thread->last_java_vframe(&rm);
- assert(vf != NULL, "must have last java frame");
- Method* method = vf->method();
- _method_id = method->jmethod_id();
- _bci = vf->bci();
+ // There can be a race condition between a VM_Operation reaching a safepoint
+ // and the target thread exiting from Java execution.
+ // We must recheck the last Java frame still exists.
+ if (_thread->has_last_Java_frame()) {
+ javaVFrame* vf = _thread->last_java_vframe(&rm);
+ assert(vf != NULL, "must have last java frame");
+ Method* method = vf->method();
+ _method_id = method->jmethod_id();
+ _bci = vf->bci();
+ } else {
+ // Clear current location as the target thread has no Java frames anymore.
+ _method_id = (jmethodID)NULL;
+ _bci = 0;
+ }
}
void get_current_location(jmethodID *method_id, int *bci) {
*method_id = _method_id;