From: Martin Willi Date: Mon, 4 Mar 2013 14:45:03 +0000 (+0100) Subject: backtrace_t.log() takes a NULL file pointer to log to registered dbg() hook X-Git-Tag: 5.0.3dr3~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe03f51302bfd70c26aba53bf17c268e522de99e;p=thirdparty%2Fstrongswan.git backtrace_t.log() takes a NULL file pointer to log to registered dbg() hook --- diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c index 226237362c..05851c2b7f 100644 --- a/src/libstrongswan/utils/backtrace.c +++ b/src/libstrongswan/utils/backtrace.c @@ -27,6 +27,8 @@ #include "backtrace.h" +#include + typedef struct private_backtrace_t private_backtrace_t; /** @@ -50,6 +52,40 @@ struct private_backtrace_t { void *frames[]; }; +/** + * Same as tty_escape_get(), but for a potentially NULL FILE* + */ +static char* esc(FILE *file, tty_escape_t escape) +{ + if (file) + { + return tty_escape_get(fileno(file), escape); + } + return ""; +} + +/** + * Write a format string with arguments to a FILE line, if it is NULL to DBG + */ +static void println(FILE *file, char *format, ...) +{ + char buf[512]; + va_list args; + + va_start(args, format); + if (file) + { + vfprintf(file, format, args); + fputs("\n", file); + } + else + { + vsnprintf(buf, sizeof(buf), format, args); + DBG1(DBG_LIB, "%s", buf); + } + va_end(args); +} + #ifdef HAVE_DLADDR #ifdef HAVE_BFD_H @@ -158,6 +194,7 @@ static void find_addr(bfd *abfd, asection *section, bfd_find_data_t *data) bfd_vma vma; const char *source; const char *function; + char fbuf[512] = "", sbuf[512] = ""; u_int line; if (!data->found || (bfd_get_section_flags(abfd, section) & SEC_ALLOC) != 0) @@ -175,21 +212,18 @@ static void find_addr(bfd *abfd, asection *section, bfd_find_data_t *data) { if (source || function) { - fprintf(data->file, " -> "); if (function) { - fprintf(data->file, "%s%s() ", - tty_escape_get(fileno(data->file), TTY_FG_BLUE), - function); + snprintf(fbuf, sizeof(fbuf), "%s%s() ", + esc(data->file, TTY_FG_BLUE), function); } if (source) { - fprintf(data->file, "%s@ %s:%d", - tty_escape_get(fileno(data->file), TTY_FG_GREEN), - source, line); + snprintf(sbuf, sizeof(sbuf), "%s@ %s:%d", + esc(data->file, TTY_FG_GREEN), source, line); } - fprintf(data->file, "%s\n", - tty_escape_get(fileno(data->file), TTY_FG_DEF)); + println(data->file, " -> %s%s%s", fbuf, sbuf, + esc(data->file, TTY_FG_DEF)); } } } @@ -301,26 +335,28 @@ void backtrace_deinit() {} */ static void print_sourceline(FILE *file, char *filename, void *ptr) { - char cmd[1024]; + char buf[1024]; FILE *output; - int c; + int c, i = 0; - snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", filename, ptr); - output = popen(cmd, "r"); + snprintf(buf, sizeof(buf), "addr2line -e %s %p", filename, ptr); + output = popen(buf, "r"); if (output) { - fprintf(file, " -> %s", tty_escape_get(fileno(file), TTY_FG_GREEN)); - while (TRUE) + while (i < sizeof(buf)) { c = getc(output); if (c == '\n' || c == EOF) { + buf[i++] = 0; break; } - fputc(c, file); + buf[i++] = c; } pclose(output); - fprintf(file, "%s\n", tty_escape_get(fileno(file), TTY_FG_DEF)); + + println(file, " -> %s%s%s", esc(file, TTY_FG_GREEN), buf, + esc(file, TTY_FG_DEF)); } } @@ -342,7 +378,7 @@ METHOD(backtrace_t, log_, void, strings = backtrace_symbols(this->frames, this->frame_count); - fprintf(file, " dumping %d stack frame addresses:\n", this->frame_count); + println(file, " dumping %d stack frame addresses:", this->frame_count); for (i = 0; i < this->frame_count; i++) { #ifdef HAVE_DLADDR @@ -358,19 +394,18 @@ METHOD(backtrace_t, log_, void, } if (info.dli_sname) { - fprintf(file, " %s%s%s @ %p (%s%s%s+0x%tx) [%p]\n", - tty_escape_get(fileno(file), TTY_FG_YELLOW), info.dli_fname, - tty_escape_get(fileno(file), TTY_FG_DEF), info.dli_fbase, - tty_escape_get(fileno(file), TTY_FG_RED), info.dli_sname, - tty_escape_get(fileno(file), TTY_FG_DEF), - this->frames[i] - info.dli_saddr, this->frames[i]); + println(file, " %s%s%s @ %p (%s%s%s+0x%tx) [%p]", + esc(file, TTY_FG_YELLOW), info.dli_fname, + esc(file, TTY_FG_DEF), info.dli_fbase, + esc(file, TTY_FG_RED), info.dli_sname, + esc(file, TTY_FG_DEF), this->frames[i] - info.dli_saddr, + this->frames[i]); } else { - fprintf(file, " %s%s%s @ %p [%p]\n", - tty_escape_get(fileno(file), TTY_FG_YELLOW), info.dli_fname, - tty_escape_get(fileno(file), TTY_FG_DEF), info.dli_fbase, - this->frames[i]); + println(file, " %s%s%s @ %p [%p]", + esc(file, TTY_FG_YELLOW), info.dli_fname, + esc(file, TTY_FG_DEF), info.dli_fbase, this->frames[i]); } if (detailed) { @@ -380,12 +415,12 @@ METHOD(backtrace_t, log_, void, else #endif /* HAVE_DLADDR */ { - fprintf(file, " %s\n", strings[i]); + println(file, " %s", strings[i]); } } free (strings); #else /* !HAVE_BACKTRACE */ - fprintf(file, "C library does not support backtrace().\n"); + println(file, "C library does not support backtrace()."); #endif /* HAVE_BACKTRACE */ } @@ -521,7 +556,7 @@ void backtrace_dump(char *label, FILE *file, bool detailed) if (label) { - fprintf(file, "Debug backtrace: %s\n", label); + println(file, "Debug backtrace: %s", label); } backtrace->log(backtrace, file, detailed); backtrace->destroy(backtrace); diff --git a/src/libstrongswan/utils/backtrace.h b/src/libstrongswan/utils/backtrace.h index aeeba4dd61..62104238dc 100644 --- a/src/libstrongswan/utils/backtrace.h +++ b/src/libstrongswan/utils/backtrace.h @@ -35,7 +35,10 @@ struct backtrace_t { /** * Log the backtrace to a FILE stream. * - * @param file FILE to log backtrace to + * If no file pointer is given, the backtrace is reported over the debug + * framework to the registered dbg() callback function. + * + * @param file FILE to log backtrace to, NULL for dbg() function * @param detailed TRUE to resolve line/file using addr2line (slow) */ void (*log)(backtrace_t *this, FILE *file, bool detailed); @@ -81,7 +84,7 @@ backtrace_t *backtrace_create(int skip); * Create a backtrace, dump it and clean it up. * * @param label description to print for this backtrace, or NULL - * @param file FILE to log backtrace to + * @param file FILE to log backtrace to, NULL to dbg() function * @param detailed TRUE to resolve line/file using addr2line (slow) */ void backtrace_dump(char *label, FILE *file, bool detailed);