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 CB39D3858C5E for ; Wed, 2 Aug 2023 09:53:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CB39D3858C5E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de 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 083FC1F894 for ; Wed, 2 Aug 2023 09:53:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1690970005; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Fjl/rbdYrSM/o6Qz9/EzsH/+yj1dvFBfueQamcLPr8A=; b=iKS8BcKhJ9TmvRrZOywJPmv/FtBf1fi8A62t9Y7iE6EyhKZoEbubgZ0Gjyyb1+bvAiZNZy D6Ayo5xh9xvPHLtgtboqTTduAaxOmtAzGMoFAgTmzntQAaq6tJBgMP+r9Dg4SfFZ1iPPt5 +DwUNsZZag2JzMd9KA9kJjJqyGJJSLw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1690970005; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Fjl/rbdYrSM/o6Qz9/EzsH/+yj1dvFBfueQamcLPr8A=; b=zrfsHcIEZO6K0aRbeDtV5gTwq5v0O0405ygOaHGl41m0mAKm/pm67OJRdC5OEQs4i/YWSU gj1nOyNrgg6M6dCg== 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 EA7DA13909 for ; Wed, 2 Aug 2023 09:53:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id mKAWOJQnymSscgAAMHmgww (envelope-from ) for ; Wed, 02 Aug 2023 09:53:24 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH v2 4/6] [gdb/symtab] Fix data race on bfd_last_cache Date: Wed, 2 Aug 2023 11:53:03 +0200 Message-Id: <20230802095305.3668-5-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230802095305.3668-1-tdevries@suse.de> References: <20230802095305.3668-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-12.2 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,WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: With gdb build with -fsanitize=3Dthread and test-case gdb.base/index-cache.= exp run using "taskset -c 0", I run into: ... (gdb) file build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache Reading symbols from build/gdb/testsuite/outputs/gdb.base/index-cache/index= -cache... =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D WARNING: ThreadSanitizer: data race (pid=3D5420) Write of size 8 at 0x0000032569e0 by main thread: #0 snip bfd/cache.c:155 (gdb+0x148b709) #1 bfd_cache_delete bfd/cache.c:176 (gdb+0x148b7a8) #2 bfd_cache_close bfd/cache.c:537 (gdb+0x148c406) #3 bfd_cache_close_all bfd/cache.c:561 (gdb+0x148c44a) #4 symbol_file_add_with_addrs gdb/symfile.c:1132 (gdb+0xf412ad) #5 symbol_file_add_from_bfd(gdb::ref_ptr const= &, char const*, enum_flags, std::vector >*, enum_flags, objfile*) gdb/s= ymfile.c:1167 (gdb+0xf4141d) #6 symbol_file_add(char const*, enum_flags, std::vect= or >*, enum_flags) gdb/symfile.c:1180 (gdb+0xf4149d) #7 symbol_file_add_main_1 gdb/symfile.c:1203 (gdb+0xf415a9) #8 symbol_file_command(char const*, int) gdb/symfile.c:1681 (gdb+0xf42f= 97) #9 file_command gdb/exec.c:554 (gdb+0x94ff11) #10 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x6d9528) #11 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:= 2735 (gdb+0x6e0f69) #12 execute_command(char const*, int) gdb/top.c:575 (gdb+0xff3784) #13 command_handler(char const*) gdb/event-top.c:552 (gdb+0x94b5a4) #14 command_line_handler(std::unique_ptr= >&&) gdb/event-top.c:788 (gdb+0x94bc61) #15 tui_command_line_handler gdb/tui/tui-interp.c:104 (gdb+0x1034ee4) #16 gdb_rl_callback_handler gdb/event-top.c:259 (gdb+0x94ab49) #17 rl_callback_read_char readline/readline/callback.c:290 (gdb+0x11be4= d7) #18 gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195 (gdb= +0x94a948) #19 gdb_rl_callback_read_char_wrapper gdb/event-top.c:234 (gdb+0x94aa09) #20 stdin_event_handler gdb/ui.c:155 (gdb+0x1075188) #21 handle_file_event gdbsupport/event-loop.cc:573 (gdb+0x1d95b94) #22 gdb_wait_for_event gdbsupport/event-loop.cc:694 (gdb+0x1d962cc) #23 gdb_do_one_event(int) gdbsupport/event-loop.cc:217 (gdb+0x1d94573) #24 start_event_loop gdb/main.c:412 (gdb+0xb5ab3a) #25 captured_command_loop gdb/main.c:476 (gdb+0xb5ad29) #26 captured_main gdb/main.c:1320 (gdb+0xb5cea9) #27 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xb5cf58) #28 main gdb/gdb.c:32 (gdb+0x416776) Previous read of size 8 at 0x0000032569e0 by thread T12: #0 cache_bseek bfd/cache.c:289 (gdb+0x148bbf7) #1 bfd_seek bfd/bfdio.c:459 (gdb+0x148a554) #2 _bfd_generic_get_section_contents bfd/libbfd.c:1069 (gdb+0x14980c7) #3 bfd_get_section_contents bfd/section.c:1606 (gdb+0x149d59f) #4 section_table_xfer_memory_partial(unsigned char*, unsigned char cons= t*, unsigned long, unsigned long, unsigned long*, std::vector > const&, gdb::function_view) gdb/exec.c:840 (gdb+0x951171) #5 exec_target::xfer_partial(target_object, char const*, unsigned char*= , unsigned char const*, unsigned long, unsigned long, unsigned long*) gdb/e= xec.c:894 (gdb+0x951372) #6 raw_memory_xfer_partial(target_ops*, unsigned char*, unsigned char c= onst*, unsigned long, long, unsigned long*) gdb/target.c:1476 (gdb+0xfade7a) #7 memory_xfer_partial_1 gdb/target.c:1607 (gdb+0xfae39a) #8 memory_xfer_partial gdb/target.c:1636 (gdb+0xfae46c) #9 target_xfer_partial(target_ops*, target_object, char const*, unsigne= d char*, unsigned char const*, unsigned long, unsigned long, unsigned long*= ) gdb/target.c:1693 (gdb+0xfae7f4) #10 target_read_partial gdb/target.c:1947 (gdb+0xfaf3e4) #11 target_read(target_ops*, target_object, char const*, unsigned char*= , unsigned long, long) gdb/target.c:1986 (gdb+0xfaf54a) #12 target_read_memory(unsigned long, unsigned char*, long) gdb/target.= c:1782 (gdb+0xfaecc6) #13 gdb_bfd_scan_elf_dyntag(int, bfd*, unsigned long*, unsigned long*) = gdb/solib.c:1638 (gdb+0xed98cf) #14 elf_locate_base gdb/solib-svr4.c:743 (gdb+0xec32e5) #15 svr4_iterate_over_objfiles_in_search_order gdb/solib-svr4.c:3430 (g= db+0xecad23) #16 gdbarch_iterate_over_objfiles_in_search_order(gdbarch*, gdb::functi= on_view, objfile*) gdb/gdbarch.c:5041 (gdb+0x537cad) #17 find_main_name gdb/symtab.c:6270 (gdb+0xf74b6b) #18 main_name() gdb/symtab.c:6299 (gdb+0xf74bf9) #19 write_cooked_index gdb/dwarf2/index-write.c:1131 (gdb+0x831044) #20 write_gdbindex gdb/dwarf2/index-write.c:1256 (gdb+0x83189b) #21 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char c= onst*, dw_index_kind) gdb/dwarf2/index-write.c:1484 (gdb+0x83287f) #22 index_cache::store(dwarf2_per_bfd*, index_cache_store_context const= &) gdb/dwarf2/index-cache.c:173 (gdb+0x82db35) #23 cooked_index::maybe_write_index(dwarf2_per_bfd*, index_cache_store_= context const&) gdb/dwarf2/cooked-index.c:642 (gdb+0x7f1d31) #24 operator() gdb/dwarf2/cooked-index.c:471 (gdb+0x7f0f31) #25 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x7f29fb) #26 std::function::operator()() const /usr/include/c++/7/bits/= std_function.h:706 (gdb+0x700952) #27 void std::__invoke_impl&>(std::__invok= e_other, std::function&) /usr/include/c++/7/bits/invoke.h:60 (gdb+= 0x7381a0) #28 std::__invoke_result&>::type std::__invoke&>(std::function&) /usr/include/c++/7/bits/in= voke.h:95 (gdb+0x737e91) #29 std::__future_base::_Task_state, std::alloca= tor, void ()>::_M_run()::{lambda()#1}::operator()() const /usr/include= /c++/7/future:1421 (gdb+0x737b59) #30 std::__future_base::_Task_setter, std::__future_base::_Result_base::_Deleter>, std::__future= _base::_Task_state, std::allocator, void ()>::_= M_run()::{lambda()#1}, void>::operator()() const /usr/include/c++/7/future:= 1362 (gdb+0x738660) #31 std::_Function_handler (), std::__future_base::_= Task_setter, std::__futur= e_base::_Result_base::_Deleter>, std::__future_base::_Task_state, std::allocator, void ()>::_M_run()::{lambda()#1}, void> = >::_M_invoke(std::_Any_data const&) /usr/include/c++/7/bits/std_function.h:= 302 (gdb+0x73825c) #32 std::function ()>::operator()() const /usr/inclu= de/c++/7/bits/std_function.h:706 (gdb+0x733623) #33 std::__future_base::_State_baseV2::_M_do_set(std::function ()>*, bool*) /usr/include/c++/7/future:561 (gdb+0x732bdf) #34 void std::__invoke_impl ()>*, bool*), std::__future_base::_= State_baseV2*, std::function ()>*, bool*>(std::__invoke_= memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function ()>*, bool*), std::__future_base::_State_baseV2*&&, std::= function ()>*&&, bool*&&) /usr/include/c++/7/bits/invoke= .h:73 (gdb+0x734c4f) #35 std::__invoke_result ()>*, bool*), std::__future_base::_State_bas= eV2*, std::function ()>*, bool*>::type std::__invoke (= )>*, bool*), std::__future_base::_State_baseV2*, std::function ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::func= tion ()>*, bool*), std::__future_base::_State_baseV2*&&,= std::function ()>*&&, bool*&&) /usr/include/c++/7/bits/= invoke.h:95 (gdb+0x733bc5) #36 std::call_once ()>*, bool*), std::__future_base::_State_baseV2*, = std::function ()>*, bool*>(std::once_flag&, void (std::_= _future_base::_State_baseV2::*&&)(std::function ()>*, bo= ol*), std::__future_base::_State_baseV2*&&, std::function ()>*&&, bool*&&)::{lambda()#1}::operator()() const /usr/include/c++/7/mut= ex:672 (gdb+0x73300d) #37 std::call_once ()>*, bool*), std::__future_base::_State_baseV2*, = std::function ()>*, bool*>(std::once_flag&, void (std::_= _future_base::_State_baseV2::*&&)(std::function ()>*, bo= ol*), std::__future_base::_State_baseV2*&&, std::function ()>*&&, bool*&&)::{lambda()#2}::operator()() const /usr/include/c++/7/mut= ex:677 (gdb+0x7330b2) #38 std::call_once ()>*, bool*), std::__future_base::_State_baseV2*, = std::function ()>*, bool*>(std::once_flag&, void (std::_= _future_base::_State_baseV2::*&&)(std::function ()>*, bo= ol*), std::__future_base::_State_baseV2*&&, std::function ()>*&&, bool*&&)::{lambda()#2}::_FUN() /usr/include/c++/7/mutex:677 (gdb+= 0x7330f2) #39 pthread_once (libtsan.so.0+0x4457c) #40 __gthread_once /usr/include/c++/7/x86_64-suse-linux/bits/gthr-defau= lt.h:699 (gdb+0x72f5dd) #41 void std::call_once ()>*, bool*), std::__future_base::_State_base= V2*, std::function ()>*, bool*>(std::once_flag&, void (s= td::__future_base::_State_baseV2::*&&)(std::function ()>= *, bool*), std::__future_base::_State_baseV2*&&, std::function ()>*&&, bool*&&) /usr/include/c++/7/mutex:684 (gdb+0x733224) #42 std::__future_base::_State_baseV2::_M_set_result(std::function ()>, bool) /usr/include/c++/7/future:401 (gdb+0x732852) #43 std::__future_base::_Task_state, std::alloca= tor, void ()>::_M_run() /usr/include/c++/7/future:1423 (gdb+0x737bef) #44 std::packaged_task::operator()() /usr/include/c++/7/future= :1556 (gdb+0x1dad242) #45 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (= gdb+0x1dacb64) #46 void std::__invoke_impl(std::__invoke_memfun_deref, void (gdb::thread_pool::*&&)(), gdb= ::thread_pool*&&) /usr/include/c++/7/bits/invoke.h:73 (gdb+0x1dadc13) #47 std::__invoke_result::type std::__invoke(voi= d (gdb::thread_pool::*&&)(), gdb::thread_pool*&&) /usr/include/c++/7/bits/i= nvoke.h:95 (gdb+0x1dad044) #48 decltype (__invoke((_S_declval<0ul>)(), (_S_declval<1ul>)())) std::= thread::_Invoker >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/include/c++/7/th= read:234 (gdb+0x1db0376) #49 std::thread::_Invoker >::operator()() /usr/include/c++/7/thread:243 (gdb+0x1db0301) #50 std::thread::_State_impl > >::_M_run() /usr/include/c++/7/th= read:186 (gdb+0x1db02b6) #51 (libstdc++.so.6+0xdcac2) Location is global 'bfd_last_cache' of size 8 at 0x0000032569e0 (gdb+0x00= 00032569e0) ... SUMMARY: ThreadSanitizer: data race bfd/cache.c:155 in snip ... The race happens when issuing the "file $exec" command. The race is between: - a worker thread calling main_name (), and in the process reading bfd_last_cache, and - the main thread writing to bfd_last_cache. Fix this by calling main_name () from the main thread. Tested on x86_64-linux. PR symtab/30392 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D30392 --- gdb/dwarf2/cooked-index.c | 7 +++++++ gdb/dwarf2/read.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c index b5718ae5529..9f647cfd4a2 100644 --- a/gdb/dwarf2/cooked-index.c +++ b/gdb/dwarf2/cooked-index.c @@ -462,6 +462,13 @@ cooked_index::start_writing_index (dwarf2_per_bfd *per= _bfd) { struct index_cache_store_context ctx (global_index_cache, per_bfd); =20 + if (global_index_cache.enabled ()) + { + /* Make sure find_main_name is called in the main thread rather than= a + worker thread, to avoid data races on bfd. */ + main_name (); + } + /* This must be set after all the finalization tasks have been started, because it may call 'wait'. */ m_write_future diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 61730f6481c..c37bacad3b1 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -5175,10 +5175,6 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_= objfile) cooked_index *vec =3D new cooked_index (std::move (indexes)); per_bfd->index_table.reset (vec); =20 - /* Cannot start writing the index entry until after the - 'index_table' member has been set. */ - vec->start_writing_index (per_bfd); - const cooked_index_entry *main_entry =3D vec->get_main (); if (main_entry !=3D nullptr) { @@ -5193,6 +5189,10 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_= objfile) set_objfile_main_name (objfile, full_name, lang); } =20 + /* Cannot start writing the index entry until after the + 'index_table' member has been set. */ + vec->start_writing_index (per_bfd); + dwarf_read_debug_printf ("Done building psymtabs of %s", objfile_name (objfile)); } --=20 2.35.3