This libbacktrace patch improves backtrace_print when there is no
debug info.  It falls back to calling backtrace_syminfo, and uses that
to print an offset from a symbol if it can.  This is a partial fix for
https://github.com/ianlancetaylor/libbacktrace/issues/59.
Bootstrapped and ran libbacktrace testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* print.c (print_syminfo_callback): New static function.
(print_callback): Call backtrace_syminfo if there is no function
or file name.
4dbb53eb10767d111228224ae3113aee0d4d6213
diff --git a/libbacktrace/print.c b/libbacktrace/print.c
index 3e61f02ebbc..70f5a93c49d 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))

Reply via email to