42#define LOGFPRT(...) fprintf(stderr, "Error: " __VA_ARGS__)
45#define LOGNLOG(...) n_log(LOG_ERR, __VA_ARGS__)
105 char addr2line_cmd[4093] =
"";
110 sprintf(addr2line_cmd,
"atos -o %.256s ./%p", program_name,
addr);
113 snprintf(addr2line_cmd,
sizeof(addr2line_cmd),
"addr2line -f -p -e ./%s %p", program_name,
addr);
114 LOGSIG(
"%s", addr2line_cmd);
117 sprintf(addr2line_cmd,
"addr2line -f -p -e %.256s %p", program_name,
addr);
120 N_STR* output = NULL;
122 n_popen(addr2line_cmd, 1024, (
void**)&output, &ret);
123 if (!output || !output->
data) {
137void windows_print_stacktrace(CONTEXT* context) {
138 SymInitialize(GetCurrentProcess(), 0,
true);
140 STACKFRAME frame = {0};
143#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
145 frame.AddrPC.Offset = context->Eip;
146 frame.AddrPC.Mode = AddrModeFlat;
147 frame.AddrStack.Offset = context->Esp;
148 frame.AddrStack.Mode = AddrModeFlat;
149 frame.AddrFrame.Offset = context->Ebp;
150 frame.AddrFrame.Mode = AddrModeFlat;
152 frame.AddrPC.Offset = context->Rip;
153 frame.AddrPC.Mode = AddrModeFlat;
154 frame.AddrStack.Offset = context->Rsp;
155 frame.AddrStack.Mode = AddrModeFlat;
156 frame.AddrFrame.Offset = context->Rbp;
157 frame.AddrFrame.Mode = AddrModeFlat;
160 while (StackWalk(IMAGE_FILE_MACHINE_I386,
166 SymFunctionTableAccess,
172 SymCleanup(GetCurrentProcess());
180LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) {
181 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
182 case EXCEPTION_ACCESS_VIOLATION:
183 LOGSIG(
"Error: EXCEPTION_ACCESS_VIOLATION");
185 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
186 LOGSIG(
"Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
188 case EXCEPTION_BREAKPOINT:
189 LOGSIG(
"Error: EXCEPTION_BREAKPOINT");
191 case EXCEPTION_DATATYPE_MISALIGNMENT:
192 LOGSIG(
"Error: EXCEPTION_DATATYPE_MISALIGNMENT");
194 case EXCEPTION_FLT_DENORMAL_OPERAND:
195 LOGSIG(
"Error: EXCEPTION_FLT_DENORMAL_OPERAND");
197 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
198 LOGSIG(
"Error: EXCEPTION_FLT_DIVIDE_BY_ZERO");
200 case EXCEPTION_FLT_INEXACT_RESULT:
201 LOGSIG(
"Error: EXCEPTION_FLT_INEXACT_RESULT");
203 case EXCEPTION_FLT_INVALID_OPERATION:
204 LOGSIG(
"Error: EXCEPTION_FLT_INVALID_OPERATION");
206 case EXCEPTION_FLT_OVERFLOW:
207 LOGSIG(
"Error: EXCEPTION_FLT_OVERFLOW");
209 case EXCEPTION_FLT_STACK_CHECK:
210 LOGSIG(
"Error: EXCEPTION_FLT_STACK_CHECK");
212 case EXCEPTION_FLT_UNDERFLOW:
213 LOGSIG(
"Error: EXCEPTION_FLT_UNDERFLOW");
215 case EXCEPTION_ILLEGAL_INSTRUCTION:
216 LOGSIG(
"Error: EXCEPTION_ILLEGAL_INSTRUCTION");
218 case EXCEPTION_IN_PAGE_ERROR:
219 LOGSIG(
"Error: EXCEPTION_IN_PAGE_ERROR");
221 case EXCEPTION_INT_DIVIDE_BY_ZERO:
222 LOGSIG(
"Error: EXCEPTION_INT_DIVIDE_BY_ZERO");
224 case EXCEPTION_INT_OVERFLOW:
225 LOGSIG(
"Error: EXCEPTION_INT_OVERFLOW");
227 case EXCEPTION_INVALID_DISPOSITION:
228 LOGSIG(
"Error: EXCEPTION_INVALID_DISPOSITION");
230 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
231 LOGSIG(
"Error: EXCEPTION_NONCONTINUABLE_EXCEPTION");
233 case EXCEPTION_PRIV_INSTRUCTION:
234 LOGSIG(
"Error: EXCEPTION_PRIV_INSTRUCTION");
236 case EXCEPTION_SINGLE_STEP:
237 LOGSIG(
"Error: EXCEPTION_SINGLE_STEP");
239 case EXCEPTION_STACK_OVERFLOW:
240 LOGSIG(
"Error: EXCEPTION_STACK_OVERFLOW");
243 LOGSIG(
"Error: Unrecognized Exception");
248 if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) {
249 windows_print_stacktrace(ExceptionInfo->ContextRecord);
255 return EXCEPTION_EXECUTE_HANDLER;
264 SetUnhandledExceptionFilter(windows_exception_handler);
274 int i, trace_size = 0;
275 char** messages = (
char**)NULL;
281 if (!messages)
return;
286 for (i = 0; i < trace_size; ++i)
289 LOGSIG(
" error determining line # for: %s", messages[i]);
308 LOGSIG(
"Caught SIGSEGV: Segmentation Fault");
311 LOGSIG(
"Caught SIGINT: Interactive attention signal, (usually ctrl+c)");
314 switch (siginfo->si_code) {
316 LOGSIG(
"Caught SIGFPE: (integer divide by zero)");
319 LOGSIG(
"Caught SIGFPE: (integer overflow)");
322 LOGSIG(
"Caught SIGFPE: (floating-point divide by zero)");
325 LOGSIG(
"Caught SIGFPE: (floating-point overflow)");
328 LOGSIG(
"Caught SIGFPE: (floating-point underflow)");
331 LOGSIG(
"Caught SIGFPE: (floating-point inexact result)");
334 LOGSIG(
"Caught SIGFPE: (floating-point invalid operation)");
337 LOGSIG(
"Caught SIGFPE: (subscript out of range)");
340 LOGSIG(
"Caught SIGFPE: Arithmetic Exception");
345 switch (siginfo->si_code) {
347 LOGSIG(
"Caught SIGILL: (illegal opcode)");
350 LOGSIG(
"Caught SIGILL: (illegal operand)");
353 LOGSIG(
"Caught SIGILL: (illegal addressing mode)");
356 LOGSIG(
"Caught SIGILL: (illegal trap)");
359 LOGSIG(
"Caught SIGILL: (privileged opcode)");
362 LOGSIG(
"Caught SIGILL: (privileged register)");
365 LOGSIG(
"Caught SIGILL: (coprocessor error)");
368 LOGSIG(
"Caught SIGILL: (internal stack error)");
371 LOGSIG(
"Caught SIGILL: Illegal Instruction");
376 LOGSIG(
"Caught SIGTERM: a termination request was sent to the program");
379 LOGSIG(
"Caught SIGABRT: usually caused by an abort() or assert()");
400 rl.rlim_cur = rl.rlim_max = 0x100000;
402 setrlimit(RLIMIT_STACK, &rl);
414 ss.ss_sp = alternate_stack;
415 ss.ss_size =
sizeof(alternate_stack);
418 if (sigaltstack(&ss, NULL) != 0) {
419 err(1,
"sigaltstack");
425 struct sigaction sig_action;
426 sigemptyset(&sig_action.sa_mask);
432 sig_action.sa_flags = SA_SIGINFO;
434 sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK;
437 if (sigaction(SIGSEGV, &sig_action, NULL) != 0) {
440 if (sigaction(SIGFPE, &sig_action, NULL) != 0) {
443 if (sigaction(SIGINT, &sig_action, NULL) != 0) {
446 if (sigaction(SIGILL, &sig_action, NULL) != 0) {
451 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 and 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.