< prev index next >

src/os/aix/vm/vmError_aix.cpp

Print this page
rev 7758 : 8065895 Synchronous signals during error reporting may terminate or hang VM process
Reviewed-by: dholmes,gziemski
Contributed-by: stuefe


  63 
  64 // Handle all synchronous signals which may happen during signal handling,
  65 // not just SIGSEGV and SIGBUS.
  66 static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
  67 static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
  68 
  69 // Space for our "saved" signal flags and handlers
  70 static int resettedSigflags[NUM_SIGNALS];
  71 static address resettedSighandler[NUM_SIGNALS];
  72 
  73 static void save_signal(int idx, int sig) {
  74   struct sigaction sa;
  75   sigaction(sig, NULL, &sa);
  76   resettedSigflags[idx]   = sa.sa_flags;
  77   resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
  78                               ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
  79                               : CAST_FROM_FN_PTR(address, sa.sa_handler);
  80 }
  81 
  82 int VMError::get_resetted_sigflags(int sig) {
  83   // Handle all program errors.
  84   for (int i = 0; i < NUM_SIGNALS; i++) {
  85     if (SIGNALS[i] == sig) {
  86       return resettedSigflags[i];
  87     }
  88   }
  89   return -1;
  90 }
  91 
  92 address VMError::get_resetted_sighandler(int sig) {
  93   // Handle all program errors.
  94   for (int i = 0; i < NUM_SIGNALS; i++) {
  95     if (SIGNALS[i] == sig) {
  96       return resettedSighandler[i];
  97     }
  98   }
  99   return NULL;
 100 }
 101 
 102 static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {

 103   // Unmask current signal.
 104   sigset_t newset;
 105   sigemptyset(&newset);
 106   sigaddset(&newset, sig);





 107 
 108   Unimplemented();

 109 }
 110 
 111 void VMError::reset_signal_handlers() {
 112   sigset_t newset;
 113   sigemptyset(&newset);
 114 
 115   for (int i = 0; i < NUM_SIGNALS; i++) {
 116     save_signal(i, SIGNALS[i]);
 117     os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
 118     sigaddset(&newset, SIGNALS[i]);
 119   }
 120 
 121   sigthreadmask(SIG_UNBLOCK, &newset, NULL);
 122 }


  63 
  64 // Handle all synchronous signals which may happen during signal handling,
  65 // not just SIGSEGV and SIGBUS.
  66 static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
  67 static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
  68 
  69 // Space for our "saved" signal flags and handlers
  70 static int resettedSigflags[NUM_SIGNALS];
  71 static address resettedSighandler[NUM_SIGNALS];
  72 
  73 static void save_signal(int idx, int sig) {
  74   struct sigaction sa;
  75   sigaction(sig, NULL, &sa);
  76   resettedSigflags[idx]   = sa.sa_flags;
  77   resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
  78                               ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
  79                               : CAST_FROM_FN_PTR(address, sa.sa_handler);
  80 }
  81 
  82 int VMError::get_resetted_sigflags(int sig) {

  83   for (int i = 0; i < NUM_SIGNALS; i++) {
  84     if (SIGNALS[i] == sig) {
  85       return resettedSigflags[i];
  86     }
  87   }
  88   return -1;
  89 }
  90 
  91 address VMError::get_resetted_sighandler(int sig) {

  92   for (int i = 0; i < NUM_SIGNALS; i++) {
  93     if (SIGNALS[i] == sig) {
  94       return resettedSighandler[i];
  95     }
  96   }
  97   return NULL;
  98 }
  99 
 100 static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
 101 
 102   // Unmask current signal.
 103   sigset_t newset;
 104   sigemptyset(&newset);
 105   sigaddset(&newset, sig);
 106   // and all other synchronous signals too.
 107   for (int i = 0; i < NUM_SIGNALS; i++) {
 108     sigaddset(&newset, SIGNALS[i]);
 109   }
 110   sigthreadmask(SIG_UNBLOCK, &newset, NULL);
 111 
 112   VMError err(NULL, sig, NULL, info, ucVoid);
 113   err.report_and_die();
 114 }
 115 
 116 void VMError::reset_signal_handlers() {
 117   sigset_t newset;
 118   sigemptyset(&newset);
 119 
 120   for (int i = 0; i < NUM_SIGNALS; i++) {
 121     save_signal(i, SIGNALS[i]);
 122     os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
 123     sigaddset(&newset, SIGNALS[i]);
 124   }
 125 
 126   sigthreadmask(SIG_UNBLOCK, &newset, NULL);
 127 }
< prev index next >