public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug symtab/30392] [gdb/symtab] thread sanitizer data race in gdb.base/index-cache.exp
Date: Fri, 04 Aug 2023 13:03:18 +0000	[thread overview]
Message-ID: <bug-30392-4717-4omtstRM0q@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-30392-4717@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=30392

--- Comment #11 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=edb157dfc6a7c0918aa67439c4ea6fd6161f3841

commit edb157dfc6a7c0918aa67439c4ea6fd6161f3841
Author: Tom de Vries <tdevries@suse.de>
Date:   Fri Aug 4 15:02:43 2023 +0200

    [gdb/symtab] Fix data race on
dwarf2_per_cu_data::{m_header_read_in,is_debug_type}

    With gdb build with -fsanitize=thread and test-case
gdb.base/index-cache.exp
    and target board debug-types, 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...
    ==================
    WARNING: ThreadSanitizer: data race (pid=9654)
      Write of size 1 at 0x7b200000420d by main thread:
        #0 dwarf2_per_cu_data::get_header() const gdb/dwarf2/read.c:21513
(gdb+0x8d1eee)
        #1 dwarf2_per_cu_data::addr_size() const gdb/dwarf2/read.c:21524
(gdb+0x8d1f4e)
        #2 dwarf2_cu::addr_type() const gdb/dwarf2/cu.c:112 (gdb+0x806327)
        #3 set_die_type gdb/dwarf2/read.c:21932 (gdb+0x8d3870)
        #4 read_base_type gdb/dwarf2/read.c:15448 (gdb+0x8bcacb)
        #5 read_type_die_1 gdb/dwarf2/read.c:19832 (gdb+0x8cc0a5)
        #6 read_type_die gdb/dwarf2/read.c:19767 (gdb+0x8cbe6d)
        #7 lookup_die_type gdb/dwarf2/read.c:19739 (gdb+0x8cbdc7)
        #8 die_type gdb/dwarf2/read.c:19593 (gdb+0x8cb68a)
        #9 read_subroutine_type gdb/dwarf2/read.c:14648 (gdb+0x8b998e)
        #10 read_type_die_1 gdb/dwarf2/read.c:19792 (gdb+0x8cbf2f)
        #11 read_type_die gdb/dwarf2/read.c:19767 (gdb+0x8cbe6d)
        #12 read_func_scope gdb/dwarf2/read.c:10154 (gdb+0x8a4f36)
        #13 process_die gdb/dwarf2/read.c:6667 (gdb+0x898daa)
        #14 read_file_scope gdb/dwarf2/read.c:7682 (gdb+0x89bad8)
        #15 process_die gdb/dwarf2/read.c:6654 (gdb+0x898ced)
        #16 process_full_comp_unit gdb/dwarf2/read.c:6418 (gdb+0x8981de)
        #17 process_queue gdb/dwarf2/read.c:5690 (gdb+0x894433)
        #18 dw2_do_instantiate_symtab gdb/dwarf2/read.c:1770 (gdb+0x88623a)
        #19 dw2_instantiate_symtab gdb/dwarf2/read.c:1792 (gdb+0x886300)
        #20 dw2_expand_symtabs_matching_one(dwarf2_per_cu_data*,
dwarf2_per_objfile*, gdb::function_view<bool (char const*, bool)>,
gdb::function_view<bool (compunit_symtab*)>) gdb/dwarf2/read.c:3042
(gdb+0x88b1f1)
        #21 cooked_index_functions::expand_symtabs_matching(objfile*,
gdb::function_view<bool (char const*, bool)>, lookup_name_info const*,
gdb::function_view<bool (char const*)>, gdb::function_view<bool
(compunit_symtab*)>, enum_flags<block_search_flag_values>, domain_enum,
search_domain) gdb/dwarf2/read.c:16917 (gdb+0x8c228e)
        #22 objfile::lookup_symbol(block_enum, char const*, domain_enum)
gdb/symfile-debug.c:288 (gdb+0xf39055)
        #23 lookup_symbol_via_quick_fns gdb/symtab.c:2385 (gdb+0xf66ab7)
        #24 lookup_symbol_in_objfile gdb/symtab.c:2516 (gdb+0xf6711b)
        #25 operator() gdb/symtab.c:2562 (gdb+0xf67272)
        #26 operator() gdb/../gdbsupport/function-view.h:305 (gdb+0xf776b1)
        #27 _FUN gdb/../gdbsupport/function-view.h:299 (gdb+0xf77708)
        #28 gdb::function_view<bool (objfile*)>::operator()(objfile*) const
gdb/../gdbsupport/function-view.h:289 (gdb+0xc3fc97)
        #29 svr4_iterate_over_objfiles_in_search_order gdb/solib-svr4.c:3455
(gdb+0xecae47)
        #30 gdbarch_iterate_over_objfiles_in_search_order(gdbarch*,
