public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ian Lance Taylor <iant@golang.org>
To: Alex Coplan <alex.coplan@arm.com>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: libbacktrace: Add support for MiniDebugInfo
Date: Wed, 16 Sep 2020 17:04:54 -0700	[thread overview]
Message-ID: <CAOyqgcV_gx-JHm3_hB+AR_=ZQE2-2cKUUN+XMhLS8q60xAdkUw@mail.gmail.com> (raw)
In-Reply-To: <20200916155402.w2krbi4brg2qp6h4@arm.com>

[-- Attachment #1: Type: text/plain, Size: 2603 bytes --]

On Wed, Sep 16, 2020 at 8:54 AM Alex Coplan <alex.coplan@arm.com> wrote:
>
> On 16/09/2020 07:26, Ian Lance Taylor wrote:
> > On Wed, Sep 16, 2020, 4:03 AM Alex Coplan <alex.coplan@arm.com> wrote:
> >
> > > Hi Ian,
> > >
> > > On 14/09/2020 14:12, Ian Lance Taylor via Gcc-patches wrote:
> > > > This patch to libbacktrace adds support for MiniDebugInfo, as
> > > > requested in PR 93608.
> > >
> > > This appears to introduce a failure in the libbacktrace testsuite
> > > (observed on both x86 and aarch64):
> > >
> > > ../gcc/libbacktrace/../test-driver: line 107:  7905 Segmentation fault
> > >   (core dumped) "$@" > $log_file 2>&1
> > > FAIL: mtest_minidebug
> >
> >
> >
> > I tested on x86 without seeing anything like this.  Can you give me any
> > more details?  Thanks.
>
> Sure. On an Ubuntu 18.04 / x86-64 system with current trunk, configuring
> with:
>
> ~/toolchain/src/gcc/configure \
>   --prefix=`pwd` \
>   --enable-languages=c,c++ \
>   --disable-multilib \
>   --disable-bootstrap
>
> running `make && make check-libbacktrace` gives the failure described
> above. Here is the contents of libbacktrace/test-suite.log:
>
> =====================================================
> package-unused version-unused: ./test-suite.log
> =====================================================
>
> # TOTAL: 33
> # PASS:  32
> # SKIP:  0
> # XFAIL: 0
> # FAIL:  1
> # XPASS: 0
> # ERROR: 0
>
> .. contents:: :depth: 2
>
> FAIL: mtest_minidebug
> =====================
>
> no debug info in ELF executable
> no debug info in ELF executable
> no debug info in ELF executable
> no debug info in ELF executable
> no debug info in ELF executable
> no debug info in ELF executable
> no debug info in ELF executable
> test1: not enough frames; got 0, expected at least 3
> test1: [0]: got  expected f3
> test1: [1]: got  expected f2
> FAIL mtest_minidebug (exit status: 139)
>
> ---
>
> Let me know if you need any more info.


Thanks.  I think the problem arises when libbacktrace is unable to
find debug info for any shared library involved in the link.

This patch should fix it.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu and aarch64-linux-gnu.  Committed to mainline.

Ian

PR libbacktrace/97080
* fileline.c (backtrace_syminfo_to_full_callback): New function.
(backtrace_syminfo_to_full_error_callback): New function.
* elf.c (elf_nodebug): Call syminfo_fn if possible.
* internal.h (struct backtrace_call_full): Define.
(backtrace_syminfo_to_full_callback): Declare.
(backtrace_syminfo_to_full_error_callback): Declare.
* mtest.c (f3): Only check all[i] if data.index permits.

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 6346 bytes --]

diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index dd004708246..941f820d944 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -547,18 +547,6 @@ elf_crc32_file (struct backtrace_state *state, int descriptor,
   return ret;
 }
 
-/* A dummy callback function used when we can't find any debug info.  */
-
-static int
-elf_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
-	     uintptr_t pc ATTRIBUTE_UNUSED,
-	     backtrace_full_callback callback ATTRIBUTE_UNUSED,
-	     backtrace_error_callback error_callback, void *data)
-{
-  error_callback (data, "no debug info in ELF executable", -1);
-  return 0;
-}
-
 /* A dummy callback function used when we can't find a symbol
    table.  */
 
@@ -571,6 +559,33 @@ elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
   error_callback (data, "no symbol table in ELF executable", -1);
 }
 
+/* A callback function used when we can't find any debug info.  */
+
+static int
+elf_nodebug (struct backtrace_state *state, uintptr_t pc,
+	     backtrace_full_callback callback,
+	     backtrace_error_callback error_callback, void *data)
+{
+  if (state->syminfo_fn != NULL && state->syminfo_fn != elf_nosyms)
+    {
+      struct backtrace_call_full bdata;
+
+      /* Fetch symbol information so that we can least get the
+	 function name.  */
+
+      bdata.full_callback = callback;
+      bdata.full_error_callback = error_callback;
+      bdata.full_data = data;
+      bdata.ret = 0;
+      state->syminfo_fn (state, pc, backtrace_syminfo_to_full_callback,
+			 backtrace_syminfo_to_full_error_callback, &bdata);
+      return bdata.ret;
+    }
+
+  error_callback (data, "no debug info in ELF executable", -1);
+  return 0;
+}
+
 /* Compare struct elf_symbol for qsort.  */
 
 static int
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index be62b9899c5..cd1e10dd58c 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -317,3 +317,30 @@ backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
   state->syminfo_fn (state, pc, callback, error_callback, data);
   return 1;
 }
