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 /* |