Better backtraces thanks to addr2link
This commit is contained in:
parent
d7e4dc376b
commit
a629798b62
1 changed files with 79 additions and 0 deletions
79
src/trap.c
79
src/trap.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue