From 30875fa698e2ffed536f7a7d15a430e69a6a28ba Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 17 Jul 2024 17:36:25 -0700 Subject: [PATCH] libbacktrace: better backtrace_print when no debug info Fixes https://github.com/ianlancetaylor/libbacktrace/issues/59 * print.c (print_syminfo_callback): New static function. (print_callback): Call backtrace_syminfo if there is no function or file name. --- libbacktrace/print.c | 57 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/libbacktrace/print.c b/libbacktrace/print.c index 3e61f02ebbc..70f5a93c49d 100644 --- a/libbacktrace/print.c +++ b/libbacktrace/print.c @@ -47,22 +47,6 @@ struct print_data FILE *f; }; -/* Print one level of a backtrace. */ - -static int -print_callback (void *data, uintptr_t pc, const char *filename, int lineno, - const char *function) -{ - struct print_data *pdata = (struct print_data *) data; - - fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n", - (unsigned long) pc, - function == NULL ? "???" : function, - filename == NULL ? "???" : filename, - lineno); - return 0; -} - /* Print errors to stderr. */ static void @@ -78,6 +62,47 @@ error_callback (void *data, const char *msg, int errnum) fputc ('\n', stderr); } +/* Print one level of a backtrace if we couldn't get a file or function name. + Use syminfo to try to get a symbol name. */ + +static void print_syminfo_callback (void *data, uintptr_t pc, + const char *symname, uintptr_t symval, + uintptr_t symsize ATTRIBUTE_UNUSED) +{ + struct print_data *pdata = (struct print_data *) data; + + if (symname == NULL) + fprintf (pdata->f, "0x%lx ???\n\t???:0\n", (unsigned long) pc); + else + fprintf (pdata->f, "0x%lx ???\n\t%s+0x%lx:0\n", + (unsigned long) pc, + symname, + pc - symval); +} + +/* Print one level of a backtrace. */ + +static int +print_callback (void *data, uintptr_t pc, const char *filename, int lineno, + const char *function) +{ + struct print_data *pdata = (struct print_data *) data; + + if (function == NULL && filename == NULL) + { + backtrace_syminfo (pdata->state, pc, print_syminfo_callback, + error_callback, data); + return 0; + } + + fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n", + (unsigned long) pc, + function == NULL ? "???" : function, + filename == NULL ? "???" : filename, + lineno); + return 0; +} + /* Print a backtrace. */ void __attribute__((noinline))