diff options
author | Ian Lance Taylor <iant@golang.org> | 2024-07-17 17:36:25 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2024-07-17 17:39:27 -0700 |
commit | 30875fa698e2ffed536f7a7d15a430e69a6a28ba (patch) | |
tree | e48dc6b2f6572a2329f9053ff305d5d52c3d958d /libbacktrace/print.c | |
parent | a922de0a7a310a6237aab87582baa09e15a36a0f (diff) | |
download | gcc-30875fa698e2ffed536f7a7d15a430e69a6a28ba.zip gcc-30875fa698e2ffed536f7a7d15a430e69a6a28ba.tar.gz gcc-30875fa698e2ffed536f7a7d15a430e69a6a28ba.tar.bz2 |
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.
Diffstat (limited to 'libbacktrace/print.c')
-rw-r--r-- | libbacktrace/print.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/libbacktrace/print.c b/libbacktrace/print.c index 3e61f02..70f5a93 100644 --- a/libbacktrace/print.c +++ b/libbacktrace/print.c @@ -47,6 +47,39 @@ struct print_data FILE *f; }; +/* Print errors to stderr. */ + +static void +error_callback (void *data, const char *msg, int errnum) +{ + struct print_data *pdata = (struct print_data *) data; + + if (pdata->state->filename != NULL) + fprintf (stderr, "%s: ", pdata->state->filename); + fprintf (stderr, "libbacktrace: %s", msg); + if (errnum > 0) + fprintf (stderr, ": %s", strerror (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 @@ -55,6 +88,13 @@ print_callback (void *data, uintptr_t pc, const char *filename, int lineno, { 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, @@ -63,21 +103,6 @@ print_callback (void *data, uintptr_t pc, const char *filename, int lineno, return 0; } -/* Print errors to stderr. */ - -static void -error_callback (void *data, const char *msg, int errnum) -{ - struct print_data *pdata = (struct print_data *) data; - - if (pdata->state->filename != NULL) - fprintf (stderr, "%s: ", pdata->state->filename); - fprintf (stderr, "libbacktrace: %s", msg); - if (errnum > 0) - fprintf (stderr, ": %s", strerror (errnum)); - fputc ('\n', stderr); -} - /* Print a backtrace. */ void __attribute__((noinline)) |