aboutsummaryrefslogtreecommitdiff
path: root/libbacktrace/print.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2024-07-17 17:36:25 -0700
committerIan Lance Taylor <iant@golang.org>2024-07-17 17:39:27 -0700
commit30875fa698e2ffed536f7a7d15a430e69a6a28ba (patch)
treee48dc6b2f6572a2329f9053ff305d5d52c3d958d /libbacktrace/print.c
parenta922de0a7a310a6237aab87582baa09e15a36a0f (diff)
downloadgcc-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.c55
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))