hotspot/src/os/linux/vm/vmError_linux.cpp
changeset 28943 679546f0cc1f
parent 13964 01a2b863cc61
child 29573 2d800e5d575f
equal deleted inserted replaced
28942:7d690319db4a 28943:679546f0cc1f
    61       yes = false;
    61       yes = false;
    62     }
    62     }
    63   } while (yes);
    63   } while (yes);
    64 }
    64 }
    65 
    65 
       
    66 // handle all synchronous program error signals which may happen during error
       
    67 // reporting. They must be unblocked, caught, handled.
       
    68 
       
    69 static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
       
    70 static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
       
    71 
    66 // Space for our "saved" signal flags and handlers
    72 // Space for our "saved" signal flags and handlers
    67 static int resettedSigflags[2];
    73 static int resettedSigflags[NUM_SIGNALS];
    68 static address resettedSighandler[2];
    74 static address resettedSighandler[NUM_SIGNALS];
    69 
    75 
    70 static void save_signal(int idx, int sig)
    76 static void save_signal(int idx, int sig)
    71 {
    77 {
    72   struct sigaction sa;
    78   struct sigaction sa;
    73   sigaction(sig, NULL, &sa);
    79   sigaction(sig, NULL, &sa);
    76                               ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
    82                               ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
    77                               : CAST_FROM_FN_PTR(address, sa.sa_handler);
    83                               : CAST_FROM_FN_PTR(address, sa.sa_handler);
    78 }
    84 }
    79 
    85 
    80 int VMError::get_resetted_sigflags(int sig) {
    86 int VMError::get_resetted_sigflags(int sig) {
    81   if(SIGSEGV == sig) {
    87   for (int i = 0; i < NUM_SIGNALS; i++) {
    82     return resettedSigflags[0];
    88     if (SIGNALS[i] == sig) {
    83   } else if(SIGBUS == sig) {
    89       return resettedSigflags[i];
    84     return resettedSigflags[1];
    90     }
    85   }
    91   }
    86   return -1;
    92   return -1;
    87 }
    93 }
    88 
    94 
    89 address VMError::get_resetted_sighandler(int sig) {
    95 address VMError::get_resetted_sighandler(int sig) {
    90   if(SIGSEGV == sig) {
    96   for (int i = 0; i < NUM_SIGNALS; i++) {
    91     return resettedSighandler[0];
    97     if (SIGNALS[i] == sig) {
    92   } else if(SIGBUS == sig) {
    98       return resettedSighandler[i];
    93     return resettedSighandler[1];
    99     }
    94   }
   100   }
    95   return NULL;
   101   return NULL;
    96 }
   102 }
    97 
   103 
    98 static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
   104 static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
    99   // unmask current signal
   105   // unmask current signal
   100   sigset_t newset;
   106   sigset_t newset;
   101   sigemptyset(&newset);
   107   sigemptyset(&newset);
   102   sigaddset(&newset, sig);
   108   sigaddset(&newset, sig);
   103   sigprocmask(SIG_UNBLOCK, &newset, NULL);
   109   // also unmask other synchronous signals
       
   110   for (int i = 0; i < NUM_SIGNALS; i++) {
       
   111     sigaddset(&newset, SIGNALS[i]);
       
   112   }
       
   113   pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
   104 
   114 
   105   VMError err(NULL, sig, NULL, info, ucVoid);
   115   VMError err(NULL, sig, NULL, info, ucVoid);
   106   err.report_and_die();
   116   err.report_and_die();
   107 }
   117 }
   108 
   118 
   109 void VMError::reset_signal_handlers() {
   119 void VMError::reset_signal_handlers() {
   110   // Save sigflags for resetted signals
   120   // install signal handlers for all synchronous program error signals
   111   save_signal(0, SIGSEGV);
   121   sigset_t newset;
   112   save_signal(1, SIGBUS);
   122   sigemptyset(&newset);
   113   os::signal(SIGSEGV, CAST_FROM_FN_PTR(void *, crash_handler));
   123 
   114   os::signal(SIGBUS, CAST_FROM_FN_PTR(void *, crash_handler));
   124   for (int i = 0; i < NUM_SIGNALS; i++) {
       
   125     save_signal(i, SIGNALS[i]);
       
   126     os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
       
   127     sigaddset(&newset, SIGNALS[i]);
       
   128   }
       
   129   pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
       
   130 
   115 }
   131 }