# HG changeset patch # User dholmes # Date 1470975584 14400 # Node ID b77bf599c11bea92126bad584cba3c8a5f0fdab1 # Parent 15e772ff7ff43792a2bf26b1aab54a22f1d06ae2 8159461: bigapps/Kitchensink/stressExitCode hits assert: Must be VMThread or JavaThread Reviewed-by: fparain, simonis, dcubed diff -r 15e772ff7ff4 -r b77bf599c11b hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Aug 11 16:22:08 2016 -0700 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Fri Aug 12 00:19:44 2016 -0400 @@ -2686,7 +2686,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. // static void resume_clear_context(OSThread *osthread) { @@ -2718,9 +2719,22 @@ // after sigsuspend. int old_errno = errno; - Thread* thread = Thread::current(); + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { diff -r 15e772ff7ff4 -r b77bf599c11b hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Aug 11 16:22:08 2016 -0700 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Aug 12 00:19:44 2016 -0400 @@ -2716,7 +2716,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. static void resume_clear_context(OSThread *osthread) { osthread->set_ucontext(NULL); @@ -2746,9 +2747,22 @@ // after sigsuspend. int old_errno = errno; - Thread* thread = Thread::current(); + Thread* thread = Thread::current_or_null_safe(); + assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { diff -r 15e772ff7ff4 -r b77bf599c11b hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Aug 11 16:22:08 2016 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Aug 12 00:19:44 2016 -0400 @@ -3971,7 +3971,8 @@ // - sets target osthread state to continue // - sends signal to end the sigsuspend loop in the SR_handler // -// Note that the SR_lock plays no role in this suspend/resume protocol. +// Note that the SR_lock plays no role in this suspend/resume protocol, +// but is checked for NULL in SR_handler as a thread termination indicator. static void resume_clear_context(OSThread *osthread) { osthread->set_ucontext(NULL); @@ -4004,8 +4005,20 @@ Thread* thread = Thread::current_or_null_safe(); assert(thread != NULL, "Missing current thread in SR_handler"); + + // On some systems we have seen signal delivery get "stuck" until the signal + // mask is changed as part of thread termination. Check that the current thread + // has not already terminated (via SR_lock()) - else the following assertion + // will fail because the thread is no longer a JavaThread as the ~JavaThread + // destructor has completed. + + if (thread->SR_lock() == NULL) { + return; + } + + assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); + OSThread* osthread = thread->osthread(); - assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); os::SuspendResume::State current = osthread->sr.state(); if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { diff -r 15e772ff7ff4 -r b77bf599c11b hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Thu Aug 11 16:22:08 2016 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Aug 12 00:19:44 2016 -0400 @@ -374,11 +374,14 @@ delete handle_area(); delete metadata_handles(); + // SR_handler uses this as a termination indicator - + // needs to happen before os::free_thread() + delete _SR_lock; + _SR_lock = NULL; + // osthread() can be NULL, if creation of thread failed. if (osthread() != NULL) os::free_thread(osthread()); - delete _SR_lock; - // clear Thread::current if thread is deleting itself. // Needed to ensure JNI correctly detects non-attached threads. if (this == Thread::current()) {