From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id D19823851A87 for ; Wed, 29 Jun 2022 15:29:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D19823851A87 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-out1.suse.de (Postfix) with ESMTPS id CBD1A21F1D; 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 B5382132C0; 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 iAsjK8tvvGKNIQAAMHmgww (envelope-from ); Wed, 29 Jun 2022 15:29:15 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 5/5] [gdb/symtab] Fix data race on per_cu->lang Date: Wed, 29 Jun 2022 17:29:14 +0200 Message-Id: <20220629152914.13149-5-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/inlined_subroutine-inheritance.exp, we run into a data race between thread T4 and the main thread: ... Write of size 1 at 0x7b200000308d: #0 prepare_one_comp_unit gdb/dwarf2/read.c:23586 (gdb+0x86f859) ... which is here: ... cu->per_cu->lang = dwarf_lang_to_enum_language (attr->constant_value (0)); ... Both writes are called from the parallel for in dwarf2_build_psymtabs_hard, this one directly: ... #1 process_psymtab_comp_unit gdb/dwarf2/read.c:6812 (gdb+0x830912) #2 operator() gdb/dwarf2/read.c:7102 (gdb+0x831902) #3 operator() gdb/../gdbsupport/parallel-for.h:171 (gdb+0x8723a8) ... and this one when handling cross-CU refs: ... #1 cooked_indexer::ensure_cu_exists(cutu_reader*, dwarf2_per_objfile*, \ sect_offset, bool, bool) gdb/dwarf2/read.c:17973 (gdb+0x85c522) #2 cooked_indexer::scan_attributes(dwarf2_per_cu_data*, cutu_reader*, \ unsigned char const*, unsigned char const*, abbrev_info const*, \ char const**, char const**, enum_flags*, \ sect_offset*, cooked_index_entry const**, unsigned long*, bool) \ gdb/dwarf2/read.c:18148 (gdb+0x85d079) #3 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, \ cooked_index_entry const*, bool) gdb/dwarf2/read.c:18327 (gdb+0x85df65) #4 cooked_indexer::make_index(cutu_reader*) gdb/dwarf2/read.c:18450 \ (gdb+0x85e72c) #5 process_psymtab_comp_unit gdb/dwarf2/read.c:6816 (gdb+0x8309c1) #6 operator() gdb/dwarf2/read.c:7102 (gdb+0x831902) #7 operator() gdbsupport/parallel-for.h:163 (gdb+0x872346) ... Fix this by guarding the write with a lock. --- gdb/dwarf2/read.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 67702d43aff..a36f25f4e62 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -6766,6 +6766,10 @@ class cooked_indexer std::vector m_deferred_entries; }; +#if CXX_STD_THREAD +static std::mutex per_cu_long_lock; +#endif + /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. Process compilation unit THIS_CU for a psymtab. */ @@ -23567,6 +23571,8 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die, /* Set the language we're debugging. */ attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu); + + enum language lang; if (cu->producer != nullptr && strstr (cu->producer, "IBM XL C for OpenCL") != NULL) { @@ -23574,19 +23580,34 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die, attribute is not standardised yet. As a workaround for the language detection we fall back to the DW_AT_producer string. */ - cu->per_cu->lang = language_opencl; + lang = language_opencl; } else if (cu->producer != nullptr && strstr (cu->producer, "GNU Go ") != NULL) { /* Similar hack for Go. */ - cu->per_cu->lang = language_go; + lang = language_go; } else if (attr != nullptr) - cu->per_cu->lang = dwarf_lang_to_enum_language (attr->constant_value (0)); + lang = dwarf_lang_to_enum_language (attr->constant_value (0)); else - cu->per_cu->lang = pretend_language; - cu->language_defn = language_def (cu->per_cu->lang); + lang = pretend_language; + + { +#if CXX_STD_THREAD + std::lock_guard guard (per_cu_long_lock); +#endif + /* Assign cu->per_cu->lang lazily. Note: we're not doing here: + if (cu->per_cu->lang == language_unknown) + cu->per_cu->lang = lang; + else + gdb_assert (cu->per_cu->lang == lang); + because language may go from unknown to minimal to c. */ + if (cu->per_cu->lang != lang) + cu->per_cu->lang = lang; + } + + cu->language_defn = language_def (lang); } /* See read.h. */ -- 2.35.3