From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 851B43851C13 for ; Wed, 29 Jun 2022 15:29:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 851B43851C13 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 952AE1F8EC; Wed, 29 Jun 2022 15:29:15 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 7CC7C132C0; Wed, 29 Jun 2022 15:29:15 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id yK5hHctvvGKNIQAAMHmgww (envelope-from ); Wed, 29 Jun 2022 15:29:15 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 3/5] [gdb/symtab] Work around fsanitize=address false positive for per_cu->lang Date: Wed, 29 Jun 2022 17:29:12 +0200 Message-Id: <20220629152914.13149-3-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220629152914.13149-1-tdevries@suse.de> References: <20220629152914.13149-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-List-Received-Date: Wed, 29 Jun 2022 15:29:18 -0000 When building gdb with -fsanitize=thread and gcc 12, and running test-case gdb.dwarf2/dwz.exp, we run into a data race between: ... Read of size 1 at 0x7b200000300d by thread T2:^M #0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \ abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6164 \ (gdb+0x82ec95)^M ... and: ... Previous write of size 1 at 0x7b200000300d by main thread:^M #0 prepare_one_comp_unit gdb/dwarf2/read.c:23588 (gdb+0x86f973)^M ... In other words, between: ... if (this_cu->reading_dwo_directly) ... and: ... cu->per_cu->lang = pretend_language; ... Both fields are part of the same bitfield, and writing to one field while reading from another is not a problem, so this is a false positive. An easy way to get rid of the false positive when compiling with thread sanitizer is to do this: ... #ifdef __SANITIZE_THREAD__ language lang; #else ENUM_BITFIELD (language) lang : LANGUAGE_BITS; #endif ... but that also inhibits the detection of parallel writing to different fields in the same bitfield, which is a problem. Fix this instead by moving the lang field out of the bitfield. In the bitfield, storing the lang field required LANGUAGE_BITS == 5 bits. Set the underlying type of enum lang to char, to require only 8 bits outside the bitfield. Due to a compilation error with gcc 7.5.0, that also requires us to set LANGUAGE_BITS to 8. The size of struct dwarf2_per_cu_data remains the same (at least for -m64). Tested on x86_64-linux. --- gdb/defs.h | 4 ++-- gdb/dwarf2/read.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gdb/defs.h b/gdb/defs.h index 99bfdd526ff..d5bf7cb2778 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -207,7 +207,7 @@ extern void quit_serial_event_clear (void); ada_sniff_from_mangled_name). (Keep this order in sync with the 'languages' array in language.c.) */ -enum language +enum language : char { language_unknown, /* Language not known */ language_auto, /* Placeholder for automatic setting */ @@ -229,7 +229,7 @@ enum language /* The number of bits needed to represent all languages, with enough padding to allow for reasonable growth. */ -#define LANGUAGE_BITS 5 +#define LANGUAGE_BITS 8 gdb_static_assert (nr_languages <= (1 << LANGUAGE_BITS)); enum precision_type diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 51e02dfc457..db300b19621 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -99,7 +99,8 @@ typedef std::unique_ptr struct dwarf2_per_cu_data { dwarf2_per_cu_data () - : queued (false), + : lang (language_unknown), + queued (false), is_debug_types (false), is_dwz (false), reading_dwo_directly (false), @@ -109,7 +110,6 @@ struct dwarf2_per_cu_data mark (false), files_read (false), unit_type {}, - lang (language_unknown), scanned (false) { } @@ -125,6 +125,9 @@ struct dwarf2_per_cu_data /* DWARF standard version this data has been read from (such as 4 or 5). */ unsigned char dwarf_version = 0; + /* The language of this CU. */ + language lang; + /* Flag indicating this compilation unit will be read in before any of the current compilation units are processed. */ unsigned int queued : 1; @@ -174,9 +177,6 @@ struct dwarf2_per_cu_data /* The unit type of this CU. */ ENUM_BITFIELD (dwarf_unit_type) unit_type : 8; - /* The language of this CU. */ - ENUM_BITFIELD (language) lang : LANGUAGE_BITS; - /* True if this CU has been scanned by the indexer; false if not. */ std::atomic scanned; -- 2.35.3