+
+/* A backtrace_syminfo_callback that can call into a
+   backtrace_full_callback, used when we have a symbol table but no
+   debug info.  */
+
+void
+backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
+				    const char *symname,
+				    uintptr_t symval ATTRIBUTE_UNUSED,
+				    uintptr_t symsize ATTRIBUTE_UNUSED)
+{
+  struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
+
+  bdata->ret = bdata->full_callback (bdata->full_data, pc, NULL, 0, symname);
+}
+
+/* An error callback that corresponds to
+   backtrace_syminfo_to_full_callback.  */
+
+void
+backtrace_syminfo_to_full_error_callback (void *data, const char *msg,
+					  int errnum)
+{
+  struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
+
+  bdata->full_error_callback (bdata->full_data, msg, errnum);
+}
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 09862337456..047a700c0ce 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -326,6 +326,31 @@ extern int backtrace_dwarf_add (struct backtrace_state *state,
 				void *data, fileline *fileline_fn,
 				struct dwarf_data **fileline_entry);
 
+/* A data structure to pass to backtrace_syminfo_to_full.  */
+
+struct backtrace_call_full
+{
+  backtrace_full_callback full_callback;
+  backtrace_error_callback full_error_callback;
+  void *full_data;
+  int ret;
+};
+
+/* A backtrace_syminfo_callback that can call into a
+   backtrace_full_callback, used when we have a symbol table but no
+   debug info.  */
+
+extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
+						const char *symname,
+						uintptr_t symval,
+						uintptr_t symsize);
+
+/* An error callback that corresponds to
+   backtrace_syminfo_to_full_callback.  */
+
+extern void backtrace_syminfo_to_full_error_callback (void *, const char *,
+						      int);
+
 /* A test-only hook for elf_uncompress_zdebug.  */
 
 extern int backtrace_uncompress_zdebug (struct backtrace_state *,
diff --git a/libbacktrace/mtest.c b/libbacktrace/mtest.c
index d90fd1e33cc..d73c98d44f8 100644
--- a/libbacktrace/mtest.c
+++ b/libbacktrace/mtest.c
@@ -156,40 +156,49 @@ f3 (int f1line __attribute__ ((unused)), int f2line __attribute__ ((unused)))
 	}
     }
 
-  if (all[0].function == NULL)
+  if (data.index > 0)
     {
-      fprintf (stderr, "test1: [0]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[0].function, "f3") != 0)
-    {
-      fprintf (stderr, "test1: [0]: got %s expected %s\n",
-	       all[0].function, "f3");
-      data.failed = 1;
+      if (all[0].function == NULL)
+	{
+	  fprintf (stderr, "test1: [0]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[0].function, "f3") != 0)
+	{
+	  fprintf (stderr, "test1: [0]: got %s expected %s\n",
+		   all[0].function, "f3");
+	  data.failed = 1;
+	}
     }
 
-  if (all[1].function == NULL)
-    {
-      fprintf (stderr, "test1: [1]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[1].function, "f2") != 0)
+  if (data.index > 1)
     {
-      fprintf (stderr, "test1: [1]: got %s expected %s\n",
-	       all[0].function, "f2");
-      data.failed = 1;
+      if (all[1].function == NULL)
+	{
+	  fprintf (stderr, "test1: [1]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[1].function, "f2") != 0)
+	{
+	  fprintf (stderr, "test1: [1]: got %s expected %s\n",
+		   all[0].function, "f2");
+	  data.failed = 1;
+	}
     }
 
-  if (all[2].function == NULL)
-    {
-      fprintf (stderr, "test1: [2]: missing function name\n");
-      data.failed = 1;
-    }
-  else if (strcmp (all[2].function, "test1") != 0)
+  if (data.index > 2)
     {
-      fprintf (stderr, "test1: [2]: got %s expected %s\n",
-	       all[0].function, "test1");
-      data.failed = 1;
+      if (all[2].function == NULL)
+	{
+	  fprintf (stderr, "test1: [2]: missing function name\n");
+	  data.failed = 1;
+	}
+      else if (strcmp (all[2].function, "test1") != 0)
+	{
+	  fprintf (stderr, "test1: [2]: got %s expected %s\n",
+		   all[0].function, "test1");
+	  data.failed = 1;
+	}
     }
 
   printf ("%s: backtrace_full noinline\n", data.failed ? "FAIL" : "PASS");

      reply	other threads:[~2020-09-17  0:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-14 21:12 Ian Lance Taylor
2020-09-16 11:03 ` Alex Coplan
2020-09-16 14:26   ` Ian Lance Taylor
2020-09-16 15:54     ` Alex Coplan
2020-09-17  0:04       ` Ian Lance Taylor [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOyqgcV_gx-JHm3_hB+AR_=ZQE2-2cKUUN+XMhLS8q60xAdkUw@mail.gmail.com' \
    --to=iant@golang.org \
    --cc=alex.coplan@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).