From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id cMqbOGqkEmPqHjIAWB0awg (envelope-from ) for ; Fri, 02 Sep 2022 20:48:42 -0400 Received: by simark.ca (Postfix, from userid 112) id E59311E4A7; Fri, 2 Sep 2022 20:48:42 -0400 (EDT) Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=Fpha8sHN; dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 8064B1E13B for ; Fri, 2 Sep 2022 20:48:42 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D030638582A0 for ; Sat, 3 Sep 2022 00:48:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D030638582A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1662166121; bh=u328G7FlQR42PMY3elwOPygWqLSbqpxZhLMfWGezqo8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Fpha8sHNPt36o06JTg573rBYKYyfWavr7KsGkn1NIZN89UrsPcLQ6/VN8G2DnUK1x UmwtltF3fX+FqunYhDtt4bYmtQeQVa00N6xMJ1i0lfopNg/3oe3yObfzgZ/WHFxDaB kFu5Us6kBucZxNPUFDsm+DU+00+rd0CRnIeY2reE= Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 9E6F93858425 for ; Sat, 3 Sep 2022 00:48:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9E6F93858425 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-615-dz0nqkQUMiKdc1TsQgamyg-1; Fri, 02 Sep 2022 20:48:18 -0400 X-MC-Unique: dz0nqkQUMiKdc1TsQgamyg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F27BD3C0F37B for ; Sat, 3 Sep 2022 00:48:17 +0000 (UTC) Received: from f36-1.lan (unknown [10.2.16.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A0101121314; Sat, 3 Sep 2022 00:48:17 +0000 (UTC) To: gdb-patches@sourceware.org Subject: [PATCH 1/2] Suppress printing of superfluous BFD error messages Date: Fri, 2 Sep 2022 17:47:58 -0700 Message-Id: <20220903004759.2082950-2-kevinb@redhat.com> In-Reply-To: <20220903004759.2082950-1-kevinb@redhat.com> References: <20220903004759.2082950-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Kevin Buettner via Gdb-patches Reply-To: Kevin Buettner Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" 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 a 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 | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 6c03ae5ef05..e74d649ea16 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 /* An object of this type is stored in the section's user data when mapping a section. */ @@ -1125,6 +1126,73 @@ 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::map bfd_error_string_counts; +}; + +/* Per-inferior data key. */ + +static const registry::key 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; + if (map.find (str) == map.end ()) + { + map[str] = 0; + } + return ++map[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 (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 +1225,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.2