When building gdb with O0 fsanitize=thread, and running test-case gdb.base/index-cache.exp, I get: ... (gdb) PASS: gdb.base/index-cache.exp: test_basic_stuff: index-cache is disabled by default set index-cache enabled on ================== [1m[31mWARNING: ThreadSanitizer: data race (pid=565983) [1m[0m[1m[34m Write of size 1 at 0x000003280448 by main thread: [1m[0m #0 index_cache::enable() /home/vries/gdb/src/gdb/dwarf2/index-cache.c:76 (gdb+0x837634) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #1 set_index_cache_enabled_command /home/vries/gdb/src/gdb/dwarf2/index-cache.c:294 (gdb+0x838104) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #2 bool setting::set<bool>(bool const&) /home/vries/gdb/src/gdb/command.h:353 (gdb+0x709c10) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #3 do_set_command(char const*, int, cmd_list_element*) /home/vries/gdb/src/gdb/cli/cli-setshow.c:414 (gdb+0x708530) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #4 execute_command(char const*, int) /home/vries/gdb/src/gdb/top.c:567 (gdb+0xff73cc) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #5 command_handler(char const*) /home/vries/gdb/src/gdb/event-top.c:566 (gdb+0x942488) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #6 command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) /home/vries/gdb/src/gdb/event-top.c:802 (gdb+0x942bc0) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #7 tui_command_line_handler /home/vries/gdb/src/gdb/tui/tui-interp.c:104 (gdb+0x10365f8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #8 gdb_rl_callback_handler /home/vries/gdb/src/gdb/event-top.c:259 (gdb+0x941884) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #9 rl_callback_read_char /home/vries/gdb/src/readline/readline/callback.c:290 (gdb+0x11a2c7c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #10 gdb_rl_callback_read_char_wrapper_noexcept /home/vries/gdb/src/gdb/event-top.c:195 (gdb+0x9415f8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #11 gdb_rl_callback_read_char_wrapper /home/vries/gdb/src/gdb/event-top.c:234 (gdb+0x941720) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #12 stdin_event_handler /home/vries/gdb/src/gdb/ui.c:155 (gdb+0x1079320) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #13 handle_file_event /home/vries/gdb/src/gdbsupport/event-loop.cc:573 (gdb+0x1cf5678) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #14 gdb_wait_for_event /home/vries/gdb/src/gdbsupport/event-loop.cc:694 (gdb+0x1cf5d3c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #15 gdb_do_one_event(int) /home/vries/gdb/src/gdbsupport/event-loop.cc:264 (gdb+0x1cf4074) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #16 start_event_loop /home/vries/gdb/src/gdb/main.c:408 (gdb+0xb79354) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #17 captured_command_loop /home/vries/gdb/src/gdb/main.c:472 (gdb+0xb79584) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #18 captured_main /home/vries/gdb/src/gdb/main.c:1342 (gdb+0xb7b99c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #19 gdb_main(captured_main_args*) /home/vries/gdb/src/gdb/main.c:1361 (gdb+0xb7ba4c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #20 main /home/vries/gdb/src/gdb/gdb.c:39 (gdb+0x423ce8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) [1m[34m Previous read of size 1 at 0x000003280448 by thread T5: [1m[0m #0 index_cache::enabled() const /home/vries/gdb/src/gdb/dwarf2/index-cache.h:70 (gdb+0x8389a4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #1 index_cache_store_context::index_cache_store_context(index_cache const&, dwarf2_per_bfd*) /home/vries/gdb/src/gdb/dwarf2/index-cache.c:93 (gdb+0x837730) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #2 cooked_index::set_contents(std::vector<std::unique_ptr<cooked_index_shard, std::default_delete<cooked_index_shard> >, std::allocator<std::unique_ptr<cooked_index_shard, std::default_delete<cooked_index_shard> > > >&&) /home/vries/gdb/src/gdb/dwarf2/cooked-index.c:489 (gdb+0x7f6fec) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #3 cooked_index_worker::done_reading() /home/vries/gdb/src/gdb/dwarf2/read.c:4901 (gdb+0x89e980) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #4 operator() /home/vries/gdb/src/gdb/dwarf2/read.c:4960 (gdb+0x89eb40) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #5 __invoke_impl<void, cooked_index_worker::do_reading()::<lambda()>&> /usr/include/c++/13/bits/invoke.h:61 (gdb+0x8decb4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #6 __invoke_r<void, cooked_index_worker::do_reading()::<lambda()>&> /usr/include/c++/13/bits/invoke.h:111 (gdb+0x8dddec) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #7 _M_invoke /usr/include/c++/13/bits/std_function.h:290 (gdb+0x8db118) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #8 std::function<void ()>::operator()() const /usr/include/c++/13/bits/std_function.h:591 (gdb+0x70c308) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #9 gdb::task_group::impl::~impl() /home/vries/gdb/src/gdbsupport/task-group.cc:39 (gdb+0x1d03610) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #10 std::_Sp_counted_ptr<gdb::task_group::impl*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() /usr/include/c++/13/bits/shared_ptr_base.h:428 (gdb+0x1d04690) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #11 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release_last_use() /usr/include/c++/13/bits/shared_ptr_base.h:175 (gdb+0x63bf20) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #12 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/13/bits/shared_ptr_base.h:361 (gdb+0x637758) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #13 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/13/bits/shared_ptr_base.h:1071 (gdb+0x63c0b8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #14 std::__shared_ptr<gdb::task_group::impl, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/13/bits/shared_ptr_base.h:1524 (gdb+0x7fc9e8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #15 std::shared_ptr<gdb::task_group::impl>::~shared_ptr() /usr/include/c++/13/bits/shared_ptr.h:175 (gdb+0x7fca20) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #16 ~<lambda> /home/vries/gdb/src/gdbsupport/task-group.cc:66 (gdb+0x1d026cc) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #17 _M_destroy /usr/include/c++/13/bits/std_function.h:175 (gdb+0x1d03228) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #18 _M_manager /usr/include/c++/13/bits/std_function.h:203 (gdb+0x1d0308c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #19 _M_manager /usr/include/c++/13/bits/std_function.h:282 (gdb+0x1d02d5c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #20 std::_Function_base::~_Function_base() /usr/include/c++/13/bits/std_function.h:244 (gdb+0x431da4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #21 std::function<void ()>::~function() /usr/include/c++/13/bits/std_function.h:334 (gdb+0x432cac) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #22 std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>::_Impl::~_Impl() /usr/include/c++/13/future:1511 (gdb+0x80f73c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #23 std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>::~_Task_state() /usr/include/c++/13/future:1477 (gdb+0x810494) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #24 void std::__new_allocator<int>::destroy<std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()> >(std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>*) /usr/include/c++/13/bits/new_allocator.h:198 (gdb+0x81062c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #25 void std::allocator_traits<std::allocator<int> >::destroy<std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()> >(std::allocator<int>&, std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>*) /usr/include/c++/13/bits/alloc_traits.h:558 (gdb+0x81062c) #26 std::_Sp_counted_ptr_inplace<std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>, std::allocator<int>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() /usr/include/c++/13/bits/shared_ptr_base.h:613 (gdb+0x81062c) #27 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release_last_use() /usr/include/c++/13/bits/shared_ptr_base.h:175 (gdb+0x63bf20) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #28 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/13/bits/shared_ptr_base.h:361 (gdb+0x637758) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #29 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/13/bits/shared_ptr_base.h:1071 (gdb+0x63c0b8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #30 std::__shared_ptr<std::__future_base::_Task_state_base<void ()>, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/13/bits/shared_ptr_base.h:1524 (gdb+0x8ebfd0) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #31 std::shared_ptr<std::__future_base::_Task_state_base<void ()> >::~shared_ptr() /usr/include/c++/13/bits/shared_ptr.h:175 (gdb+0x8ec008) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #32 std::packaged_task<void ()>::~packaged_task() /usr/include/c++/13/future:1594 (gdb+0x8ec16c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #33 std::_Optional_payload_base<std::packaged_task<void ()> >::_M_destroy() /usr/include/c++/13/optional:287 (gdb+0x1d10c94) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #34 std::_Optional_payload_base<std::packaged_task<void ()> >::_M_reset() /usr/include/c++/13/optional:318 (gdb+0x1d0fe18) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #35 std::_Optional_payload<std::packaged_task<void ()>, false, false, false>::~_Optional_payload() /usr/include/c++/13/optional:439 (gdb+0x1d0f500) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #36 std::_Optional_base<std::packaged_task<void ()>, false, false>::~_Optional_base() /usr/include/c++/13/optional:510 (gdb+0x1d0ed88) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #37 std::optional<std::packaged_task<void ()> >::~optional() /usr/include/c++/13/optional:705 (gdb+0x1d0ee0c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #38 gdb::thread_pool::thread_function() /home/vries/gdb/src/gdbsupport/thread-pool.cc:247 (gdb+0x1d0e82c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #39 void std::__invoke_impl<void, void (gdb::thread_pool::*)(), gdb::thread_pool*>(std::__invoke_memfun_deref, void (gdb::thread_pool::*&&)(), gdb::thread_pool*&&) /usr/include/c++/13/bits/invoke.h:74 (gdb+0x1d12968) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #40 std::__invoke_result<void (gdb::thread_pool::*)(), gdb::thread_pool*>::type std::__invoke<void (gdb::thread_pool::*)(), gdb::thread_pool*>(void (gdb::thread_pool::*&&)(), gdb::thread_pool*&&) /usr/include/c++/13/bits/invoke.h:96 (gdb+0x1d12804) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #41 void std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/include/c++/13/bits/std_thread.h:292 (gdb+0x1d126e4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #42 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::operator()() /usr/include/c++/13/bits/std_thread.h:299 (gdb+0x1d1266c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #43 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> > >::_M_run() /usr/include/c++/13/bits/std_thread.h:244 (gdb+0x1d12618) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #44 execute_native_thread_routine <null> (libstdc++.so.6+0xdda9c) (BuildId: 93e3778007c3847dd08373eb42577dc85c8750e4) [1m[32m Location is global 'global_index_cache' of size 48 at 0x000003280428 (gdb+0x3280448) [1m[0m[1m[36m Thread T5 'gdb worker' (tid=565994, running) created by main thread at: [1m[0m #0 pthread_create <null> (libtsan.so.2+0x4605c) (BuildId: fe872cc4563474b7ad67d63a019aa94e1e0df888) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xddbe4) (BuildId: 93e3778007c3847dd08373eb42577dc85c8750e4) #2 gdb::thread_pool::set_thread_count(unsigned long) /home/vries/gdb/src/gdbsupport/thread-pool.cc:169 (gdb+0x1d0e4b4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #3 update_thread_pool_size() /home/vries/gdb/src/gdb/maint.c:866 (gdb+0xb87c70) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #4 captured_main_1 /home/vries/gdb/src/gdb/main.c:1062 (gdb+0xb7a8a4) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #5 captured_main /home/vries/gdb/src/gdb/main.c:1332 (gdb+0xb7b998) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #6 gdb_main(captured_main_args*) /home/vries/gdb/src/gdb/main.c:1361 (gdb+0xb7ba4c) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) #7 main /home/vries/gdb/src/gdb/gdb.c:39 (gdb+0x423ce8) (BuildId: 6dc308d9bc2da51d7adf979315fabd66fb46e8a3) SUMMARY: ThreadSanitizer: data race /home/vries/gdb/src/gdb/dwarf2/index-cache.c:76 in index_cache::enable() ================== (gdb) FAIL: gdb.base/index-cache.exp: test_basic_stuff: enable index cache ...
I guess the problem is that we're capturing index_cache_store_context in a worker thread (T5) while the capturing is supposed to happen in the main thread: ... /* Information to be captured in the main thread, and to be used by worker threads during store (). */ struct index_cache_store_context { friend class index_cache; index_cache_store_context (const index_cache &ic, dwarf2_per_bfd *per_bfd); ... In other words, this should trigger: ... diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c index 7ddd7b3f974..50db5f92b40 100644 --- a/gdb/dwarf2/index-cache.c +++ b/gdb/dwarf2/index-cache.c @@ -92,6 +92,7 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic, dwarf2_per_bfd *per_bfd) : m_enabled (ic.enabled ()) { + gdb_assert (is_main_thread ()); if (!m_enabled) return; ...
Bisects to: ... commit 33c6eaaefcedd45e86d564d014f14cce2620f933 Author: Tom Tromey <tom@tromey.com> Date: Fri Mar 24 23:35:02 2023 -0600 Do more DWARF reading in the background ...
I found another bug here (the cache directory isn't captured) and I have a series to clean this all up now.
https://sourceware.org/pipermail/gdb-patches/2024-January/206245.html
The master branch has been updated by Tom Tromey <tromey@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ed29a346be439466ff2a5ce33e715e02c49fbdac commit ed29a346be439466ff2a5ce33e715e02c49fbdac Author: Tom Tromey <tom@tromey.com> Date: Sun Jan 28 09:14:04 2024 -0700 Avoid race when writing to index cache The background DWARF reader changes introduced a race when writing to the index cache. The problem here is that constructing the index_cache_store_context object should only happen on the main thread, to ensure that the various value captures do not race. This patch adds an assert to the construct to that effect, and then arranges for this object to be constructed by the cooked_index_worker constructor -- which is only invoked on the main thread. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31262
Fixed.