< prev index next >
src/os/posix/vm/os_posix.cpp
Print this page
rev 8910 : full patch for jfr
*** 1,7 ****
/*
! * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 827,836 ****
--- 827,898 ----
} else if (sig == SIGCHLD) {
os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status);
}
}
+ 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 = ThreadLocalStorage::thread();
+ assert(_protected_thread != NULL, "Cannot crash protect a NULL 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();
+ }
+ }
+ }
+
os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
}
/*
< prev index next >