Better backtraces thanks to addr2link

This commit is contained in:
Andreas Öman 2011-02-21 22:40:10 +01:00
parent d7e4dc376b
commit a629798b62

View file

@ -30,6 +30,7 @@ char tvh_binshasum[20];
#include <string.h>
#include <signal.h>
#include <ucontext.h>
#include <limits.h>
#if ENABLE_EXECINFO
#include <execinfo.h>
#endif
@ -49,6 +50,7 @@ char tvh_binshasum[20];
static char line1[200];
static char tmpbuf[1024];
static char libs[1024];
static char self[PATH_MAX];
static void
sappend(char *buf, size_t l, const char *fmt, ...)
@ -62,10 +64,76 @@ sappend(char *buf, size_t l, const char *fmt, ...)
/**
*
*/
static int
add2lineresolve(const char *binary, void *addr, char *buf0, size_t buflen)
{
char *buf = buf0;
int fd[2], r, f;
const char *argv[5];
pid_t p;
char addrstr[30], *cp;
argv[0] = "addr2line";
argv[1] = "-e";
argv[2] = binary;
argv[3] = addrstr;
argv[4] = NULL;
snprintf(addrstr, sizeof(addrstr), "%p", (void *)((intptr_t)addr-1));
if(pipe(fd) == -1)
return -1;
if((p = fork()) == -1)
return -1;
if(p == 0) {
close(0);
close(2);
close(fd[0]);
dup2(fd[1], 1);
close(fd[1]);
if((f = open("/dev/null", O_RDWR)) == -1)
exit(1);
dup2(f, 0);
dup2(f, 2);
close(f);
execve("/usr/bin/addr2line", (char *const *) argv, environ);
exit(2);
}
close(fd[1]);
*buf = 0;
while(buflen > 1) {
r = read(fd[0], buf, buflen);
if(r < 1)
break;
buf += r;
buflen -= r;
*buf = 0;
cp = strchr(buf0, '\n');
if(cp != NULL) {
*cp = 0;
break;
}
}
close(fd[0]);
return 0;
}
static void
traphandler(int sig, siginfo_t *si, void *UC)
{
ucontext_t *uc = UC;
char buf[200];
#if ENABLE_EXECINFO
static void *frames[MAXFRAMES];
int nframes = backtrace(frames, MAXFRAMES);
@ -122,6 +190,11 @@ traphandler(int sig, siginfo_t *si, void *UC)
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,
@ -153,6 +226,7 @@ extern const char *htsversion_full;
void
trap_init(const char *ver)
{
int r;
uint8_t digest[20];
struct sigaction sa, old;
char path[256];
@ -160,6 +234,11 @@ trap_init(const char *ver)
SHA_CTX binsum;
int fd;
r = readlink("/proc/self/exe", self, sizeof(self) - 1);
if(r == -1)
self[0] = 0;
else
self[r] = 0;
if((fd = open("/proc/self/exe", O_RDONLY)) != -1) {
struct stat st;