From 9e10af0e8f90f0152b568d0c7569d3cdc52fb0cf 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 #59 * print.c (print_syminfo_callback): New static function. (print_callback): Call backtrace_syminfo if there is no function or file name. --- print.c | 57 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/print.c b/print.c index 3e61f02..70f5a93 100644 --- a/print.c +++ b/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))