From 17eb20b22ef9fe5e621a4b6eff1c1a83e9489645 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 9 Aug 2017 13:30:34 -0400 Subject: [PATCH] log: Add log_callstack_to_file() This makes it trivial to log the callstack to, e.g., stderr, which can simplify debug cycles. --- src/nvim/README.md | 5 +++-- src/nvim/log.c | 25 ++++++++++++++++--------- src/nvim/log.h | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/nvim/README.md b/src/nvim/README.md index 1c1c3c364e..0caf71e2c5 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -11,8 +11,9 @@ Logs Low-level log messages sink to `$NVIM_LOG_FILE`. -You can use `LOG_CALLSTACK()` anywhere in the source to log the current -stacktrace. (Currently Linux-only.) +You can use `LOG_CALLSTACK();` anywhere in the source to log the current +stacktrace. To log in an alternate file, e.g. stderr, use +`LOG_CALLSTACK_TO_FILE(FILE*)`. (Currently Linux-only.) UI events are logged at level 0 (`DEBUG_LOG_LEVEL`). diff --git a/src/nvim/log.c b/src/nvim/log.c index b64aef3cac..3baf0b2ebd 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -178,7 +178,8 @@ FILE *open_log_file(void) } #ifdef HAVE_EXECINFO_BACKTRACE -void log_callstack(const char *const func_name, const int line_num) +void log_callstack_to_file(FILE *log_file, const char *const func_name, + const int line_num) { void *trace[100]; int trace_size = backtrace(trace, ARRAY_SIZE(trace)); @@ -190,8 +191,6 @@ void log_callstack(const char *const func_name, const int line_num) } assert(24 + exepathlen < IOSIZE); // Must fit in `cmdbuf` below. - do_log(DEBUG_LOG_LEVEL, func_name, line_num, true, "trace:"); - char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace))]; snprintf(cmdbuf, sizeof(cmdbuf), "addr2line -e %s -f -p", exepath); for (int i = 1; i < trace_size; i++) { @@ -202,12 +201,8 @@ void log_callstack(const char *const func_name, const int line_num) // Now we have a command string like: // addr2line -e /path/to/exe -f -p 0x123 0x456 ... - log_lock(); - FILE *log_file = open_log_file(); - if (log_file == NULL) { - goto end; - } - + do_log_to_file(log_file, DEBUG_LOG_LEVEL, func_name, line_num, true, + "trace:"); FILE *fp = popen(cmdbuf, "r"); char linebuf[IOSIZE]; while (fgets(linebuf, sizeof(linebuf) - 1, fp) != NULL) { @@ -218,6 +213,18 @@ void log_callstack(const char *const func_name, const int line_num) if (log_file != stderr && log_file != stdout) { fclose(log_file); } +} + +void log_callstack(const char *const func_name, const int line_num) +{ + log_lock(); + FILE *log_file = open_log_file(); + if (log_file == NULL) { + goto end; + } + + log_callstack_to_file(log_file, func_name, line_num); + end: log_unlock(); } diff --git a/src/nvim/log.h b/src/nvim/log.h index 743a8d17aa..5064d9333b 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -63,6 +63,7 @@ #ifdef HAVE_EXECINFO_BACKTRACE # define LOG_CALLSTACK() log_callstack(__func__, __LINE__) +# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) #endif #ifdef INCLUDE_GENERATED_DECLARATIONS