static void addr2text(char *out, size_t outlen, void *ptr) { Dl_info dli = {}; char buf[256]; int r = dladdr(ptr, &dli); if(r && dli.dli_sname != NULL && dli.dli_saddr != NULL) { snprintf(out, outlen, "%s+0x%tx (%s)", dli.dli_sname, ptr - dli.dli_saddr, dli.dli_fname); return; } if(self[0] && !add2lineresolve(self, ptr, buf, sizeof(buf))) { snprintf(out, outlen, "%s %p", buf, ptr); return; } if(dli.dli_fname != NULL && dli.dli_fbase != NULL) { snprintf(out, outlen, "%s %p", dli.dli_fname, ptr); return; } snprintf(out, outlen, "%p", ptr); }
static void traphandler(int sig, siginfo_t *si, void *UC) { ucontext_t *uc = UC; #if ENABLE_EXECINFO char buf[200]; static void *frames[MAXFRAMES]; int nframes = backtrace(frames, MAXFRAMES); Dl_info dli; #endif int i; const char *reason = NULL; tvhlog_spawn(LOG_ALERT, "CRASH", "Signal: %d in %s ", sig, line1); switch(sig) { case SIGSEGV: switch(si->si_code) { case SEGV_MAPERR: reason = "Address not mapped"; break; case SEGV_ACCERR: reason = "Access error"; break; } break; case SIGFPE: switch(si->si_code) { case FPE_INTDIV: reason = "Integer division by zero"; break; } break; } tvhlog_spawn(LOG_ALERT, "CRASH", "Fault address %p (%s)", si->si_addr, reason ?: "N/A"); tvhlog_spawn(LOG_ALERT, "CRASH", "Loaded libraries: %s ", libs); snprintf(tmpbuf, sizeof(tmpbuf), "Register dump [%d]: ", NGREG); for(i = 0; i < NGREG; i++) { #if __WORDSIZE == 64 sappend(tmpbuf, sizeof(tmpbuf), "%016llx ", uc->uc_mcontext.gregs[i]); #else sappend(tmpbuf, sizeof(tmpbuf), "%08x ", uc->uc_mcontext.gregs[i]); #endif } tvhlog_spawn(LOG_ALERT, "CRASH", "%s", tmpbuf); #if ENABLE_EXECINFO tvhlog_spawn(LOG_ALERT, "CRASH", "STACKTRACE"); for(i = 0; i < nframes; i++) { if(dladdr(frames[i], &dli)) { if(dli.dli_sname != NULL && dli.dli_saddr != NULL) { tvhlog_spawn(LOG_ALERT, "CRASH", "%s+0x%tx (%s)", dli.dli_sname, frames[i] - dli.dli_saddr, dli.dli_fname); continue; } if(self[0] && !add2lineresolve(self, frames[i], buf, sizeof(buf))) { tvhlog_spawn(LOG_ALERT, "CRASH", "%s %p", buf, frames[i]); continue; } if(dli.dli_fname != NULL && dli.dli_fbase != NULL) { tvhlog_spawn(LOG_ALERT, "CRASH", "%s %p", dli.dli_fname, frames[i]); continue; } tvhlog_spawn(LOG_ALERT, "CRASH", "%p", frames[i]); } } #endif }