41static bool_t inited = B_FALSE;
45static struct sigaction old_sigsegv = {};
46static struct sigaction old_sigabrt = {};
47static struct sigaction old_sigfpe = {};
48static struct sigaction old_sigint = {};
49static struct sigaction old_sigill = {};
50static struct sigaction old_sigterm = {};
53sigfpe2str(
int si_code)
57 return (
"integer divide by zero");
59 return (
"integer overflow");
61 return (
"floating-point divide by zero");
63 return (
"floating-point overflow");
65 return (
"floating-point underflow");
67 return (
"floating-point inexact result");
69 return (
"floating-point invalid operation");
71 return (
"subscript out of range");
73 return (
"general arithmetic exception");
78sigill2str(
int si_code)
82 return (
"illegal opcode");
84 return (
"illegal operand");
86 return (
"illegal addressing mode");
88 return (
"illegal trap");
90 return (
"privileged opcode");
92 return (
"privileged register");
94 return (
"coprocessor error");
96 return (
"internal stack error");
98 return (
"unknown error");
103handle_posix_sig(
int sig, siginfo_t *siginfo,
void *context)
105#define SIGNAL_FORWARD(sigact) \
107 if ((sigact)->sa_sigaction != NULL && \
108 ((sigact)->sa_flags & SA_SIGINFO)) { \
109 (sigact)->sa_sigaction(sig, siginfo, context); \
110 } else if ((sigact)->sa_handler != NULL) { \
111 (sigact)->sa_handler(sig); \
116 logMsg(
"Caught SIGSEGV: segmentation fault (%p)",
120 logMsg(
"Caught SIGABORT: abort (%p)", siginfo->si_addr);
123 logMsg(
"Caught SIGFPE: floating point exception (%s)",
124 sigfpe2str(siginfo->si_code));
127 logMsg(
"Caught SIGILL: illegal instruction (%s)",
128 sigill2str(siginfo->si_code));
131 logMsg(
"Caught SIGTERM: terminated");
134 logMsg(
"Caught signal %d", sig);
142 SIGNAL_FORWARD(&old_sigsegv);
145 SIGNAL_FORWARD(&old_sigabrt);
148 SIGNAL_FORWARD(&old_sigfpe);
151 SIGNAL_FORWARD(&old_sigill);
154 SIGNAL_FORWARD(&old_sigterm);
162static uint8_t *alternate_stack = NULL;
166signal_handler_init(
void)
168 struct sigaction sig_action = { .sa_sigaction = handle_posix_sig };
170 sigemptyset(&sig_action.sa_mask);
177 alternate_stack = malloc(SIGSTKSZ);
179 .ss_sp = (
void*)alternate_stack,
184 VERIFY0(sigaltstack(&ss, NULL));
185 sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK;
187 sig_action.sa_flags = SA_SIGINFO;
190 VERIFY0(sigaction(SIGSEGV, &sig_action, &old_sigsegv));
191 VERIFY0(sigaction(SIGABRT, &sig_action, &old_sigabrt));
192 VERIFY0(sigaction(SIGFPE, &sig_action, &old_sigfpe));
193 VERIFY0(sigaction(SIGINT, &sig_action, &old_sigint));
194 VERIFY0(sigaction(SIGILL, &sig_action, &old_sigill));
195 VERIFY0(sigaction(SIGTERM, &sig_action, &old_sigterm));
199signal_handler_fini(
void)
201 VERIFY0(sigaction(SIGSEGV, &old_sigsegv, NULL));
202 VERIFY0(sigaction(SIGABRT, &old_sigabrt, NULL));
203 VERIFY0(sigaction(SIGFPE, &old_sigfpe, NULL));
204 VERIFY0(sigaction(SIGINT, &old_sigint, NULL));
205 VERIFY0(sigaction(SIGILL, &old_sigill, NULL));
206 VERIFY0(sigaction(SIGTERM, &old_sigterm, NULL));
208 free(alternate_stack);
209 alternate_stack = NULL;
215static LPTOP_LEVEL_EXCEPTION_FILTER prev_windows_except_handler = NULL;
218handle_windows_exception(EXCEPTION_POINTERS *ei)
220 switch(ei->ExceptionRecord->ExceptionCode) {
221 case EXCEPTION_ASSERTION_FAILED:
224 case EXCEPTION_ACCESS_VIOLATION:
225 logMsg(
"Caught EXCEPTION_ACCESS_VIOLATION");
227 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
228 logMsg(
"Caught EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
230 case EXCEPTION_BREAKPOINT:
231 logMsg(
"Caught EXCEPTION_BREAKPOINT");
233 case EXCEPTION_DATATYPE_MISALIGNMENT:
234 logMsg(
"Caught EXCEPTION_DATATYPE_MISALIGNMENT");
236 case EXCEPTION_FLT_DENORMAL_OPERAND:
237 logMsg(
"Caught EXCEPTION_FLT_DENORMAL_OPERAND");
239 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
240 logMsg(
"Caught EXCEPTION_FLT_DIVIDE_BY_ZERO");
242 case EXCEPTION_FLT_INEXACT_RESULT:
243 logMsg(
"Caught EXCEPTION_FLT_INEXACT_RESULT");
245 case EXCEPTION_FLT_INVALID_OPERATION:
246 logMsg(
"Caught EXCEPTION_FLT_INVALID_OPERATION");
248 case EXCEPTION_FLT_OVERFLOW:
249 logMsg(
"Caught EXCEPTION_FLT_OVERFLOW");
251 case EXCEPTION_FLT_STACK_CHECK:
252 logMsg(
"Caught EXCEPTION_FLT_STACK_CHECK");
254 case EXCEPTION_FLT_UNDERFLOW:
255 logMsg(
"Caught EXCEPTION_FLT_UNDERFLOW");
257 case EXCEPTION_ILLEGAL_INSTRUCTION:
258 logMsg(
"Caught EXCEPTION_ILLEGAL_INSTRUCTION");
260 case EXCEPTION_IN_PAGE_ERROR:
261 logMsg(
"Caught EXCEPTION_IN_PAGE_ERROR");
263 case EXCEPTION_INT_DIVIDE_BY_ZERO:
264 logMsg(
"Caught EXCEPTION_INT_DIVIDE_BY_ZERO");
266 case EXCEPTION_INT_OVERFLOW:
267 logMsg(
"Caught EXCEPTION_INT_OVERFLOW");
269 case EXCEPTION_INVALID_DISPOSITION:
270 logMsg(
"Caught EXCEPTION_INVALID_DISPOSITION");
272 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
273 logMsg(
"Caught EXCEPTION_NONCONTINUABLE_EXCEPTION");
275 case EXCEPTION_PRIV_INSTRUCTION:
276 logMsg(
"Caught EXCEPTION_PRIV_INSTRUCTION");
278 case EXCEPTION_SINGLE_STEP:
279 logMsg(
"Caught EXCEPTION_SINGLE_STEP");
281 case EXCEPTION_STACK_OVERFLOW:
282 logMsg(
"Caught EXCEPTION_STACK_OVERFLOW");
285 logMsg(
"Caught unknown exception %lx",
286 ei->ExceptionRecord->ExceptionCode);
289 log_backtrace_sw64(ei->ContextRecord);
291 if (prev_windows_except_handler != NULL)
292 return (prev_windows_except_handler(ei));
294 return (EXCEPTION_CONTINUE_SEARCH);
310 signal_handler_init();
312 prev_windows_except_handler =
313 SetUnhandledExceptionFilter(handle_windows_exception);
329 signal_handler_fini();
331 SetUnhandledExceptionFilter(prev_windows_except_handler);
void log_backtrace(int skip_frames)