Tue, 04 Feb 2020 11:16:27 +0800
8183925: Decouple crash protection from watcher thread
Reviewed-by: dcubed, coleenp
1.1 --- a/src/os/posix/vm/os_posix.cpp Thu Jan 30 00:21:06 2020 +0000 1.2 +++ b/src/os/posix/vm/os_posix.cpp Tue Feb 04 11:16:27 2020 +0800 1.3 @@ -919,59 +919,3 @@ 1.4 } 1.5 } 1.6 } 1.7 - 1.8 -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 1.9 - assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 1.10 -} 1.11 - 1.12 -/* 1.13 - * See the caveats for this class in os_posix.hpp 1.14 - * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this 1.15 - * method and returns false. If none of the signals are raised, returns true. 1.16 - * The callback is supposed to provide the method that should be protected. 1.17 - */ 1.18 -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { 1.19 - sigset_t saved_sig_mask; 1.20 - 1.21 - assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); 1.22 - assert(!WatcherThread::watcher_thread()->has_crash_protection(), 1.23 - "crash_protection already set?"); 1.24 - 1.25 - // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask 1.26 - // since on at least some systems (OS X) siglongjmp will restore the mask 1.27 - // for the process, not the thread 1.28 - pthread_sigmask(0, NULL, &saved_sig_mask); 1.29 - if (sigsetjmp(_jmpbuf, 0) == 0) { 1.30 - // make sure we can see in the signal handler that we have crash protection 1.31 - // installed 1.32 - WatcherThread::watcher_thread()->set_crash_protection(this); 1.33 - cb.call(); 1.34 - // and clear the crash protection 1.35 - WatcherThread::watcher_thread()->set_crash_protection(NULL); 1.36 - return true; 1.37 - } 1.38 - // this happens when we siglongjmp() back 1.39 - pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); 1.40 - WatcherThread::watcher_thread()->set_crash_protection(NULL); 1.41 - return false; 1.42 -} 1.43 - 1.44 -void os::WatcherThreadCrashProtection::restore() { 1.45 - assert(WatcherThread::watcher_thread()->has_crash_protection(), 1.46 - "must have crash protection"); 1.47 - 1.48 - siglongjmp(_jmpbuf, 1); 1.49 -} 1.50 - 1.51 -void os::WatcherThreadCrashProtection::check_crash_protection(int sig, 1.52 - Thread* thread) { 1.53 - 1.54 - if (thread != NULL && 1.55 - thread->is_Watcher_thread() && 1.56 - WatcherThread::watcher_thread()->has_crash_protection()) { 1.57 - 1.58 - if (sig == SIGSEGV || sig == SIGBUS) { 1.59 - WatcherThread::watcher_thread()->crash_protection()->restore(); 1.60 - } 1.61 - } 1.62 -}
2.1 --- a/src/os/posix/vm/os_posix.hpp Thu Jan 30 00:21:06 2020 +0000 2.2 +++ b/src/os/posix/vm/os_posix.hpp Tue Feb 04 11:16:27 2020 +0800 2.3 @@ -88,24 +88,4 @@ 2.4 sigjmp_buf _jmpbuf; 2.5 }; 2.6 2.7 -/* 2.8 - * Crash protection for the watcher thread. Wrap the callback 2.9 - * with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp 2.10 - * back. 2.11 - * To be able to use this - don't take locks, don't rely on destructors, 2.12 - * don't make OS library calls, don't allocate memory, don't print, 2.13 - * don't call code that could leave the heap / memory in an inconsistent state, 2.14 - * or anything else where we are not in control if we suddenly jump out. 2.15 - */ 2.16 -class WatcherThreadCrashProtection : public StackObj { 2.17 -public: 2.18 - WatcherThreadCrashProtection(); 2.19 - bool call(os::CrashProtectionCallback& cb); 2.20 - 2.21 - static void check_crash_protection(int signal, Thread* thread); 2.22 -private: 2.23 - void restore(); 2.24 - sigjmp_buf _jmpbuf; 2.25 -}; 2.26 - 2.27 #endif // OS_POSIX_VM_OS_POSIX_HPP
3.1 --- a/src/os/windows/vm/os_windows.cpp Thu Jan 30 00:21:06 2020 +0000 3.2 +++ b/src/os/windows/vm/os_windows.cpp Tue Feb 04 11:16:27 2020 +0800 3.3 @@ -4905,34 +4905,6 @@ 3.4 return success; 3.5 } 3.6 3.7 -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 3.8 - assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 3.9 -} 3.10 - 3.11 -/* 3.12 - * See the caveats for this class in os_windows.hpp 3.13 - * Protects the callback call so that raised OS EXCEPTIONS causes a jump back 3.14 - * into this method and returns false. If no OS EXCEPTION was raised, returns 3.15 - * true. 3.16 - * The callback is supposed to provide the method that should be protected. 3.17 - */ 3.18 -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { 3.19 - assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); 3.20 - assert(!WatcherThread::watcher_thread()->has_crash_protection(), 3.21 - "crash_protection already set?"); 3.22 - 3.23 - bool success = true; 3.24 - __try { 3.25 - WatcherThread::watcher_thread()->set_crash_protection(this); 3.26 - cb.call(); 3.27 - } __except(EXCEPTION_EXECUTE_HANDLER) { 3.28 - // only for protection, nothing to do 3.29 - success = false; 3.30 - } 3.31 - WatcherThread::watcher_thread()->set_crash_protection(NULL); 3.32 - return success; 3.33 -} 3.34 - 3.35 // An Event wraps a win32 "CreateEvent" kernel handle. 3.36 // 3.37 // We have a number of choices regarding "CreateEvent" win32 handle leakage:
4.1 --- a/src/os/windows/vm/os_windows.hpp Thu Jan 30 00:21:06 2020 +0000 4.2 +++ b/src/os/windows/vm/os_windows.hpp Tue Feb 04 11:16:27 2020 +0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -125,20 +125,6 @@ 4.11 static volatile intptr_t _crash_mux; 4.12 }; 4.13 4.14 -/* 4.15 - * Crash protection for the watcher thread. Wrap the callback 4.16 - * with a __try { call() } 4.17 - * To be able to use this - don't take locks, don't rely on destructors, 4.18 - * don't make OS library calls, don't allocate memory, don't print, 4.19 - * don't call code that could leave the heap / memory in an inconsistent state, 4.20 - * or anything else where we are not in control if we suddenly jump out. 4.21 - */ 4.22 -class WatcherThreadCrashProtection : public StackObj { 4.23 -public: 4.24 - WatcherThreadCrashProtection(); 4.25 - bool call(os::CrashProtectionCallback& cb); 4.26 -}; 4.27 - 4.28 class PlatformEvent : public CHeapObj<mtInternal> { 4.29 private: 4.30 double CachePad [4] ; // increase odds that _Event is sole occupant of cache line
5.1 --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Jan 30 00:21:06 2020 +0000 5.2 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Tue Feb 04 11:16:27 2020 +0800 5.3 @@ -407,7 +407,7 @@ 5.4 5.5 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away 5.6 // (no destructors can be run) 5.7 - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); 5.8 + os::ThreadCrashProtection::check_crash_protection(sig, t); 5.9 5.10 SignalHandlerMark shm(t); 5.11
6.1 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Jan 30 00:21:06 2020 +0000 6.2 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Tue Feb 04 11:16:27 2020 +0800 6.3 @@ -544,7 +544,7 @@ 6.4 6.5 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away 6.6 // (no destructors can be run) 6.7 - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); 6.8 + os::ThreadCrashProtection::check_crash_protection(sig, t); 6.9 6.10 SignalHandlerMark shm(t); 6.11
7.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Jan 30 00:21:06 2020 +0000 7.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Tue Feb 04 11:16:27 2020 +0800 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -222,7 +222,7 @@ 7.11 7.12 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away 7.13 // (no destructors can be run) 7.14 - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); 7.15 + os::ThreadCrashProtection::check_crash_protection(sig, t); 7.16 7.17 SignalHandlerMark shm(t); 7.18
8.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Jan 30 00:21:06 2020 +0000 8.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Tue Feb 04 11:16:27 2020 +0800 8.3 @@ -312,7 +312,7 @@ 8.4 8.5 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away 8.6 // (no destructors can be run) 8.7 - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); 8.8 + os::ThreadCrashProtection::check_crash_protection(sig, t); 8.9 8.10 SignalHandlerMark shm(t); 8.11
9.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Jan 30 00:21:06 2020 +0000 9.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue Feb 04 11:16:27 2020 +0800 9.3 @@ -369,7 +369,7 @@ 9.4 9.5 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away 9.6 // (no destructors can be run) 9.7 - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); 9.8 + os::ThreadCrashProtection::check_crash_protection(sig, t); 9.9 9.10 SignalHandlerMark shm(t); 9.11
10.1 --- a/src/share/vm/runtime/mutex.cpp Thu Jan 30 00:21:06 2020 +0000 10.2 +++ b/src/share/vm/runtime/mutex.cpp Tue Feb 04 11:16:27 2020 +0800 10.3 @@ -1,6 +1,6 @@ 10.4 10.5 /* 10.6 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 10.7 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 10.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.9 * 10.10 * This code is free software; you can redistribute it and/or modify it 10.11 @@ -1373,10 +1373,8 @@ 10.12 debug_only(if (rank() != Mutex::special) \ 10.13 thread->check_for_valid_safepoint_state(false);) 10.14 } 10.15 - if (thread->is_Watcher_thread()) { 10.16 - assert(!WatcherThread::watcher_thread()->has_crash_protection(), 10.17 - "locking not allowed when crash protection is set"); 10.18 - } 10.19 + assert(!os::ThreadCrashProtection::is_crash_protected(thread), 10.20 + "locking not allowed when crash protection is set"); 10.21 } 10.22 10.23 void Monitor::check_block_state(Thread *thread) {
11.1 --- a/src/share/vm/runtime/os.cpp Thu Jan 30 00:21:06 2020 +0000 11.2 +++ b/src/share/vm/runtime/os.cpp Tue Feb 04 11:16:27 2020 +0800 11.3 @@ -593,21 +593,10 @@ 11.4 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); 11.5 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); 11.6 11.7 -#ifdef ASSERT 11.8 - // checking for the WatcherThread and crash_protection first 11.9 - // since os::malloc can be called when the libjvm.{dll,so} is 11.10 - // first loaded and we don't have a thread yet. 11.11 - // try to find the thread after we see that the watcher thread 11.12 - // exists and has crash protection. 11.13 - WatcherThread *wt = WatcherThread::watcher_thread(); 11.14 - if (wt != NULL && wt->has_crash_protection()) { 11.15 - Thread* thread = ThreadLocalStorage::get_thread_slow(); 11.16 - if (thread == wt) { 11.17 - assert(!wt->has_crash_protection(), 11.18 - "Can't malloc with crash protection from WatcherThread"); 11.19 - } 11.20 - } 11.21 -#endif 11.22 + // Since os::malloc can be called when the libjvm.{dll,so} is 11.23 + // first loaded and we don't have a thread yet we must accept NULL also here. 11.24 + assert(!os::ThreadCrashProtection::is_crash_protected(ThreadLocalStorage::thread()), 11.25 + "malloc() not allowed when crash protection is set"); 11.26 11.27 if (size == 0) { 11.28 // return a valid pointer if size is zero
12.1 --- a/src/share/vm/runtime/thread.cpp Thu Jan 30 00:21:06 2020 +0000 12.2 +++ b/src/share/vm/runtime/thread.cpp Tue Feb 04 11:16:27 2020 +0800 12.3 @@ -1239,7 +1239,7 @@ 12.4 bool WatcherThread::_startable = false; 12.5 volatile bool WatcherThread::_should_terminate = false; 12.6 12.7 -WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) { 12.8 +WatcherThread::WatcherThread() : Thread() { 12.9 assert(watcher_thread() == NULL, "we can only allocate one WatcherThread"); 12.10 if (os::create_thread(this, os::watcher_thread)) { 12.11 _watcher_thread = this;
13.1 --- a/src/share/vm/runtime/thread.hpp Thu Jan 30 00:21:06 2020 +0000 13.2 +++ b/src/share/vm/runtime/thread.hpp Tue Feb 04 11:16:27 2020 +0800 13.3 @@ -734,8 +734,6 @@ 13.4 13.5 static bool _startable; 13.6 volatile static bool _should_terminate; // updated without holding lock 13.7 - 13.8 - os::WatcherThreadCrashProtection* _crash_protection; 13.9 public: 13.10 enum SomeConstants { 13.11 delay_interval = 10 // interrupt delay in milliseconds 13.12 @@ -762,15 +760,6 @@ 13.13 // Only allow start once the VM is sufficiently initialized 13.14 // Otherwise the first task to enroll will trigger the start 13.15 static void make_startable(); 13.16 - 13.17 - void set_crash_protection(os::WatcherThreadCrashProtection* crash_protection) { 13.18 - assert(Thread::current()->is_Watcher_thread(), "Can only be set by WatcherThread"); 13.19 - _crash_protection = crash_protection; 13.20 - } 13.21 - 13.22 - bool has_crash_protection() const { return _crash_protection != NULL; } 13.23 - os::WatcherThreadCrashProtection* crash_protection() const { return _crash_protection; } 13.24 - 13.25 private: 13.26 int sleep() const; 13.27 };