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:02 +0000	[thread overview]
Message-ID: <bug-30392-4717-9Cxs0uUiXS@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 #8 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=8adc5522280c06c1c750185af0dc5a8461d9a13f

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

    [gdb/symtab] Fix data race on index_cache::m_enabled

    With gdb build with -fsanitize=thread and test-case
gdb.base/index-cache.exp 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...
    (gdb) show index-cache enabled
    The index cache is off.
    (gdb) PASS: gdb.base/index-cache.exp: test_basic_stuff: index-cache is
disabled by default
    set index-cache enabled on
    ==================
    WARNING: ThreadSanitizer: data race (pid=32248)
      Write of size 1 at 0x00000321f540 by main thread:
        #0 index_cache::enable() gdb/dwarf2/index-cache.c:76 (gdb+0x82cfdd)
        #1 set_index_cache_enabled_command gdb/dwarf2/index-cache.c:270
(gdb+0x82d9af)
        #2 bool setting::set<bool>(bool const&) gdb/command.h:353
(gdb+0x6fe5f2)
        #3 do_set_command(char const*, int, cmd_list_element*)
gdb/cli/cli-setshow.c:414 (gdb+0x6fcd21)
        #4 execute_command(char const*, int) gdb/top.c:567 (gdb+0xff2e64)
        #5 command_handler(char const*) gdb/event-top.c:552 (gdb+0x94acc0)
        #6 command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char>
>&&) gdb/event-top.c:788 (gdb+0x94b37d)
        #7 tui_command_line_handler gdb/tui/tui-interp.c:104 (gdb+0x103467e)
        #8 gdb_rl_callback_handler gdb/event-top.c:259 (gdb+0x94a265)
        #9 rl_callback_read_char readline/readline/callback.c:290
(gdb+0x11bdd3f)
        #10 gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195
(gdb+0x94a064)
        #11 gdb_rl_callback_read_char_wrapper gdb/event-top.c:234
(gdb+0x94a125)
        #12 stdin_event_handler gdb/ui.c:155 (gdb+0x1074922)
        #13 handle_file_event gdbsupport/event-loop.cc:573 (gdb+0x1d94de4)
        #14 gdb_wait_for_event gdbsupport/event-loop.cc:694 (gdb+0x1d9551c)
        #15 gdb_do_one_event(int) gdbsupport/event-loop.cc:264 (gdb+0x1d93908)
        #16 start_event_loop gdb/main.c:412 (gdb+0xb5a256)
        #17 captured_command_loop gdb/main.c:476 (gdb+0xb5a445)
        #18 captured_main gdb/main.c:1320 (gdb+0xb5c5c5)
        #19 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xb5c674)
        #20 main gdb/gdb.c:32 (gdb+0x416776)

      Previous read of size 1 at 0x00000321f540 by thread T12:
        #0 index_cache::enabled() const gdb/dwarf2/index-cache.h:48
(gdb+0x82e1a6)
        #1 index_cache::store(dwarf2_per_bfd*) gdb/dwarf2/index-cache.c:94
(gdb+0x82d0bc)
        #2 cooked_index::maybe_write_index(dwarf2_per_bfd*)
gdb/dwarf2/cooked-index.c:638 (gdb+0x7f1b97)
        #3 operator() gdb/dwarf2/cooked-index.c:468 (gdb+0x7f0f24)
        #4 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x7f285b)
        #5 std::function<void ()>::operator()() const
/usr/include/c++/7/bits/std_function.h:706 (gdb+0x700952)
        #6 void std::__invoke_impl<void, std::function<void
()>&>(std::__invoke_other, std::function<void ()>&)
/usr/include/c++/7/bits/invoke.h:60 (gdb+0x7381a0)
        #7 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)
        #8 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)
        #9
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)
        #10
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)
        #11 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)
        #12
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)
        #13 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)
        #14 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)
        #15 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)
        #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()#2}::operator()() const /usr/include/c++/7/mutex:677
(gdb+0x7330b2)
        #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}::_FUN() /usr/include/c++/7/mutex:677 (gdb+0x7330f2)
        #18 pthread_once <null> (libtsan.so.0+0x4457c)
        #19 __gthread_once
/usr/include/c++/7/x86_64-suse-linux/bits/gthr-default.h:699 (gdb+0x72f5dd)
        #20 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)
        #21
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)
        #22 std::__future_base::_Task_state<std::function<void ()>,
std::allocator<int>, void ()>::_M_run() /usr/include/c++/7/future:1423
(gdb+0x737bef)
        #23 std::packaged_task<void ()>::operator()()
/usr/include/c++/7/future:1556 (gdb+0x1dac492)
        #24 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242
(gdb+0x1dabdb4)
        #25 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+0x1dace63)
        #26 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+0x1dac294)
        #27 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+0x1daf5c6)
        #28 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(),
gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243
(gdb+0x1daf551)
        #29 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+0x1daf506)
        #30 <null> <null> (libstdc++.so.6+0xdcac2)

      Location is global 'global_index_cache' of size 48 at 0x00000321f520
(gdb+0x00000321f540)
      ...
    SUMMARY: ThreadSanitizer: data race gdb/dwarf2/index-cache.c:76 in
index_cache::enable()
    ...

    The race happens when issuing a "file $exec" command followed by a
    "set index-cache enabled on" command.

    The race is between:
    - a worker thread reading index_cache::m_enabled to determine whether an
      index-cache entry for $exec needs to be written
      (due to command "file $exec"), and
    - the main thread setting index_cache::m_enabled
      (due to command "set index-cache enabled on").

    Fix this by capturing the value of index_cache::m_enabled in the main
thread,
    and using the captured value in the worker thread.

    Tested on x86_64-linux.

    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 [this message]
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: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-9Cxs0uUiXS@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).