gdb::function_view<bool (objfile*)>, objfile*) gdb/gdbarch.c:5041
(gdb+0x537cad)
        #31 lookup_global_or_static_symbol gdb/symtab.c:2559 (gdb+0xf674fb)
        #32 lookup_global_symbol(char const*, block const*, domain_enum)
gdb/symtab.c:2615 (gdb+0xf67780)
        #33 language_defn::lookup_symbol_nonlocal(char const*, block const*,
domain_enum) const gdb/symtab.c:2447 (gdb+0xf66d6e)
        #34 lookup_symbol_aux gdb/symtab.c:2123 (gdb+0xf65cb3)
        #35 lookup_symbol_in_language(char const*, block const*, domain_enum,
language, field_of_this_result*) gdb/symtab.c:1931 (gdb+0xf64dab)
        #36 set_initial_language() gdb/symfile.c:1708 (gdb+0xf43074)
        #37 symbol_file_add_main_1 gdb/symfile.c:1212 (gdb+0xf41608)
        #38 symbol_file_command(char const*, int) gdb/symfile.c:1681
(gdb+0xf42faf)
        #39 file_command gdb/exec.c:554 (gdb+0x94ff29)
        #40 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x6d9528)
        #41 cmd_func(cmd_list_element*, char const*, int)
gdb/cli/cli-decode.c:2735 (gdb+0x6e0f69)
        #42 execute_command(char const*, int) gdb/top.c:575 (gdb+0xff379c)
        #43 command_handler(char const*) gdb/event-top.c:552 (gdb+0x94b5bc)
        #44 command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char>
>&&) gdb/event-top.c:788 (gdb+0x94bc79)
        #45 tui_command_line_handler gdb/tui/tui-interp.c:104 (gdb+0x1034efc)
        #46 gdb_rl_callback_handler gdb/event-top.c:259 (gdb+0x94ab61)
        #47 rl_callback_read_char readline/readline/callback.c:290
(gdb+0x11be4ef)
        #48 gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195
(gdb+0x94a960)
        #49 gdb_rl_callback_read_char_wrapper gdb/event-top.c:234
(gdb+0x94aa21)
        #50 stdin_event_handler gdb/ui.c:155 (gdb+0x10751a0)
        #51 handle_file_event gdbsupport/event-loop.cc:573 (gdb+0x1d95bac)
        #52 gdb_wait_for_event gdbsupport/event-loop.cc:694 (gdb+0x1d962e4)
        #53 gdb_do_one_event(int) gdbsupport/event-loop.cc:264 (gdb+0x1d946d0)
        #54 start_event_loop gdb/main.c:412 (gdb+0xb5ab52)
        #55 captured_command_loop gdb/main.c:476 (gdb+0xb5ad41)
        #56 captured_main gdb/main.c:1320 (gdb+0xb5cec1)
        #57 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xb5cf70)
        #58 main gdb/gdb.c:32 (gdb+0x416776)

      Previous read of size 1 at 0x7b200000420d by thread T11:
        #0 write_gdbindex gdb/dwarf2/index-write.c:1229 (gdb+0x831630)
        #1 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char
const*, dw_index_kind) gdb/dwarf2/index-write.c:1484 (gdb+0x832897)
        #2 index_cache::store(dwarf2_per_bfd*, index_cache_store_context
const&) gdb/dwarf2/index-cache.c:173 (gdb+0x82db8d)
        #3 cooked_index::maybe_write_index(dwarf2_per_bfd*,
index_cache_store_context const&) gdb/dwarf2/cooked-index.c:645 (gdb+0x7f1d49)
        #4 operator() gdb/dwarf2/cooked-index.c:474 (gdb+0x7f0f31)
        #5 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x7f2a13)
        #6 std::function<void ()>::operator()() const
/usr/include/c++/7/bits/std_function.h:706 (gdb+0x700952)
        #7 void std::__invoke_impl<void, std::function<void
()>&>(std::__invoke_other, std::function<void ()>&)
/usr/include/c++/7/bits/invoke.h:60 (gdb+0x7381a0)
        #8 std::__invoke_result<std::function<void ()>&>::type
std::__invoke<std::function<void ()>&>(std::function<void ()>&)
/usr/include/c++/7/bits/invoke.h:95 (gdb+0x737e91)
        #9 std::__future_base::_Task_state<std::function<void ()>,
