-
Bug
-
Resolution: Fixed
-
P3
-
1.4.2
-
mantis
-
sparc
-
solaris_8
###@###.### 2002-11-11
JavaThread::java_suspend_self() has a race with a subsequent external
suspend request. I believe this race has been lying dormant in the code
since we implemented the self-suspend logic (in Ladybird?). Mantis-B05
contains a fix for the following bug:
4683006 3/3 3rd party memory managers risk deadlock with JVMDI/JVMPI/JVM_Suspend
This fix stops using forced suspension with native threads which is the
right thing to do. However, there is an unfortunate side effect of
exposing this race. The fix for 4683006 is _not_ broken! It merely
exposes a race condition. The condition appears to be pretty rare. I've
only seen it on my Ultra-80 2x450MHZ machine running Solaris 8 with the
java_g PepTest stress test. It has not been seen on any other stress
test config nor on any other OS platform.
sampler target
============================ ===========================================
SuspendThreadList() :
enter(SR_lock) :
set_external_suspend() :
exit(SR_lock) :
: post_event()
: ThreadToNativeFromVM
: handle_special_runtime_exit_condition()
: if (is_external_suspend_with_lock() {
: StateSaver sv
: java_suspend_self() {
: enter(SR_lock)
: set_self_suspended()
: while (is_self_suspended())
: SR_lock.wait()
java_suspend(target) :
VM_ThreadSuspend :
VM_ForceSafepoint :
:
GetCallTrace() :
wait_for_ext_suspend...() :
fill_call_trace() :
:
ResumeThreadList() :
enter(SR_lock) :
clear_external_suspend() :
if (is_self_suspended()) { :
clear_self_suspended(); :
SR_lock->notify_all(); : notify received but
} : thread doesn't run
:
SuspendThreadList() :
enter(SR_lock) :
set_external_suspend() :
exit(SR_lock) :
java_suspend(target) :
VM_ThreadSuspend :
VM_ForceSafepoint :
:
GetCallTrace() :
wait_for_ext_suspend...() :
fill_call_trace() : thread runs finally
: : reenter SR_lock
: : sees no longer self suspended
: exit(SR_lock)
: } // end java_suspend_self()
: sampler thread crashes // StateSaver destructor called here
: at this point // which whacks the _post_Java_state
: // field while sampler is walking
: } // end if (is_external_suspend...()
: } // end handle_special_....()
:
: <hprof-code>
: raw_monitor_enter()
: enter(SR_lock)
: while (is_external_suspend())
: exit(SR_lock)
: {
: StateSaver sv
: // this StateSaver makes the thread
: // look okay
: java_suspend_self() {
: enter(SR_lock)
: set_self_suspended()
: while (is_self_suspended())
: SR_lock.wait()
: // we find target thread here
JavaThread::java_suspend_self() has a race with a subsequent external
suspend request. I believe this race has been lying dormant in the code
since we implemented the self-suspend logic (in Ladybird?). Mantis-B05
contains a fix for the following bug:
4683006 3/3 3rd party memory managers risk deadlock with JVMDI/JVMPI/JVM_Suspend
This fix stops using forced suspension with native threads which is the
right thing to do. However, there is an unfortunate side effect of
exposing this race. The fix for 4683006 is _not_ broken! It merely
exposes a race condition. The condition appears to be pretty rare. I've
only seen it on my Ultra-80 2x450MHZ machine running Solaris 8 with the
java_g PepTest stress test. It has not been seen on any other stress
test config nor on any other OS platform.
sampler target
============================ ===========================================
SuspendThreadList() :
enter(SR_lock) :
set_external_suspend() :
exit(SR_lock) :
: post_event()
: ThreadToNativeFromVM
: handle_special_runtime_exit_condition()
: if (is_external_suspend_with_lock() {
: StateSaver sv
: java_suspend_self() {
: enter(SR_lock)
: set_self_suspended()
: while (is_self_suspended())
: SR_lock.wait()
java_suspend(target) :
VM_ThreadSuspend :
VM_ForceSafepoint :
:
GetCallTrace() :
wait_for_ext_suspend...() :
fill_call_trace() :
:
ResumeThreadList() :
enter(SR_lock) :
clear_external_suspend() :
if (is_self_suspended()) { :
clear_self_suspended(); :
SR_lock->notify_all(); : notify received but
} : thread doesn't run
:
SuspendThreadList() :
enter(SR_lock) :
set_external_suspend() :
exit(SR_lock) :
java_suspend(target) :
VM_ThreadSuspend :
VM_ForceSafepoint :
:
GetCallTrace() :
wait_for_ext_suspend...() :
fill_call_trace() : thread runs finally
: : reenter SR_lock
: : sees no longer self suspended
: exit(SR_lock)
: } // end java_suspend_self()
: sampler thread crashes // StateSaver destructor called here
: at this point // which whacks the _post_Java_state
: // field while sampler is walking
: } // end if (is_external_suspend...()
: } // end handle_special_....()
:
: <hprof-code>
: raw_monitor_enter()
: enter(SR_lock)
: while (is_external_suspend())
: exit(SR_lock)
: {
: StateSaver sv
: // this StateSaver makes the thread
: // look okay
: java_suspend_self() {
: enter(SR_lock)
: set_self_suspended()
: while (is_self_suspended())
: SR_lock.wait()
: // we find target thread here
- relates to
-
JDK-4683006 3rd party memory managers risk deadlock with JVMDI/JVMPI/JVM_Suspend
- Closed