From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id iAWLBZecWGeV+woAWB0awg (envelope-from ) for ; Tue, 10 Dec 2024 14:55:03 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TKJ/ZZ4F; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 10FBE1E097; Tue, 10 Dec 2024 14:55:03 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable autolearn_force=no version=4.0.0 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 494901E091 for ; Tue, 10 Dec 2024 14:55:02 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E4B173857C6E for ; Tue, 10 Dec 2024 19:54:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E4B173857C6E Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TKJ/ZZ4F Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id D3DEC3857C68 for ; Tue, 10 Dec 2024 19:51:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D3DEC3857C68 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D3DEC3857C68 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1733860309; cv=none; b=d8VXR2An/N47yV0t20q8setrYoegUsQ5oCmWJu+z7AQ6j1A4p8A+E9+m49NinQNlVEMEXqxGISEeXWgdzDaZzpHnVE4QotF1CZgTcl0d5ZpSWr2yPwmGAN5EVnsZboqGWdCu+bzcaTO+uSw0UKlXALQmxIcNJyTPTwuCrJq3TUE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1733860309; c=relaxed/simple; bh=I+TEjvXIL80+G+KSQ0+mUV3olDu/0dRkW1pNq7wfLCU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=pntrN6wO4/xrRA4MDy9JDFuSimuAYTQFWmILhRUJ2u5f8nI6adg1LR8UpESN0aINAa9sVAoxy8Rwp15DX7A4M3erC0/WZbecqsTvYKIcKM7g08Q7sLTAskWofqEgLlp6PQkhwK6a10qmIfY1bJcH3UfT60Uer0Wa4WICSewm9W0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D3DEC3857C68 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733860309; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TVCdJQ0FoYcIOyvxvoKtCterPVdhNtC8pdUL71tvf7s=; b=TKJ/ZZ4FJLy6+fBkOQxs70YtiGkqK1nesN4Uc6tTuwPCzkgj+OQvdL+SGg81q/d35mVUhZ BUBBfNUWK/TVCr45OPKZbz9vC3tVJy2NOoo4OwmyNq4BnCqqqhJKYXyVUwluKqjU1t/f37 TZFdFJEsykdWym9hcP7phHpfh5hPNGk= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-637-MrjvmBZuMh2gZrDSOgtRbg-1; Tue, 10 Dec 2024 14:51:46 -0500 X-MC-Unique: MrjvmBZuMh2gZrDSOgtRbg-1 X-Mimecast-MFC-AGG-ID: MrjvmBZuMh2gZrDSOgtRbg Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (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 mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4AD4F1956079; Tue, 10 Dec 2024 19:51:45 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.96.134.195]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8D5DE1956054; Tue, 10 Dec 2024 19:51:43 +0000 (UTC) From: Guinevere Larsen To: gdb-patches@sourceware.org Cc: Guinevere Larsen , Thiago Jung Bauermann Subject: [PATCH v8 1/5] gdb: make gdbarch store a vector of frame unwinders Date: Tue, 10 Dec 2024 16:51:11 -0300 Message-ID: <20241210195115.3046370-2-guinevere@redhat.com> In-Reply-To: <20241210195115.3046370-1-guinevere@redhat.com> References: <20241210195115.3046370-1-guinevere@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: X8hfZsLnIB6xN9F-DSpXv_aGOOTaonZsEtrMHBMiVa4_1733860305 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Before this commit, all frame unwinders would be stored in the obstack of a gdbarch and accessed by using the registry system. This made for unwieldy code, and unnecessarily complex logic in the frame_unwinder implementation, along with making frame_unwind structs be unable to have non-trivial destructors. Seeing as a future patch of this series wants to refactor the frame_unwind struct to use inheritance, and we'd like to not restrict the future derived classes on what destructors are allowed. In preparation for that change, this commit changes the registry in gdbarch to instead store an std::vector, which doesn't require using an obstack and doesn't rely on a linked list. There should be no user-visible changes. Reviewed-by: Thiago Jung Bauermann --- gdb/frame-unwind.c | 107 +++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 352779fcdcc..e61f6244913 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -31,61 +31,42 @@ #include "cli/cli-cmds.h" #include "inferior.h" -struct frame_unwind_table_entry +/* Default sniffers, that must always be the first in the unwinder list, + no matter the architecture. */ +static constexpr auto standard_unwinders = { - const struct frame_unwind *unwinder; - struct frame_unwind_table_entry *next; + &dummy_frame_unwind, + /* The DWARF tailcall sniffer must come before the inline sniffer. + Otherwise, we can end up in a situation where a DWARF frame finds + tailcall information, but then the inline sniffer claims a frame + before the tailcall sniffer, resulting in confusion. This is + safe to do always because the tailcall sniffer can only ever be + activated if the newer frame was created using the DWARF + unwinder, and it also found tailcall information. */ + &dwarf2_tailcall_frame_unwind, + &inline_frame_unwind, }; -struct frame_unwind_table -{ - struct frame_unwind_table_entry *list = nullptr; - /* The head of the OSABI part of the search list. */ - struct frame_unwind_table_entry **osabi_head = nullptr; -}; +/* If an unwinder should be prepended to the list, this is the + index in which it should be inserted. */ +static constexpr int prepend_unwinder_index = standard_unwinders.size (); -static const registry::key +static const registry::key> frame_unwind_data; -/* A helper function to add an unwinder to a list. LINK says where to - install the new unwinder. The new link is returned. */ - -static struct frame_unwind_table_entry ** -add_unwinder (struct obstack *obstack, const struct frame_unwind *unwinder, - struct frame_unwind_table_entry **link) -{ - *link = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); - (*link)->unwinder = unwinder; - return &(*link)->next; -} - -static struct frame_unwind_table * +/* Retrieve the list of frame unwinders available in GDBARCH. + If this list is empty, it is initialized before being returned. */ +static std::vector * get_frame_unwind_table (struct gdbarch *gdbarch) { - struct frame_unwind_table *table = frame_unwind_data.get (gdbarch); + std::vector *table = frame_unwind_data.get (gdbarch); if (table != nullptr) return table; - table = new frame_unwind_table; - - /* Start the table out with a few default sniffers. OSABI code - can't override this. */ - struct frame_unwind_table_entry **link = &table->list; + table = new std::vector; + table->insert (table->begin (), standard_unwinders.begin (), + standard_unwinders.end ()); - struct obstack *obstack = gdbarch_obstack (gdbarch); - link = add_unwinder (obstack, &dummy_frame_unwind, link); - /* The DWARF tailcall sniffer must come before the inline sniffer. - Otherwise, we can end up in a situation where a DWARF frame finds - tailcall information, but then the inline sniffer claims a frame - before the tailcall sniffer, resulting in confusion. This is - safe to do always because the tailcall sniffer can only ever be - activated if the newer frame was created using the DWARF - unwinder, and it also found tailcall information. */ - link = add_unwinder (obstack, &dwarf2_tailcall_frame_unwind, link); - link = add_unwinder (obstack, &inline_frame_unwind, link); - - /* The insertion point for OSABI sniffers. */ - table->osabi_head = link; frame_unwind_data.set (gdbarch, table); return table; @@ -95,27 +76,16 @@ void frame_unwind_prepend_unwinder (struct gdbarch *gdbarch, const struct frame_unwind *unwinder) { - struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); - struct frame_unwind_table_entry *entry; - - /* Insert the new entry at the start of the list. */ - entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); - entry->unwinder = unwinder; - entry->next = (*table->osabi_head); - (*table->osabi_head) = entry; + std::vector *table = get_frame_unwind_table (gdbarch); + + table->insert (table->begin () + prepend_unwinder_index, unwinder); } void frame_unwind_append_unwinder (struct gdbarch *gdbarch, const struct frame_unwind *unwinder) { - struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); - struct frame_unwind_table_entry **ip; - - /* Find the end of the list and insert the new entry there. */ - for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next); - (*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); - (*ip)->unwinder = unwinder; + get_frame_unwind_table (gdbarch)->push_back (unwinder); } /* Call SNIFFER from UNWINDER. If it succeeded set UNWINDER for @@ -188,9 +158,6 @@ frame_unwind_find_by_frame (const frame_info_ptr &this_frame, void **this_cache) FRAME_SCOPED_DEBUG_ENTER_EXIT; frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame)); - struct gdbarch *gdbarch = get_frame_arch (this_frame); - struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); - struct frame_unwind_table_entry *entry; const struct frame_unwind *unwinder_from_target; unwinder_from_target = target_get_unwinder (); @@ -205,8 +172,10 @@ frame_unwind_find_by_frame (const frame_info_ptr &this_frame, void **this_cache) unwinder_from_target)) return; - for (entry = table->list; entry != NULL; entry = entry->next) - if (frame_unwind_try_unwinder (this_frame, this_cache, entry->unwinder)) + struct gdbarch *gdbarch = get_frame_arch (this_frame); + std::vector *table = get_frame_unwind_table (gdbarch); + for (auto unwinder : *table) + if (frame_unwind_try_unwinder (this_frame, this_cache, unwinder)) return; internal_error (_("frame_unwind_find_by_frame failed")); @@ -347,7 +316,7 @@ static void maintenance_info_frame_unwinders (const char *args, int from_tty) { gdbarch *gdbarch = current_inferior ()->arch (); - struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); + std::vector *table = get_frame_unwind_table (gdbarch); ui_out *uiout = current_uiout; ui_out_emit_table table_emitter (uiout, 2, -1, "FrameUnwinders"); @@ -355,15 +324,11 @@ maintenance_info_frame_unwinders (const char *args, int from_tty) uiout->table_header (25, ui_left, "type", "Type"); uiout->table_body (); - for (struct frame_unwind_table_entry *entry = table->list; entry != NULL; - entry = entry->next) + for (auto unwinder : *table) { - const char *name = entry->unwinder->name; - const char *type = frame_type_str (entry->unwinder->type); - ui_out_emit_list tuple_emitter (uiout, nullptr); - uiout->field_string ("name", name); - uiout->field_string ("type", type); + uiout->field_string ("name", unwinder->name); + uiout->field_string ("type", frame_type_str (unwinder->type)); uiout->text ("\n"); } } -- 2.47.0