src/os/posix/vm/os_posix.cpp

changeset 9858
b985cbb00e68
parent 9711
0f2fe7d37d8c
child 9891
4904bded9702
equal deleted inserted replaced
9727:c7a3e57fdf4a 9858:b985cbb00e68
856 } else if (sig == SIGCHLD) { 856 } else if (sig == SIGCHLD) {
857 os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status); 857 os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status);
858 } 858 }
859 } 859 }
860 860
861 Thread* os::ThreadCrashProtection::_protected_thread = NULL;
862 os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;
863 volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0;
864
865 os::ThreadCrashProtection::ThreadCrashProtection() {
866 }
867
868 /*
869 * See the caveats for this class in os_posix.hpp
870 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
871 * method and returns false. If none of the signals are raised, returns true.
872 * The callback is supposed to provide the method that should be protected.
873 */
874 bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
875 sigset_t saved_sig_mask;
876
877 Thread::muxAcquire(&_crash_mux, "CrashProtection");
878
879 _protected_thread = ThreadLocalStorage::thread();
880 assert(_protected_thread != NULL, "Cannot crash protect a NULL thread");
881
882 // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
883 // since on at least some systems (OS X) siglongjmp will restore the mask
884 // for the process, not the thread
885 pthread_sigmask(0, NULL, &saved_sig_mask);
886 if (sigsetjmp(_jmpbuf, 0) == 0) {
887 // make sure we can see in the signal handler that we have crash protection
888 // installed
889 _crash_protection = this;
890 cb.call();
891 // and clear the crash protection
892 _crash_protection = NULL;
893 _protected_thread = NULL;
894 Thread::muxRelease(&_crash_mux);
895 return true;
896 }
897 // this happens when we siglongjmp() back
898 pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
899 _crash_protection = NULL;
900 _protected_thread = NULL;
901 Thread::muxRelease(&_crash_mux);
902 return false;
903 }
904
905 void os::ThreadCrashProtection::restore() {
906 assert(_crash_protection != NULL, "must have crash protection");
907 siglongjmp(_jmpbuf, 1);
908 }
909
910 void os::ThreadCrashProtection::check_crash_protection(int sig,
911 Thread* thread) {
912
913 if (thread != NULL &&
914 thread == _protected_thread &&
915 _crash_protection != NULL) {
916
917 if (sig == SIGSEGV || sig == SIGBUS) {
918 _crash_protection->restore();
919 }
920 }
921 }
922
861 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 923 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
862 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 924 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
863 } 925 }
864 926
865 /* 927 /*

mercurial