From: Simon Marchi Date: Thu, 21 May 2026 04:00:48 +0000 (-0400) Subject: gdb: lock complaint_mutex in clear_complaints X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7ae086a3da45baec8d11f917ce00deeccf61c2d3;p=thirdparty%2Fbinutils-gdb.git gdb: lock complaint_mutex in clear_complaints If I add a dummy complaint like complaint (_("I am a complaint")); in cooked_index_worker_debug_info::process_unit, and then load a file under a GDB built with ThreadSanitizer, I get this (trimmed for readability): WARNING: ThreadSanitizer: data race (pid=497507) Read of size 4 at 0x7208000004c8 by thread T4 (mutexes: write M0): #0 std::pair<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator*, std::__cxx1998::vector, std::allocator > > >, std::__debug::vector, std::allocator > >, std::random_access_iterator_tag>, bool> ankerl::unordered_dense::v4_8_0::detail::table, std::equal_to, std::allocator >, ankerl::unordered_dense::v4_8_0::bucket_type::standard, ankerl::unordered_dense::v4_8_0::detail::default_container_t, false>::do_try_emplace(char const* const&) /home/simark/src/binutils-gdb/gdb/../gdbsupport/unordered_dense/unordered_dense.h:1227 (gdb+0xf0fd75) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #1 std::pair<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator*, std::__cxx1998::vector, std::allocator > > >, std::__debug::vector, std::allocator > >, std::random_access_iterator_tag>, bool> ankerl::unordered_dense::v4_8_0::detail::table, std::equal_to, std::allocator >, ankerl::unordered_dense::v4_8_0::bucket_type::standard, ankerl::unordered_dense::v4_8_0::detail::default_container_t, false>::try_emplace<, int, true>(char const* const&) /home/simark/src/binutils-gdb/gdb/../gdbsupport/unordered_dense/unordered_dense.h:1701 (gdb+0xf0ec50) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #2 int& ankerl::unordered_dense::v4_8_0::detail::table, std::equal_to, std::allocator >, ankerl::unordered_dense::v4_8_0::bucket_type::standard, ankerl::unordered_dense::v4_8_0::detail::default_container_t, false>::operator[](char const* const&) /home/simark/src/binutils-gdb/gdb/../gdbsupport/unordered_dense/unordered_dense.h:1926 (gdb+0xf0e3e2) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #3 complaint_internal(char const*, ...) /home/simark/src/binutils-gdb/gdb/complaints.c:50 (gdb+0xf0abc6) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #4 cooked_index_worker_debug_info::process_unit(dwarf2_per_cu*, dwarf2_per_objfile*, cooked_index_worker_result*) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3162 (gdb+0x11d741c) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #5 cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&)::{lambda()#1}::operator()() const /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3068 (gdb+0x122b195) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #6 void cooked_index_worker_result::catch_error(cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&)::{lambda()#1}&&) /home/simark/src/binutils-gdb/gdb/dwarf2/cooked-index-worker.h:122 (gdb+0x1236454) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #7 cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3066 (gdb+0x122b22d) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #8 cooked_index_worker_debug_info::parallel_indexing_worker::operator()(iterator_range*>) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3060 (gdb+0x122b0a3) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) ... Previous write of size 8 at 0x7208000004c8 by main thread: #0 __tsan_memset (libtsan.so.2+0x95e66) (BuildId: b5c99e8ceaf9098eb9a01fcfcc35ece8603116df) #1 ankerl::unordered_dense::v4_8_0::detail::table, std::equal_to, std::allocator >, ankerl::unordered_dense::v4_8_0::bucket_type::standard, ankerl::unordered_dense::v4_8_0::detail::default_container_t, false>::clear_buckets() /home/simark/src/binutils-gdb/gdb/../gdbsupport/unordered_dense/unordered_dense.h:1116 (gdb+0xf0edd6) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #2 ankerl::unordered_dense::v4_8_0::detail::table, std::equal_to, std::allocator >, ankerl::unordered_dense::v4_8_0::bucket_type::standard, ankerl::unordered_dense::v4_8_0::detail::default_container_t, false>::clear() /home/simark/src/binutils-gdb/gdb/../gdbsupport/unordered_dense/unordered_dense.h:1494 (gdb+0xf0e479) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #3 clear_complaints() /home/simark/src/binutils-gdb/gdb/complaints.c:74 (gdb+0xf0adbf) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #4 finish_new_objfile /home/simark/src/binutils-gdb/gdb/symfile.c:986 (gdb+0x1a2c65d) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #5 symbol_file_add_with_addrs /home/simark/src/binutils-gdb/gdb/symfile.c:1111 (gdb+0x1a2cdde) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #6 symbol_file_add_from_bfd(gdb::ref_ptr const&, char const*, enum_flags, std::__debug::vector >*, enum_flags, objfile*) /home/simark/src/binutils-gdb/gdb/symfile.c:1148 (gdb+0x1a2cfab) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #7 symbol_file_add(char const*, enum_flags, std::__debug::vector >*, enum_flags) /home/simark/src/binutils-gdb/gdb/symfile.c:1161 (gdb+0x1a2d03a) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #8 symbol_file_add_main_1 /home/simark/src/binutils-gdb/gdb/symfile.c:1185 (gdb+0x1a2d1a5) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #9 symbol_file_command(char const*, int) /home/simark/src/binutils-gdb/gdb/symfile.c:1615 (gdb+0x1a2ed10) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #10 file_command /home/simark/src/binutils-gdb/gdb/exec.c:580 (gdb+0x1305356) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) ... Location is heap block of size 32 at 0x7208000004c0 allocated by main thread: ... #11 __static_initialization_and_destruction_0 /home/simark/src/binutils-gdb/gdb/complaints.c:31 (gdb+0xf0df04) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) ... Mutex M0 (0x558908cdbc20) created at: #0 pthread_mutex_lock (libtsan.so.2+0x60b5a) (BuildId: b5c99e8ceaf9098eb9a01fcfcc35ece8603116df) #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/include/c++/16.1.1/x86_64-pc-linux-gnu/bits/gthr-default.h:795 (gdb+0xf0dfa6) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #2 std::mutex::lock() /usr/include/c++/16.1.1/bits/std_mutex.h:116 (gdb+0xf0dfa6) #3 std::lock_guard::lock_guard(std::mutex&) /usr/include/c++/16.1.1/bits/std_mutex.h:276 (gdb+0xf0e1f0) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #4 complaint_internal(char const*, ...) /home/simark/src/binutils-gdb/gdb/complaints.c:49 (gdb+0xf0abad) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #5 cooked_index_worker_debug_info::process_unit(dwarf2_per_cu*, dwarf2_per_objfile*, cooked_index_worker_result*) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3162 (gdb+0x11d741c) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #6 cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&)::{lambda()#1}::operator()() const /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3068 (gdb+0x122b195) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #7 void cooked_index_worker_result::catch_error(cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&)::{lambda()#1}&&) /home/simark/src/binutils-gdb/gdb/dwarf2/cooked-index-worker.h:122 (gdb+0x1236454) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #8 cooked_index_worker_debug_info::parallel_indexing_worker::process_one(dwarf2_per_cu&) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3066 (gdb+0x122b22d) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) #9 cooked_index_worker_debug_info::parallel_indexing_worker::operator()(iterator_range*>) /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:3060 (gdb+0x122b0a3) (BuildId: 5d682ab96882c738940aae3c2c67270d969f113f) ... This points to clear_complaints touching the global counters map in the main thread without holding a lock, while a background thread touched the map in a worker thread while holding the lock complaint_mutex. Fix this by holding the complaint_mutex lock in clear_complaints. Change-Id: Id2fe442486bcdf57156aacdc9253055702c07600 Approved-By: Tom Tromey --- diff --git a/gdb/complaints.c b/gdb/complaints.c index 4a2318a7f80..ab6e2049685 100644 --- a/gdb/complaints.c +++ b/gdb/complaints.c @@ -71,6 +71,7 @@ complaint_internal (const char *fmt, ...) void clear_complaints () { + gdb::lock_guard guard (complaint_mutex); counters.clear (); }