public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Cc: lsix@lancelotsix.com, simark@simark.ca,
	Kevin Buettner <kevinb@redhat.com>
Subject: [PATCH v3 1/2] Suppress printing of superfluous BFD error messages
Date: Wed,  7 Sep 2022 18:58:11 -0700	[thread overview]
Message-ID: <20220908015812.12175-2-kevinb@redhat.com> (raw)
In-Reply-To: <20220908015812.12175-1-kevinb@redhat.com>

This commit adds a hook to the BFD error handler for suppressing
identical messages which have been output once already.

It's motivated by this Fedora bug...

https://bugzilla.redhat.com/show_bug.cgi?id=2083315

...in which over 900,000 BFD error messages are output when attaching
to firefox.  From the bug report, the messages all say:

BFD: /usr/lib/debug/usr/lib64/firefox/libxul.so-100.0-2.fc35.x86_64.debug: attempt to load strings from a non-string section (number 38)

Since there's no (additional) context which might assist the user in
determining what's wrong, there's really no point in outputting more
than one message.  Of course, if BFD should output some
other/different message, it should be output too, but all future
messages identical to those already output should be suppressed.

For the firefox problem, it turned out that there were only 37
sections, but something was referring to section #38.  I haven't
investigated further to find out how this came to be.

Despite this problem, useful debugging might still be done, especially
if the user doesn't care about debugging the problematic library.

If it turns out that knowing the quantity of messages might be useful,
I've implemented the suppression mechanism by keeping a count of each
identical message.  A new GDB command, perhaps a 'maintenance'
command, could be added to print out each message along with the
count.  I haven't implemented this though because I'm not convinced of
its utility.  Also, the BFD message printer has support for BFD-
specific format specifiers.  The BFD message strings that GDB stores
in its map are sufficient for distinguishing messages from each
other, but are not identical to those output by BFD's default error
handler.  So, that problem would need to be solved too.
---
 gdb/gdb_bfd.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index 6c03ae5ef05..6299148d419 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -33,6 +33,7 @@
 #include "gdb/fileio.h"
 #include "inferior.h"
 #include "cli/cli-style.h"
+#include <unordered_map>
 
 /* An object of this type is stored in the section's user data when
    mapping a section.  */
@@ -1125,6 +1126,69 @@ maintenance_info_bfds (const char *arg, int from_tty)
   htab_traverse (all_bfds, print_one_bfd, uiout);
 }
 
+/* BFD related per-inferior data.  */
+
+struct bfd_inferior_data
+{
+  std::unordered_map<std::string, unsigned long> bfd_error_string_counts;
+};
+
+/* Per-inferior data key.  */
+
+static const registry<inferior>::key<bfd_inferior_data> bfd_inferior_data_key;
+
+/* Fetch per-inferior BFD data.  It always returns a valid pointer to
+   a bfd_inferior_data struct.  */
+
+static struct bfd_inferior_data *
+get_bfd_inferior_data (struct inferior *inf)
+{
+  struct bfd_inferior_data *data;
+
+  data = bfd_inferior_data_key.get (inf);
+  if (data == nullptr)
+    data = bfd_inferior_data_key.emplace (inf);
+
+  return data;
+}
+
+/* Increment the BFD error count for STR and return the updated
+   count.  */
+
+static unsigned long
+increment_bfd_error_count (std::string str)
+{
+  struct bfd_inferior_data *bid = get_bfd_inferior_data (current_inferior ());
+
+  auto &map = bid->bfd_error_string_counts;
+  return ++map[std::move (str)];
+}
+
+static bfd_error_handler_type default_bfd_error_handler;
+
+/* Define a BFD error handler which will suppress the printing of
+   messages which have been printed once already.  This is done on a
+   per-inferior basis.  */
+
+static void
+gdb_bfd_error_handler (const char *fmt, va_list ap)
+{
+  va_list ap_copy;
+
+  va_copy(ap_copy, ap);
+  const std::string str = string_vprintf (fmt, ap_copy);
+  va_end (ap_copy);
+
+  if (increment_bfd_error_count (std::move (str)) > 1)
+    return;
+
+  /* We must call the BFD mechanism for printing format strings since
+     it supports additional format specifiers that GDB's vwarning() doesn't
+     recognize.  It also outputs additional text, i.e. "BFD: ", which
+     makes it clear that it's a BFD warning/error.  */
+  (*default_bfd_error_handler) (fmt, ap);
+}
+
 void _initialize_gdb_bfd ();
 void
 _initialize_gdb_bfd ()
@@ -1157,4 +1221,7 @@ When non-zero, bfd cache specific debugging is enabled."),
 			   NULL,
 			   &show_bfd_cache_debug,
 			   &setdebuglist, &showdebuglist);
+
+  /* Hook the BFD error/warning handler to limit amount of output.  */
+  default_bfd_error_handler = bfd_set_error_handler (gdb_bfd_error_handler);
 }
-- 
2.37.3


  reply	other threads:[~2022-09-08  1:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-08  1:58 [PATCH v3 0/2] " Kevin Buettner
2022-09-08  1:58 ` Kevin Buettner [this message]
2022-09-08  1:58 ` [PATCH v3 2/2] BFD error message suppression test case Kevin Buettner
2022-09-16 23:32 ` [PATCH v3 0/2] Suppress printing of superfluous BFD error messages Kevin Buettner

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=20220908015812.12175-2-kevinb@redhat.com \
    --to=kevinb@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=lsix@lancelotsix.com \
    --cc=simark@simark.ca \
    /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).