std::allocator<int>, void ()>::_M_run()::{lambda()#1}::operator()() const
/usr/include/c++/7/future:1421 (gdb+0x737b59)
        #10
std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>,
std::__future_base::_Result_base::_Deleter>,
std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>,
void ()>::_M_run()::{lambda()#1}, void>::operator()() const
/usr/include/c++/7/future:1362 (gdb+0x738660)
        #11
std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> (),
std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>,
std::__future_base::_Result_base::_Deleter>,
std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>,
void ()>::_M_run()::{lambda()#1}, void> >::_M_invoke(std::_Any_data const&)
/usr/include/c++/7/bits/std_function.h:302 (gdb+0x73825c)
        #12 std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>::operator()() const
/usr/include/c++/7/bits/std_function.h:706 (gdb+0x733623)
        #13
std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*)
/usr/include/c++/7/future:561 (gdb+0x732bdf)
        #14 void std::__invoke_impl<void, void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*,
bool*>(std::__invoke_memfun_deref, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)
/usr/include/c++/7/bits/invoke.h:73 (gdb+0x734c4f)
        #15 std::__invoke_result<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>::type
std::__invoke<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)
/usr/include/c++/7/bits/invoke.h:95 (gdb+0x733bc5)
        #16 std::call_once<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&,
bool*&&)::{lambda()#1}::operator()() const /usr/include/c++/7/mutex:672
(gdb+0x73300d)
        #17 std::call_once<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&,
bool*&&)::{lambda()#2}::operator()() const /usr/include/c++/7/mutex:677
(gdb+0x7330b2)
        #18 std::call_once<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&,
bool*&&)::{lambda()#2}::_FUN() /usr/include/c++/7/mutex:677 (gdb+0x7330f2)
        #19 pthread_once <null> (libtsan.so.0+0x4457c)
        #20 __gthread_once
/usr/include/c++/7/x86_64-suse-linux/bits/gthr-default.h:699 (gdb+0x72f5dd)
        #21 void std::call_once<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)
/usr/include/c++/7/mutex:684 (gdb+0x733224)
        #22
std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>, bool)
/usr/include/c++/7/future:401 (gdb+0x732852)
        #23 std::__future_base::_Task_state<std::function<void ()>,
std::allocator<int>, void ()>::_M_run() /usr/include/c++/7/future:1423
(gdb+0x737bef)
        #24 std::packaged_task<void ()>::operator()()
/usr/include/c++/7/future:1556 (gdb+0x1dad25a)
        #25 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242
(gdb+0x1dacb7c)
        #26 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++/7/bits/invoke.h:73 (gdb+0x1dadc2b)
        #27 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++/7/bits/invoke.h:95 (gdb+0x1dad05c)
        #28 decltype (__invoke((_S_declval<0ul>)(), (_S_declval<1ul>)()))
std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(),
gdb::thread_pool*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>)
/usr/include/c++/7/thread:234 (gdb+0x1db038e)
        #29 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(),
gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243
(gdb+0x1db0319)
        #30 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void
(gdb::thread_pool::*)(), gdb::thread_pool*> > >::_M_run()
/usr/include/c++/7/thread:186 (gdb+0x1db02ce)
        #31 <null> <null> (libstdc++.so.6+0xdcac2)
      ...
    SUMMARY: ThreadSanitizer: data race gdb/dwarf2/read.c:21513 in
dwarf2_per_cu_data::get_header() const
    ...

    The race happens when issuing the "file $exec" command.

    The race is between:
    - a worker thread writing the index cache, and in the process reading
       dwarf2_per_cu_data::is_debug_type, and
    - the main thread writing to dwarf2_per_cu_data::m_header_read_in.

    The two bitfields dwarf2_per_cu_data::m_header_read_in and
    dwarf2_per_cu_data::is_debug_type share the same bitfield container.

    Fix this by making dwarf2_per_cu_data::m_header_read_in a packed<bool, 1>.

    Tested on x86_64-linux.

    Approved-By: Tom Tromey <tom@tromey.com>

    PR symtab/30392
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30392

-- 
You are receiving this mail because:
You are on the CC list for the bug.

  parent reply	other threads:[~2023-08-04 13:03 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-26 17:34 [Bug symtab/30392] New: " vries at gcc dot gnu.org
2023-04-26 17:35 ` [Bug symtab/30392] " vries at gcc dot gnu.org
2023-04-26 17:35 ` vries at gcc dot gnu.org
2023-04-26 20:09 ` vries at gcc dot gnu.org
2023-04-27 23:27 ` tromey at sourceware dot org
2023-04-28 14:30 ` simon.marchi at polymtl dot ca
2023-07-25 12:27 ` vries at gcc dot gnu.org
2023-07-28  8:58 ` vries at gcc dot gnu.org
2023-07-28  9:32 ` vries at gcc dot gnu.org
2023-07-28  9:36 ` vries at gcc dot gnu.org
2023-08-04 13:03 ` cvs-commit at gcc dot gnu.org
2023-08-04 13:03 ` cvs-commit at gcc dot gnu.org
2023-08-04 13:03 ` cvs-commit at gcc dot gnu.org
2023-08-04 13:03 ` cvs-commit at gcc dot gnu.org [this message]
2023-08-04 13:10 ` vries at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-30392-4717-4omtstRM0q@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).