From 35ea6a5a054d61cbcd1db680439f03d152e5a5b4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 5 Oct 2011 19:41:40 -0700 Subject: [PATCH] log: Add support for backtrace symbole resolving --- src/log.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- src/main.c | 2 +- src/ofono.h | 2 +- 3 files changed, 112 insertions(+), 17 deletions(-) diff --git a/src/log.c b/src/log.c index c31a76c..84710f0 100644 --- a/src/log.c +++ b/src/log.c @@ -24,14 +24,20 @@ #endif #define _GNU_SOURCE +#include +#include #include -#include #include +#include +#include #include #include #include "ofono.h" +static const char *program_exec; +static const char *program_path; + /** * ofono_info: * @format: format string @@ -107,30 +113,115 @@ void ofono_debug(const char *format, ...) va_end(ap); } -static void signal_handler(int signo) +static void print_backtrace(unsigned int offset) { - void *frames[64]; - char **symbols; + void *frames[99]; size_t n_ptrs; unsigned int i; + int outfd[2], infd[2]; + int pathlen; + pid_t pid; + + if (program_exec == NULL) + return; + + pathlen = strlen(program_path); n_ptrs = backtrace(frames, G_N_ELEMENTS(frames)); - symbols = backtrace_symbols(frames, n_ptrs); - if (symbols == NULL) { - ofono_error("No backtrace symbols"); - exit(1); + if (n_ptrs < offset) + return; + + if (pipe(outfd) < 0) + return; + + if (pipe(infd) < 0) { + close(outfd[0]); + close(outfd[1]); + return; + } + + pid = fork(); + if (pid < 0) { + close(outfd[0]); + close(outfd[1]); + close(infd[0]); + close(infd[1]); + return; + } + + if (pid == 0) { + close(outfd[1]); + close(infd[0]); + + dup2(outfd[0], STDIN_FILENO); + dup2(infd[1], STDOUT_FILENO); + + execlp("addr2line", "-C", "-f", "-e", program_exec, NULL); + + exit(EXIT_FAILURE); } - ofono_error("Aborting (signal %d)", signo); + close(outfd[0]); + close(infd[1]); + ofono_error("++++++++ backtrace ++++++++"); - for (i = 1; i < n_ptrs; i++) - ofono_error("[%d]: %s", i - 1, symbols[i]); + for (i = offset; i < n_ptrs - 1; i++) { + Dl_info info; + char addr[20], buf[PATH_MAX * 2]; + int len, written; + char *ptr, *pos; + + dladdr(frames[i], &info); + + len = snprintf(addr, sizeof(addr), "%p\n", frames[i]); + if (len < 0) + break; + + written = write(outfd[1], addr, len); + if (written < 0) + break; + + len = read(infd[0], buf, sizeof(buf)); + if (len < 0) + break; + + buf[len] = '\0'; + + pos = strchr(buf, '\n'); + *pos++ = '\0'; + + if (strcmp(buf, "??") == 0) { + ofono_error("#%-2u %p in %s", i - offset, + frames[i], info.dli_fname); + continue; + } + + ptr = strchr(pos, '\n'); + *ptr++ = '\0'; + + if (strncmp(pos, program_path, pathlen) == 0) + pos += pathlen + 1; + + ofono_error("#%-2u %p in %s() at %s", i - offset, + frames[i], buf, pos); + } ofono_error("+++++++++++++++++++++++++++"); - g_free(symbols); - exit(1); + kill(pid, SIGTERM); + + close(outfd[1]); + close(infd[0]); +} + +static void signal_handler(int signo) +{ + ofono_error("Aborting (signal %d) [%s]", signo, program_exec); + + print_backtrace(2); + + exit(EXIT_FAILURE); } static void signal_setup(sighandler_t handler) @@ -197,10 +288,14 @@ void __ofono_log_enable(struct ofono_debug_desc *start, } } -int __ofono_log_init(const char *debug, ofono_bool_t detach) +int __ofono_log_init(const char *exe, const char *debug, ofono_bool_t detach) { + static char path[PATH_MAX]; int option = LOG_NDELAY | LOG_PID; + program_exec = exe; + program_path = getcwd(path, sizeof(path)); + if (debug != NULL) enabled = g_strsplit_set(debug, ":, ", 0); @@ -211,7 +306,7 @@ int __ofono_log_init(const char *debug, ofono_bool_t detach) signal_setup(signal_handler); - openlog("ofonod", option, LOG_DAEMON); + openlog(basename(exe), option, LOG_DAEMON); syslog(LOG_INFO, "oFono version %s", VERSION); diff --git a/src/main.c b/src/main.c index e6233f0..b88b538 100644 --- a/src/main.c +++ b/src/main.c @@ -226,7 +226,7 @@ int main(int argc, char **argv) signal = setup_signalfd(); - __ofono_log_init(option_debug, option_detach); + __ofono_log_init(argv[0], option_debug, option_detach); dbus_error_init(&error); diff --git a/src/ofono.h b/src/ofono.h index a5995b0..a25299d 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -34,7 +34,7 @@ void __ofono_modem_shutdown(void); #include -int __ofono_log_init(const char *debug, ofono_bool_t detach); +int __ofono_log_init(const char *exe, const char *debug, ofono_bool_t detach); void __ofono_log_cleanup(void); void __ofono_log_enable(struct ofono_debug_desc *start, struct ofono_debug_desc *stop); -- 2.7.4