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 } |