< prev index next >

src/os/posix/vm/os_posix.cpp

Print this page
rev 13203 : [mq]: 8183925

*** 1282,1343 **** } return stack_size; } ! os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { ! assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); } /* * See the caveats for this class in os_posix.hpp * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this * method and returns false. If none of the signals are raised, returns true. * The callback is supposed to provide the method that should be protected. */ ! bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { sigset_t saved_sig_mask; ! assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); ! assert(!WatcherThread::watcher_thread()->has_crash_protection(), ! "crash_protection already set?"); // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask // since on at least some systems (OS X) siglongjmp will restore the mask // for the process, not the thread pthread_sigmask(0, NULL, &saved_sig_mask); if (sigsetjmp(_jmpbuf, 0) == 0) { // make sure we can see in the signal handler that we have crash protection // installed ! WatcherThread::watcher_thread()->set_crash_protection(this); cb.call(); // and clear the crash protection ! WatcherThread::watcher_thread()->set_crash_protection(NULL); return true; } // this happens when we siglongjmp() back pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); ! WatcherThread::watcher_thread()->set_crash_protection(NULL); return false; } ! void os::WatcherThreadCrashProtection::restore() { ! assert(WatcherThread::watcher_thread()->has_crash_protection(), ! "must have crash protection"); ! siglongjmp(_jmpbuf, 1); } ! void os::WatcherThreadCrashProtection::check_crash_protection(int sig, Thread* thread) { if (thread != NULL && ! thread->is_Watcher_thread() && ! WatcherThread::watcher_thread()->has_crash_protection()) { if (sig == SIGSEGV || sig == SIGBUS) { ! WatcherThread::watcher_thread()->crash_protection()->restore(); } } } #define check_with_errno(check_type, cond, msg) \ --- 1282,1349 ---- } return stack_size; } ! Thread* os::ThreadCrashProtection::_protected_thread = NULL; ! os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL; ! volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0; ! ! os::ThreadCrashProtection::ThreadCrashProtection() { } /* * See the caveats for this class in os_posix.hpp * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this * method and returns false. If none of the signals are raised, returns true. * The callback is supposed to provide the method that should be protected. */ ! bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) { sigset_t saved_sig_mask; ! Thread::muxAcquire(&_crash_mux, "CrashProtection"); ! ! _protected_thread = Thread::current_or_null(); ! assert(_protected_thread != NULL, "Cannot crash protect a none Thread"); // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask // since on at least some systems (OS X) siglongjmp will restore the mask // for the process, not the thread pthread_sigmask(0, NULL, &saved_sig_mask); if (sigsetjmp(_jmpbuf, 0) == 0) { // make sure we can see in the signal handler that we have crash protection // installed ! _crash_protection = this; cb.call(); // and clear the crash protection ! _crash_protection = NULL; ! _protected_thread = NULL; ! Thread::muxRelease(&_crash_mux); return true; } // this happens when we siglongjmp() back pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); ! _crash_protection = NULL; ! _protected_thread = NULL; ! Thread::muxRelease(&_crash_mux); return false; } ! void os::ThreadCrashProtection::restore() { ! assert(_crash_protection != NULL, "must have crash protection"); siglongjmp(_jmpbuf, 1); } ! void os::ThreadCrashProtection::check_crash_protection(int sig, Thread* thread) { if (thread != NULL && ! thread == _protected_thread && ! _crash_protection != NULL) { if (sig == SIGSEGV || sig == SIGBUS) { ! _crash_protection->restore(); } } } #define check_with_errno(check_type, cond, msg) \
< prev index next >