41#define LOGFPRT(...) fprintf(stderr, "Error: " __VA_ARGS__)
44#define LOGNLOG(...) n_log(LOG_ERR, __VA_ARGS__)
104 char addr2line_cmd[4093] =
"";
109 sprintf(addr2line_cmd,
"atos -o %.256s ./%p", program_name,
addr);
112 snprintf(addr2line_cmd,
sizeof(addr2line_cmd),
"addr2line -f -p -e ./%s %p", program_name,
addr);
113 LOGSIG(
"%s", addr2line_cmd);
116 sprintf(addr2line_cmd,
"addr2line -f -p -e %.256s %p", program_name,
addr);
119 N_STR* output = NULL;
121 n_popen(addr2line_cmd, 1024, (
void**)&output, &ret);
122 if (!output || !output->
data) {
136void windows_print_stacktrace(CONTEXT* context) {
137 SymInitialize(GetCurrentProcess(), 0,
true);
139 STACKFRAME frame = {0};
142#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
144 frame.AddrPC.Offset = context->Eip;
145 frame.AddrPC.Mode = AddrModeFlat;
146 frame.AddrStack.Offset = context->Esp;
147 frame.AddrStack.Mode = AddrModeFlat;
148 frame.AddrFrame.Offset = context->Ebp;
149 frame.AddrFrame.Mode = AddrModeFlat;
151 frame.AddrPC.Offset = context->Rip;
152 frame.AddrPC.Mode = AddrModeFlat;
153 frame.AddrStack.Offset = context->Rsp;
154 frame.AddrStack.Mode = AddrModeFlat;
155 frame.AddrFrame.Offset = context->Rbp;
156 frame.AddrFrame.Mode = AddrModeFlat;
159 while (StackWalk(IMAGE_FILE_MACHINE_I386,
165 SymFunctionTableAccess,
171 SymCleanup(GetCurrentProcess());
179LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) {
180 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
181 case EXCEPTION_ACCESS_VIOLATION:
182 LOGSIG(
"Error: EXCEPTION_ACCESS_VIOLATION");
184 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
185 LOGSIG(
"Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
187 case EXCEPTION_BREAKPOINT:
188 LOGSIG(
"Error: EXCEPTION_BREAKPOINT");
190 case EXCEPTION_DATATYPE_MISALIGNMENT:
191 LOGSIG(
"Error: EXCEPTION_DATATYPE_MISALIGNMENT");
193 case EXCEPTION_FLT_DENORMAL_OPERAND:
194 LOGSIG(
"Error: EXCEPTION_FLT_DENORMAL_OPERAND");
196 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
197 LOGSIG(
"Error: EXCEPTION_FLT_DIVIDE_BY_ZERO");
199 case EXCEPTION_FLT_INEXACT_RESULT:
200 LOGSIG(
"Error: EXCEPTION_FLT_INEXACT_RESULT");
202 case EXCEPTION_FLT_INVALID_OPERATION:
203 LOGSIG(
"Error: EXCEPTION_FLT_INVALID_OPERATION");
205 case EXCEPTION_FLT_OVERFLOW:
206 LOGSIG(
"Error: EXCEPTION_FLT_OVERFLOW");
208 case EXCEPTION_FLT_STACK_CHECK:
209 LOGSIG(
"Error: EXCEPTION_FLT_STACK_CHECK");
211 case EXCEPTION_FLT_UNDERFLOW:
212 LOGSIG(
"Error: EXCEPTION_FLT_UNDERFLOW");
214 case EXCEPTION_ILLEGAL_INSTRUCTION:
215 LOGSIG(
"Error: EXCEPTION_ILLEGAL_INSTRUCTION");
217 case EXCEPTION_IN_PAGE_ERROR:
218 LOGSIG(
"Error: EXCEPTION_IN_PAGE_ERROR");
220 case EXCEPTION_INT_DIVIDE_BY_ZERO:
221 LOGSIG(
"Error: EXCEPTION_INT_DIVIDE_BY_ZERO");
223 case EXCEPTION_INT_OVERFLOW:
224 LOGSIG(
"Error: EXCEPTION_INT_OVERFLOW");
226 case EXCEPTION_INVALID_DISPOSITION:
227 LOGSIG(
"Error: EXCEPTION_INVALID_DISPOSITION");
229 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
230 LOGSIG(
"Error: EXCEPTION_NONCONTINUABLE_EXCEPTION");
232 case EXCEPTION_PRIV_INSTRUCTION:
233 LOGSIG(
"Error: EXCEPTION_PRIV_INSTRUCTION");
235 case EXCEPTION_SINGLE_STEP:
236 LOGSIG(
"Error: EXCEPTION_SINGLE_STEP");
238 case EXCEPTION_STACK_OVERFLOW:
239 LOGSIG(
"Error: EXCEPTION_STACK_OVERFLOW");
242 LOGSIG(
"Error: Unrecognized Exception");
247 if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) {
248 windows_print_stacktrace(ExceptionInfo->ContextRecord);
254 return EXCEPTION_EXECUTE_HANDLER;
263 SetUnhandledExceptionFilter(windows_exception_handler);
273 int i, trace_size = 0;
274 char** messages = (
char**)NULL;
280 if (!messages)
return;
285 for (i = 0; i < trace_size; ++i)
288 LOGSIG(
" error determining line # for: %s", messages[i]);
307 LOGSIG(
"Caught SIGSEGV: Segmentation Fault");
310 LOGSIG(
"Caught SIGINT: Interactive attention signal, (usually ctrl+c)");
313 switch (siginfo->si_code) {
315 LOGSIG(
"Caught SIGFPE: (integer divide by zero)");
318 LOGSIG(
"Caught SIGFPE: (integer overflow)");
321 LOGSIG(
"Caught SIGFPE: (floating-point divide by zero)");
324 LOGSIG(
"Caught SIGFPE: (floating-point overflow)");
327 LOGSIG(
"Caught SIGFPE: (floating-point underflow)");
330 LOGSIG(
"Caught SIGFPE: (floating-point inexact result)");
333 LOGSIG(
"Caught SIGFPE: (floating-point invalid operation)");
336 LOGSIG(
"Caught SIGFPE: (subscript out of range)");
339 LOGSIG(
"Caught SIGFPE: Arithmetic Exception");
344 switch (siginfo->si_code) {
346 LOGSIG(
"Caught SIGILL: (illegal opcode)");
349 LOGSIG(
"Caught SIGILL: (illegal operand)");
352 LOGSIG(
"Caught SIGILL: (illegal addressing mode)");
355 LOGSIG(
"Caught SIGILL: (illegal trap)");
358 LOGSIG(
"Caught SIGILL: (privileged opcode)");
361 LOGSIG(
"Caught SIGILL: (privileged register)");
364 LOGSIG(
"Caught SIGILL: (coprocessor error)");
367 LOGSIG(
"Caught SIGILL: (internal stack error)");
370 LOGSIG(
"Caught SIGILL: Illegal Instruction");
375 LOGSIG(
"Caught SIGTERM: a termination request was sent to the program");
378 LOGSIG(
"Caught SIGABRT: usually caused by an abort() or assert()");
399 rl.rlim_cur = rl.rlim_max = 0x100000;
400 setrlimit(RLIMIT_STACK, &rl);
412 ss.ss_sp = alternate_stack;
413 ss.ss_size =
sizeof(alternate_stack);
416 if (sigaltstack(&ss, NULL) != 0) {
417 err(1,
"sigaltstack");
423 struct sigaction sig_action;
424 sigemptyset(&sig_action.sa_mask);
430 sig_action.sa_flags = SA_SIGINFO;
432 sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK;
435 if (sigaction(SIGSEGV, &sig_action, NULL) != 0) {
438 if (sigaction(SIGFPE, &sig_action, NULL) != 0) {
441 if (sigaction(SIGINT, &sig_action, NULL) != 0) {
444 if (sigaction(SIGILL, &sig_action, NULL) != 0) {
449 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.