24#define LOGFPRT( ... ) fprintf( stderr , "Error: " __VA_ARGS__ )
27#define LOGNLOG( ... ) n_log( LOG_ERR , __VA_ARGS__ )
88int addr2line(
char const *
const program_name,
void const *
const addr)
90 char addr2line_cmd[4093] =
"" ;
95 sprintf(addr2line_cmd,
"atos -o %.256s ./%p", program_name, addr);
98 sprintf(addr2line_cmd,
"addr2line -f -p -e ./%s %p", program_name, addr);
99 LOGSIG(
"%s", addr2line_cmd );
102 sprintf(addr2line_cmd,
"addr2line -f -p -e %.256s %p", program_name, addr);
105 N_STR *output = NULL ;
107 n_popen( addr2line_cmd, 1024, (
void **)&output, &ret );
108 LOGSIG(
"%s", output -> data );
119void windows_print_stacktrace(CONTEXT* context)
121 SymInitialize(GetCurrentProcess(), 0,
true);
123 STACKFRAME frame = { 0 };
126#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
128 frame.AddrPC.Offset = context->Eip;
129 frame.AddrPC.Mode = AddrModeFlat;
130 frame.AddrStack.Offset = context->Esp;
131 frame.AddrStack.Mode = AddrModeFlat;
132 frame.AddrFrame.Offset = context->Ebp;
133 frame.AddrFrame.Mode = AddrModeFlat;
135 frame.AddrPC.Offset = context->Rip;
136 frame.AddrPC.Mode = AddrModeFlat;
137 frame.AddrStack.Offset = context->Rsp;
138 frame.AddrStack.Mode = AddrModeFlat;
139 frame.AddrFrame.Offset = context->Rbp;
140 frame.AddrFrame.Mode = AddrModeFlat;
143 while (StackWalk(IMAGE_FILE_MACHINE_I386,
149 SymFunctionTableAccess,
156 SymCleanup( GetCurrentProcess() );
166LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo)
168 switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
170 case EXCEPTION_ACCESS_VIOLATION:
171 LOGSIG(
"Error: EXCEPTION_ACCESS_VIOLATION" );
173 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
174 LOGSIG(
"Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED" );
176 case EXCEPTION_BREAKPOINT:
177 LOGSIG(
"Error: EXCEPTION_BREAKPOINT" );
179 case EXCEPTION_DATATYPE_MISALIGNMENT:
180 LOGSIG(
"Error: EXCEPTION_DATATYPE_MISALIGNMENT" );
182 case EXCEPTION_FLT_DENORMAL_OPERAND:
183 LOGSIG(
"Error: EXCEPTION_FLT_DENORMAL_OPERAND" );
185 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
186 LOGSIG(
"Error: EXCEPTION_FLT_DIVIDE_BY_ZERO" );
188 case EXCEPTION_FLT_INEXACT_RESULT:
189 LOGSIG(
"Error: EXCEPTION_FLT_INEXACT_RESULT" );
191 case EXCEPTION_FLT_INVALID_OPERATION:
192 LOGSIG(
"Error: EXCEPTION_FLT_INVALID_OPERATION" );
194 case EXCEPTION_FLT_OVERFLOW:
195 LOGSIG(
"Error: EXCEPTION_FLT_OVERFLOW" );
197 case EXCEPTION_FLT_STACK_CHECK:
198 LOGSIG(
"Error: EXCEPTION_FLT_STACK_CHECK" );
200 case EXCEPTION_FLT_UNDERFLOW:
201 LOGSIG(
"Error: EXCEPTION_FLT_UNDERFLOW" );
203 case EXCEPTION_ILLEGAL_INSTRUCTION:
204 LOGSIG(
"Error: EXCEPTION_ILLEGAL_INSTRUCTION" );
206 case EXCEPTION_IN_PAGE_ERROR:
207 LOGSIG(
"Error: EXCEPTION_IN_PAGE_ERROR" );
209 case EXCEPTION_INT_DIVIDE_BY_ZERO:
210 LOGSIG(
"Error: EXCEPTION_INT_DIVIDE_BY_ZERO" );
212 case EXCEPTION_INT_OVERFLOW:
213 LOGSIG(
"Error: EXCEPTION_INT_OVERFLOW" );
215 case EXCEPTION_INVALID_DISPOSITION:
216 LOGSIG(
"Error: EXCEPTION_INVALID_DISPOSITION" );
218 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
219 LOGSIG(
"Error: EXCEPTION_NONCONTINUABLE_EXCEPTION" );
221 case EXCEPTION_PRIV_INSTRUCTION:
222 LOGSIG(
"Error: EXCEPTION_PRIV_INSTRUCTION" );
224 case EXCEPTION_SINGLE_STEP:
225 LOGSIG(
"Error: EXCEPTION_SINGLE_STEP" );
227 case EXCEPTION_STACK_OVERFLOW:
228 LOGSIG(
"Error: EXCEPTION_STACK_OVERFLOW" );
231 LOGSIG(
"Error: Unrecognized Exception" );
236 if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
238 windows_print_stacktrace(ExceptionInfo->ContextRecord);
246 return EXCEPTION_EXECUTE_HANDLER;
257 SetUnhandledExceptionFilter(windows_exception_handler);
268 int i, trace_size = 0;
269 char **messages = (
char **)NULL;
279 for (i = 0; i < trace_size; ++i)
283 LOGSIG(
" error determining line # for: %s", messages[i] );
304 LOGSIG(
"Caught SIGSEGV: Segmentation Fault" );
307 LOGSIG(
"Caught SIGINT: Interactive attention signal, (usually ctrl+c)" );
310 switch(siginfo->si_code)
313 LOGSIG(
"Caught SIGFPE: (integer divide by zero)" );
316 LOGSIG(
"Caught SIGFPE: (integer overflow)" );
319 LOGSIG(
"Caught SIGFPE: (floating-point divide by zero)" );
322 LOGSIG(
"Caught SIGFPE: (floating-point overflow)" );
325 LOGSIG(
"Caught SIGFPE: (floating-point underflow)" );
328 LOGSIG(
"Caught SIGFPE: (floating-point inexact result)" );
331 LOGSIG(
"Caught SIGFPE: (floating-point invalid operation)" );
334 LOGSIG(
"Caught SIGFPE: (subscript out of range)" );
337 LOGSIG(
"Caught SIGFPE: Arithmetic Exception" );
342 switch(siginfo->si_code)
345 LOGSIG(
"Caught SIGILL: (illegal opcode)" );
348 LOGSIG(
"Caught SIGILL: (illegal operand)" );
351 LOGSIG(
"Caught SIGILL: (illegal addressing mode)" );
354 LOGSIG(
"Caught SIGILL: (illegal trap)" );
357 LOGSIG(
"Caught SIGILL: (privileged opcode)" );
360 LOGSIG(
"Caught SIGILL: (privileged register)" );
363 LOGSIG(
"Caught SIGILL: (coprocessor error)" );
366 LOGSIG(
"Caught SIGILL: (internal stack error)" );
369 LOGSIG(
"Caught SIGILL: Illegal Instruction" );
374 LOGSIG(
"Caught SIGTERM: a termination request was sent to the program" );
377 LOGSIG(
"Caught SIGABRT: usually caused by an abort() or assert()" );
402 rl.rlim_cur = rl.rlim_max = 0x100000;
403 setrlimit (RLIMIT_STACK, &rl);
414 ss.ss_flags = SS_ONSTACK ;
416 if (sigaltstack(&ss, NULL) != 0)
418 err(1,
"sigaltstack");
424 struct sigaction sig_action ;
425 sigemptyset( &sig_action.sa_mask );
431 sig_action.sa_flags = SA_SIGINFO;
433 sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK;
436 if (sigaction(SIGSEGV, &sig_action, NULL) != 0)
440 if (sigaction(SIGFPE, &sig_action, NULL) != 0)
444 if (sigaction(SIGINT, &sig_action, NULL) != 0)
448 if (sigaction(SIGILL, &sig_action, NULL) != 0)
454 if (sigaction(SIGABRT, &sig_action, NULL) != 0)
int n_popen(char *cmd, int 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[MAX_STACK_FRAMES]
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.
static uint8_t alternate_stack[SIGALTSTACK_SIZE]
static block for alternate stack
#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.