8199813: SIGSEGV in ThreadsList::includes()
ThreadsListHandles cannot be used by JavaThreads that are not on the Threads list. Reviewed-by: eosterlund, gthornbr, dholmes, rehn
This commit is contained in:
parent
7995d17bca
commit
d2e9c712ad
@ -1644,10 +1644,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
//
|
||||
// Dynamic loader will make all stacks executable after
|
||||
// this function returns, and will not do that again.
|
||||
#ifdef ASSERT
|
||||
ThreadsListHandle tlh;
|
||||
assert(tlh.length() == 0, "no Java threads should exist yet.");
|
||||
#endif
|
||||
assert(Threads::number_of_threads() == 0, "no Java threads should exist yet.");
|
||||
} else {
|
||||
warning("You have loaded library %s which might have disabled stack guard. "
|
||||
"The VM will try to fix the stack guard now.\n"
|
||||
|
@ -2392,11 +2392,13 @@ int JavaThread::java_suspend_self() {
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// verify the JavaThread has not yet been published in the Threads::list, and
|
||||
// hence doesn't need protection from concurrent access at this stage
|
||||
// Verify the JavaThread has not yet been published in the Threads::list, and
|
||||
// hence doesn't need protection from concurrent access at this stage.
|
||||
void JavaThread::verify_not_published() {
|
||||
ThreadsListHandle tlh;
|
||||
assert(!tlh.includes(this), "JavaThread shouldn't have been published yet!");
|
||||
// Cannot create a ThreadsListHandle here and check !tlh.includes(this)
|
||||
// since an unpublished JavaThread doesn't participate in the
|
||||
// Thread-SMR protocol for keeping a ThreadsList alive.
|
||||
assert(!on_thread_list(), "JavaThread shouldn't have been published yet!");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4262,11 +4264,6 @@ bool Threads::destroy_vm() {
|
||||
VMThread::destroy();
|
||||
}
|
||||
|
||||
// clean up ideal graph printers
|
||||
#if defined(COMPILER2) && !defined(PRODUCT)
|
||||
IdealGraphPrinter::clean_up();
|
||||
#endif
|
||||
|
||||
// Now, all Java threads are gone except daemon threads. Daemon threads
|
||||
// running Java code or in VM are stopped by the Safepoint. However,
|
||||
// daemon threads executing native code are still running. But they
|
||||
@ -4275,6 +4272,16 @@ bool Threads::destroy_vm() {
|
||||
|
||||
VM_Exit::set_vm_exited();
|
||||
|
||||
// Clean up ideal graph printers after the VMThread has started
|
||||
// the final safepoint which will block all the Compiler threads.
|
||||
// Note that this Thread has already logically exited so the
|
||||
// clean_up() function's use of a JavaThreadIteratorWithHandle
|
||||
// would be a problem except set_vm_exited() has remembered the
|
||||
// shutdown thread which is granted a policy exception.
|
||||
#if defined(COMPILER2) && !defined(PRODUCT)
|
||||
IdealGraphPrinter::clean_up();
|
||||
#endif
|
||||
|
||||
notify_vm_shutdown();
|
||||
|
||||
// We are after VM_Exit::set_vm_exited() so we can't call
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "runtime/jniHandles.inline.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/threadSMR.inline.hpp"
|
||||
#include "runtime/vm_operations.hpp"
|
||||
#include "services/threadService.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
@ -469,6 +470,16 @@ ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thre
|
||||
|
||||
ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
|
||||
assert(self == Thread::current(), "sanity check");
|
||||
// Threads::threads_do() is used by the Thread-SMR protocol to visit all
|
||||
// Threads in the system which ensures the safety of the ThreadsList
|
||||
// managed by this ThreadsListHandle, but JavaThreads that are not on
|
||||
// the Threads list cannot be included in that visit. The JavaThread that
|
||||
// calls Threads::destroy_vm() is exempt from this check because it has
|
||||
// to logically exit as part of the shutdown procedure. This is safe
|
||||
// because VM_Exit::_shutdown_thread is not set until after the VMThread
|
||||
// has started the final safepoint which holds the Threads_lock for the
|
||||
// remainder of the VM's life.
|
||||
assert(!self->is_Java_thread() || self == VM_Exit::shutdown_thread() || (((JavaThread*)self)->on_thread_list() && !((JavaThread*)self)->is_terminated()), "JavaThread must be on the Threads list to use a ThreadsListHandle");
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_timer.start();
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadCo
|
||||
}
|
||||
|
||||
volatile bool VM_Exit::_vm_exited = false;
|
||||
Thread * VM_Exit::_shutdown_thread = NULL;
|
||||
Thread * volatile VM_Exit::_shutdown_thread = NULL;
|
||||
|
||||
int VM_Exit::set_vm_exited() {
|
||||
|
||||
|
@ -459,7 +459,7 @@ class VM_Exit: public VM_Operation {
|
||||
private:
|
||||
int _exit_code;
|
||||
static volatile bool _vm_exited;
|
||||
static Thread * _shutdown_thread;
|
||||
static Thread * volatile _shutdown_thread;
|
||||
static void wait_if_vm_exited();
|
||||
public:
|
||||
VM_Exit(int exit_code) {
|
||||
@ -468,6 +468,7 @@ class VM_Exit: public VM_Operation {
|
||||
static int wait_for_threads_in_native_to_block();
|
||||
static int set_vm_exited();
|
||||
static bool vm_exited() { return _vm_exited; }
|
||||
static Thread * shutdown_thread() { return _shutdown_thread; }
|
||||
static void block_if_vm_exited() {
|
||||
if (_vm_exited) {
|
||||
wait_if_vm_exited();
|
||||
|
Loading…
Reference in New Issue
Block a user