From: Adam Dickmeiss Date: Tue, 18 Nov 2014 13:50:57 +0000 (+0100) Subject: Backtrace using addr2line to get filename + lineno info X-Git-Url: http://lists.indexdata.dk/?a=commitdiff_plain;h=254bb5f2d9c6d57778a79dd9db6326555e1a582e;p=yaz-moved-to-github.git Backtrace using addr2line to get filename + lineno info --- diff --git a/src/backtrace.c b/src/backtrace.c index ec1d9be..840d2c5 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -35,7 +35,7 @@ #include #endif -#define BACKTRACE_SZ 1000 +#define BACKTRACE_SZ 100 void yaz_invoke_backtrace(char *buf, int buf_sz) { @@ -64,8 +64,70 @@ void yaz_invoke_backtrace(char *buf, int buf_sz) backtrace_info[i], backtrace_str[i]); } } -#endif write(fd, buf, strlen(buf)); + + if (backtrace_str) + { + pid_t pid; + const char *cp = "-----------\n"; + write(fd, cp, strlen(cp)); + + pid = fork(); + if (pid == (pid_t) (-1)) + { /* error */ + const char *cp = "backtrace: fork failure"; + write(fd, cp, strlen(cp)); + } + else if (pid == 0) + { /* child */ + int i; + char *arg[BACKTRACE_SZ + 4]; + int arg_no = 0; + char *cp; + + close(0); + dup(fd); + close(1); + dup(fd); + if (fd != 2) + { + close(2); + dup(fd); + } + arg[arg_no++] = "addr2line"; + arg[arg_no++] = "-paf"; + arg[arg_no++] = "-e"; + arg[arg_no++] = backtrace_str[0]; + cp = strchr(backtrace_str[0], '('); + if (cp) + *cp = '\0'; + + for (i = 1; i < sz; i++) + { + cp = strchr(backtrace_str[i], '['); + if (cp) + arg[arg_no++] = cp + 1; + } + arg[arg_no] = 0; + execv("/usr/bin/addr2line", arg); + _exit(1); + } + else + { /* parent */ + int status; + waitpid(pid, &status, 0); + if (status) + { + char msg[100]; + sprintf(msg, "backtrace: exit status=%d\n", status); + write(fd, msg, strlen(msg)); + } + } + } +#else + strcat(buf, "no backtrace support (execinfo.h not found)\n"); + write(fd, buf, strlen(buf)); +#endif } void yaz_panic_sig_handler(int sig) @@ -98,10 +160,12 @@ void yaz_panic_sig_handler(int sig) void yaz_enable_panic_backtrace(void) { +#if HAVE_EXECINFO_H signal(SIGABRT, yaz_panic_sig_handler); signal(SIGSEGV, yaz_panic_sig_handler); signal(SIGFPE, yaz_panic_sig_handler); signal(SIGBUS, yaz_panic_sig_handler); +#endif } /*