24#define LOGFPRT(...) fprintf(stderr, "Error: " __VA_ARGS__)
27#define LOGNLOG(...) n_log(LOG_ERR, __VA_ARGS__)
87 char addr2line_cmd[4093] =
"";
92 sprintf(addr2line_cmd,
"atos -o %.256s ./%p", program_name,
addr);
95 sprintf(addr2line_cmd,
"addr2line -f -p -e ./%s %p", program_name,
addr);
96 LOGSIG(
"%s", addr2line_cmd);
99 sprintf(addr2line_cmd,
"addr2line -f -p -e %.256s %p", program_name,
addr);
102 N_STR* output = NULL;
104 n_popen(addr2line_cmd, 1024, (
void**)&output, &ret);
115void windows_print_stacktrace(CONTEXT* context) {
116 SymInitialize(GetCurrentProcess(), 0,
true);
118 STACKFRAME frame = {0};
121#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
123 frame.AddrPC.Offset = context->Eip;
124 frame.AddrPC.Mode = AddrModeFlat;
125 frame.AddrStack.Offset = context->Esp;
126 frame.AddrStack.Mode = AddrModeFlat;
127 frame.AddrFrame.Offset = context->Ebp;
128 frame.AddrFrame.Mode = AddrModeFlat;
130 frame.AddrPC.Offset = context->Rip;
131 frame.AddrPC.Mode = AddrModeFlat;
132 frame.AddrStack.Offset = context->Rsp;
133 frame.AddrStack.Mode = AddrModeFlat;
134 frame.AddrFrame.Offset = context->Rbp;
135 frame.AddrFrame.Mode = AddrModeFlat;
138 while (StackWalk(IMAGE_FILE_MACHINE_I386,
144 SymFunctionTableAccess,
150 SymCleanup(GetCurrentProcess());
158LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) {
159 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
160 case EXCEPTION_ACCESS_VIOLATION:
161 LOGSIG(
"Error: EXCEPTION_ACCESS_VIOLATION");
163 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
164 LOGSIG(
"Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
166 case EXCEPTION_BREAKPOINT:
167 LOGSIG(
"Error: EXCEPTION_BREAKPOINT");
169 case EXCEPTION_DATATYPE_MISALIGNMENT:
170 LOGSIG(
"Error: EXCEPTION_DATATYPE_MISALIGNMENT");
172 case EXCEPTION_FLT_DENORMAL_OPERAND:
173 LOGSIG(
"Error: EXCEPTION_FLT_DENORMAL_OPERAND");
175 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
176 LOGSIG(
"Error: EXCEPTION_FLT_DIVIDE_BY_ZERO");
178 case EXCEPTION_FLT_INEXACT_RESULT:
179 LOGSIG(
"Error: EXCEPTION_FLT_INEXACT_RESULT");
181 case EXCEPTION_FLT_INVALID_OPERATION:
182 LOGSIG(
"Error: EXCEPTION_FLT_INVALID_OPERATION");
184 case EXCEPTION_FLT_OVERFLOW:
185 LOGSIG(
"Error: EXCEPTION_FLT_OVERFLOW");
187 case EXCEPTION_FLT_STACK_CHECK:
188 LOGSIG(
"Error: EXCEPTION_FLT_STACK_CHECK");
190 case EXCEPTION_FLT_UNDERFLOW:
191 LOGSIG(
"Error: EXCEPTION_FLT_UNDERFLOW");
193 case EXCEPTION_ILLEGAL_INSTRUCTION:
194 LOGSIG(
"Error: EXCEPTION_ILLEGAL_INSTRUCTION");
196 case EXCEPTION_IN_PAGE_ERROR:
197 LOGSIG(
"Error: EXCEPTION_IN_PAGE_ERROR");
199 case EXCEPTION_INT_DIVIDE_BY_ZERO:
200 LOGSIG(
"Error: EXCEPTION_INT_DIVIDE_BY_ZERO");
202 case EXCEPTION_INT_OVERFLOW:
203 LOGSIG(
"Error: EXCEPTION_INT_OVERFLOW");
205 case EXCEPTION_INVALID_DISPOSITION:
206 LOGSIG(
"Error: EXCEPTION_INVALID_DISPOSITION");
208 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
209 LOGSIG(
"Error: EXCEPTION_NONCONTINUABLE_EXCEPTION");
211 case EXCEPTION_PRIV_INSTRUCTION:
212 LOGSIG(
"Error: EXCEPTION_PRIV_INSTRUCTION");
214 case EXCEPTION_SINGLE_STEP:
215 LOGSIG(
"Error: EXCEPTION_SINGLE_STEP");
217 case EXCEPTION_STACK_OVERFLOW:
218 LOGSIG(
"Error: EXCEPTION_STACK_OVERFLOW");
221 LOGSIG(
"Error: Unrecognized Exception");
226 if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) {
227 windows_print_stacktrace(ExceptionInfo->ContextRecord);
233 return EXCEPTION_EXECUTE_HANDLER;
242 SetUnhandledExceptionFilter(windows_exception_handler);
252 int i, trace_size = 0;
253 char** messages = (
char**)NULL;
263 for (i = 0; i < trace_size; ++i)
266 LOGSIG(
" error determining line # for: %s", messages[i]);
284 LOGSIG(
"Caught SIGSEGV: Segmentation Fault");
287 LOGSIG(
"Caught SIGINT: Interactive attention signal, (usually ctrl+c)");
290 switch (siginfo->si_code) {
292 LOGSIG(
"Caught SIGFPE: (integer divide by zero)");
295 LOGSIG(
"Caught SIGFPE: (integer overflow)");
298 LOGSIG(
"Caught SIGFPE: (floating-point divide by zero)");
301 LOGSIG(
"Caught SIGFPE: (floating-point overflow)");
304 LOGSIG(
"Caught SIGFPE: (floating-point underflow)");
307 LOGSIG(
"Caught SIGFPE: (floating-point inexact result)");
310 LOGSIG(
"Caught SIGFPE: (floating-point invalid operation)");
313 LOGSIG(
"Caught SIGFPE: (subscript out of range)");
316 LOGSIG(
"Caught SIGFPE: Arithmetic Exception");
321 switch (siginfo->si_code) {
323 LOGSIG(
"Caught SIGILL: (illegal opcode)");
326 LOGSIG(
"Caught SIGILL: (illegal operand)");
329 LOGSIG(
"Caught SIGILL: (illegal addressing mode)");
332 LOGSIG(
"Caught SIGILL: (illegal trap)");
335 LOGSIG(
"Caught SIGILL: (privileged opcode)");
338 LOGSIG(
"Caught SIGILL: (privileged register)");
341 LOGSIG(
"Caught SIGILL: (coprocessor error)");
344 LOGSIG(
"Caught SIGILL: (internal stack error)");
347 LOGSIG(
"Caught SIGILL: Illegal Instruction");
352 LOGSIG(
"Caught SIGTERM: a termination request was sent to the program");
355 LOGSIG(
"Caught SIGABRT: usually caused by an abort() or assert()");
376 rl.rlim_cur = rl.rlim_max = 0x100000;
377 setrlimit(RLIMIT_STACK, &rl);
389 ss.ss_sp = alternate_stack;
390 ss.ss_size =
sizeof(alternate_stack);
391 ss.ss_flags = SS_ONSTACK;
393 if (sigaltstack(&ss, NULL) != 0) {
394 err(1,
"sigaltstack");
400 struct sigaction sig_action;
401 sigemptyset(&sig_action.sa_mask);
407 sig_action.sa_flags = SA_SIGINFO;
409 sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK;
412 if (sigaction(SIGSEGV, &sig_action, NULL) != 0) {
415 if (sigaction(SIGFPE, &sig_action, NULL) != 0) {
418 if (sigaction(SIGINT, &sig_action, NULL) != 0) {
421 if (sigaction(SIGILL, &sig_action, NULL) != 0) {
426 if (sigaction(SIGABRT, &sig_action, NULL) != 0) {
int n_popen(char *cmd, size_t read_buf_size, void **nstr_output, int *ret)
launch a command abd return output and status
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
A box including a string and his lenght.
#define SIGALTSTACK_SIZE
Size of the signal handler alternate stack.
#define MAX_STACK_FRAMES
Number of backtrace log lines.
void set_signal_handler(const char *progname)
Install a signal handler for progname.
static void * stack_traces[32]
static frame list
static const char * __n_stack_traced_progam_name
name of program to debug (addr2line & co)
int addr2line(char const *const program_name, void const *const addr)
Resolve symbol name and source location given the path to the executable and an address.
#define LOGSIG
internal: output to syslog
void posix_print_stack_trace()
print current stack
void posix_signal_handler(int sig, siginfo_t *siginfo, void *context)
decode a signal and call stack print
Signals general handling with stack printing, from https://gist.github.com/jvranish/4441299.
N_STR and string function declaration.