#include <string.h>
#include <signal.h>
#include <ucontext.h>
+#include <limits.h>
#if ENABLE_EXECINFO
#include <execinfo.h>
#endif
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, ...)
+/**
+ *
+ */
+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);
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,
void
trap_init(const char *ver)
{
+ int r;
uint8_t digest[20];
struct sigaction sa, old;
char path[256];
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;