From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id zkocOvrqwGDnBwAAWB0awg (envelope-from ) for ; Wed, 09 Jun 2021 12:23:22 -0400 Received: by simark.ca (Postfix, from userid 112) id D45C11F163; Wed, 9 Jun 2021 12:23:22 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,T_DKIM_INVALID,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from 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 RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 529651E01F for ; Wed, 9 Jun 2021 12:23:21 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E4E7139960F4 for ; Wed, 9 Jun 2021 16:23:20 +0000 (GMT) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 7E8E0398EC08 for ; Wed, 9 Jun 2021 16:23:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7E8E0398EC08 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de Received: from imap.suse.de (imap-alt.suse-dmz.suse.de [192.168.254.47]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 83F4E1FD5F; Wed, 9 Jun 2021 16:23:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1623255788; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PA/nbtvuO6cG40SwO84ehZyzcsxIbP/7tcy0d/Scr34=; b=YTo1bXEhOlkSVsvuoqFcXMTHyNbv2fhAOxAVQBszpZcQYYIixBOYX4DCabJDG+SmZw7BqH 3XeEXlG7TV1RTZrsPB4Bjkb42duFfoKwMBhBCl0MileIBJKQ/gUFjUmCSksR6Rp5DGfiDU XIi+dRYBxMxpmJhrtJJXlVpq5yTcYFw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1623255788; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PA/nbtvuO6cG40SwO84ehZyzcsxIbP/7tcy0d/Scr34=; b=Lzf5MmyjdGjtVaAKJCjG9xwCoIBoJj0z2nOvZtTX3lzuSY25zvNTzcPCTIESzKHZRdNpYU N1RfETh2JO7KBuDw== Received: from imap3-int (imap-alt.suse-dmz.suse.de [192.168.254.47]) by imap.suse.de (Postfix) with ESMTP id 5A012118DD; Wed, 9 Jun 2021 16:23:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1623255788; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PA/nbtvuO6cG40SwO84ehZyzcsxIbP/7tcy0d/Scr34=; b=YTo1bXEhOlkSVsvuoqFcXMTHyNbv2fhAOxAVQBszpZcQYYIixBOYX4DCabJDG+SmZw7BqH 3XeEXlG7TV1RTZrsPB4Bjkb42duFfoKwMBhBCl0MileIBJKQ/gUFjUmCSksR6Rp5DGfiDU XIi+dRYBxMxpmJhrtJJXlVpq5yTcYFw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1623255788; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PA/nbtvuO6cG40SwO84ehZyzcsxIbP/7tcy0d/Scr34=; b=Lzf5MmyjdGjtVaAKJCjG9xwCoIBoJj0z2nOvZtTX3lzuSY25zvNTzcPCTIESzKHZRdNpYU N1RfETh2JO7KBuDw== Received: from director2.suse.de ([192.168.254.72]) by imap3-int with ESMTPSA id A1cDFezqwGADEgAALh3uQQ (envelope-from ); Wed, 09 Jun 2021 16:23:08 +0000 Date: Wed, 9 Jun 2021 18:23:06 +0200 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH][gdb/symtab] Fix infinite recursion in dwarf2_cu::get_builder(), again Message-ID: <20210609162305.GA7082@delia.home> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) 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: , Cc: Tom Tromey Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" Hi, This is another attempt at fixing the problem described in commit 4cf88725da1 "[gdb/symtab] Fix infinite recursion in dwarf2_cu::get_builder()", which was reverted in commit 3db19b2d724. First off, some context. A DWARF CU can be viewed as a symbol table: toplevel children of a CU DIE represent symbol table entries for that CU. Furthermore, there is a hierarchy: a symbol table entry such as a function itself has a symbol table containing parameters and local variables. The dwarf reader maintains a notion of current symbol table (that is: the symbol table a new symbol needs to be entered into) in dwarf2_cu member list_in_scope. A problem then presents itself when reading inter-CU references: - a new symbol read from a CU B needs to be entered into the symbol table of another CU A. - the notion of current symbol table is tracked on a per-CU basis. This is addressed in inherit_abstract_dies by temporarily overwriting the list_in_scope for CU B with the one for CU A. The current symbol table is one aspect of the current dwarf reader context that is tracked, but there are more, f.i. ones that are tracked via the dwarf2_cu member m_builder, f.i. m_builder->m_local_using_directives. A similar problem exists in relation to inter-CU references, but a different solution was chosen: - to keep track of an ancestor field in dwarf2_cu, which is updated when traversing inter-CU references, and - to use the ancestor field in dwarf2_cu::get_builder to return the m_builder in scope. There is no actual concept of a CU having an ancestor, it just marks the most recent CU from which a CU was inter-CU-referenced. Consequently, when following inter-CU references from a CU A to another CU B and back to CU A, the ancestors form a cycle, which causes dwarf2_cu::get_builder to hang or segfault, as reported in PR26327. ISTM that the ancestor implementation is confusing and fragile, and should go. Furthermore, it seems that keeping track of the m_builder in scope can be handled simply with a global variable. Fix the hang / segfault by: - keeping track of the m_builder in scope using a new variable dwarf2_cu::sym_cu, and - using it in dwarf2_cu::get_builder. Tested on x86_64-linux (openSUSE Leap 15.2), no regressions for config: - using default gcc version 7.5.0 (with 5 unexpected FAILs) - gcc 10.3.0 and target board unix/-flto/-O0/-flto-partition=none/-ffat-lto-objects (with 1000 unexpected FAILs) Any comments? Thanks, - Tom [gdb/symtab] Fix infinite recursion in dwarf2_cu::get_builder(), again gdb/ChangeLog: 2021-06-09 Tom de Vries PR symtab/26327 * dwarf2/cu.c (dwarf2_cu::sym_cu): New var. * dwarf2/cu.h (dwarf2_cu::ancestor): Remove. (dwarf2_cu::sym_cu): Declare. (dwarf2_cu::get_builder): Use sym_cu instead of ancestor. Assert return value is non-null. * dwarf2/read.c (read_file_scope): Set dwarf2_cu::sym_cu. (follow_die_offset, follow_die_sig_1): Remove setting of ancestor. --- gdb/dwarf2/cu.c | 3 +++ gdb/dwarf2/cu.h | 11 +++++------ gdb/dwarf2/read.c | 13 ++++++------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c index 1031ed3aa00..b5b1f4551c6 100644 --- a/gdb/dwarf2/cu.c +++ b/gdb/dwarf2/cu.c @@ -21,6 +21,9 @@ #include "dwarf2/cu.h" #include "dwarf2/read.h" +/* See cu.h. */ +dwarf2_cu *dwarf2_cu::sym_cu; + /* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu, diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index b4a5b08d5a6..68f213d9d48 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -272,9 +272,8 @@ struct dwarf2_cu struct partial_die_info *find_partial_die (sect_offset sect_off); - /* If this CU was inherited by another CU (via specification, - abstract_origin, etc), this is the ancestor CU. */ - dwarf2_cu *ancestor; + /* The CU containing the m_builder in scope. */ + static dwarf2_cu *sym_cu; /* Get the buildsym_compunit for this CU. */ buildsym_compunit *get_builder () @@ -283,10 +282,10 @@ struct dwarf2_cu if (m_builder != nullptr) return m_builder.get (); - /* Otherwise, search ancestors for a valid builder. */ - if (ancestor != nullptr) - return ancestor->get_builder (); + if (sym_cu != nullptr) + return sym_cu->m_builder.get (); + gdb_assert_not_reached (""); return nullptr; } }; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 96009f1418f..f904073da21 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -10521,6 +10521,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) cu->start_symtab (fnd.name, fnd.comp_dir, lowpc); + gdb_assert (dwarf2_cu::sym_cu == nullptr); + scoped_restore restore_sym_cu = make_scoped_restore (&dwarf2_cu::sym_cu); + dwarf2_cu::sym_cu = cu; + /* Decode line number information if present. We do this before processing child DIEs, so that the line header table is available for DW_AT_decl_file. */ @@ -10536,6 +10540,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) child_die = child_die->sibling; } } + dwarf2_cu::sym_cu = nullptr; /* Decode macro information, if present. Dwarf 2 macro information refers to information in the line number info statement program @@ -23114,9 +23119,6 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz, *ref_cu = target_cu; temp_die.sect_off = sect_off; - if (target_cu != cu) - target_cu->ancestor = cu; - return (struct die_info *) htab_find_with_hash (target_cu->die_hash, &temp_die, to_underlying (sect_off)); @@ -23469,7 +23471,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type, struct dwarf2_cu **ref_cu) { struct die_info temp_die; - struct dwarf2_cu *sig_cu, *cu = *ref_cu; + struct dwarf2_cu *sig_cu; struct die_info *die; dwarf2_per_objfile *per_objfile = (*ref_cu)->per_objfile; @@ -23505,9 +23507,6 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type, } *ref_cu = sig_cu; - if (sig_cu != cu) - sig_cu->ancestor = cu; - return die; }