)]}'
{
  "commit": "0961970dea995ce9f8750bd615a534bbbd23cefd",
  "tree": "e744ac2dc2557de919615203b45dafa780088ccd",
  "parents": [
    "38ef7c3513f6a4241b2bac61fd18d61c99564e04"
  ],
  "author": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Fri Aug 04 15:05:57 2023 +0200"
  },
  "committer": {
    "name": "Tom de Vries",
    "email": "tdevries@suse.de",
    "time": "Fri Aug 04 15:05:57 2023 +0200"
  },
  "message": "[gdb/symtab] Fix data race on dwarf2_per_cu_data::{files_read,is_debug_types}\n\nWith gdb build with -fsanitize\u003dthread, and the exec from test-case\ngdb.base/index-cache.exp, I run into:\n...\n$ rm -f ~/.cache/gdb/*; \\\n  gdb -q -batch -iex \"set index-cache enabled on\" index-cache \\\n    -ex \"print foobar\"\n  ...\nWARNING: ThreadSanitizer: data race (pid\u003d25018)\n  Write of size 1 at 0x7b200000410d by main thread:\n    #0 dw2_get_file_names_reader gdb/dwarf2/read.c:2033 (gdb+0x7ab023)\n    #1 dw2_get_file_names gdb/dwarf2/read.c:2130 (gdb+0x7ab023)\n    #2 dw_expand_symtabs_matching_file_matcher(dwarf2_per_objfile*, gdb::function_view\u003cbool (char const*, bool)\u003e) gdb/dwarf2/read.c:3105 (gdb+0x7ac6e9)\n    #3 cooked_index_functions::expand_symtabs_matching(objfile*, gdb::function_view\u003cbool (char const*, bool)\u003e, lookup_name_info const*, gdb::function_view\u003cbool (char const*)\u003e, gdb::function_view\u003cbool (compunit_symtab*)\u003e, enum_flags\u003cblock_search_flag_values\u003e, domain_enum, search_domain) gdb/dwarf2/read.c:16812 (gdb+0x7d040f)\n    #4 objfile::map_symtabs_matching_filename(char const*, char const*, gdb::function_view\u003cbool (symtab*)\u003e) gdb/symfile-debug.c:219 (gdb+0xda5b6e)\n    #5 iterate_over_symtabs(char const*, gdb::function_view\u003cbool (symtab*)\u003e) gdb/symtab.c:648 (gdb+0xdc441d)\n    #6 lookup_symtab(char const*) gdb/symtab.c:662 (gdb+0xdc4522)\n    #7 classify_name gdb/c-exp.y:3083 (gdb+0x61afec)\n    #8 c_yylex gdb/c-exp.y:3251 (gdb+0x61dd13)\n    #9 c_yyparse() build/gdb/c-exp.c.tmp:1988 (gdb+0x61f07e)\n    #10 c_parse(parser_state*) gdb/c-exp.y:3417 (gdb+0x62d864)\n    #11 language_defn::parser(parser_state*) const gdb/language.c:598 (gdb+0x977245)\n    #12 parse_exp_in_context gdb/parse.c:414 (gdb+0xb10b1b)\n    #13 parse_expression(char const*, innermost_block_tracker*, enum_flags\u003cparser_flag\u003e) gdb/parse.c:462 (gdb+0xb1112e)\n    #14 process_print_command_args gdb/printcmd.c:1321 (gdb+0xb4bf8c)\n    #15 print_command_1 gdb/printcmd.c:1335 (gdb+0xb4caaa)\n    #16 print_command gdb/printcmd.c:1468 (gdb+0xb4cdda)\n    #17 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x65b078)\n    #18 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 (gdb+0x65ed53)\n    #19 execute_command(char const*, int) gdb/top.c:575 (gdb+0xe3a7ea)\n    #20 catch_command_errors gdb/main.c:518 (gdb+0xa183fd)\n    #21 execute_cmdargs gdb/main.c:617 (gdb+0xa185bf)\n    #22 captured_main_1 gdb/main.c:1289 (gdb+0xa1aad8)\n    #23 captured_main gdb/main.c:1310 (gdb+0xa1b9da)\n    #24 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xa1b9da)\n    #25 main gdb/gdb.c:39 (gdb+0x42506a)\n\n  Previous read of size 1 at 0x7b200000410d by thread T2:\n    #0 write_gdbindex gdb/dwarf2/index-write.c:1214 (gdb+0x75bb30)\n    #1 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char const*, dw_index_kind) gdb/dwarf2/index-write.c:1469 (gdb+0x75f803)\n    #2 index_cache::store(dwarf2_per_bfd*, index_cache_store_context const\u0026) gdb/dwarf2/index-cache.c:173 (gdb+0x755a36)\n    #3 cooked_index::maybe_write_index(dwarf2_per_bfd*, index_cache_store_context const\u0026) gdb/dwarf2/cooked-index.c:642 (gdb+0x71c96d)\n    #4 operator() gdb/dwarf2/cooked-index.c:471 (gdb+0x71c96d)\n    #5 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x71c96d)\n    #6 std::function\u003cvoid ()\u003e::operator()() const /usr/include/c++/7/bits/std_function.h:706 (gdb+0x72a57c)\n    #7 void std::__invoke_impl\u003cvoid, std::function\u003cvoid ()\u003e\u0026\u003e(std::__invoke_other, std::function\u003cvoid ()\u003e\u0026) /usr/include/c++/7/bits/invoke.h:60 (gdb+0x72a5db)\n    #8 std::__invoke_result\u003cstd::function\u003cvoid ()\u003e\u0026\u003e::type std::__invoke\u003cstd::function\u003cvoid ()\u003e\u0026\u003e(std::function\u003cvoid ()\u003e\u0026) /usr/include/c++/7/bits/invoke.h:95 (gdb+0x72a5db)\n    #9 std::__future_base::_Task_state\u003cstd::function\u003cvoid ()\u003e, std::allocator\u003cint\u003e, void ()\u003e::_M_run()::{lambda()#1}::operator()() const /usr/include/c++/7/future:1421 (gdb+0x72a5db)\n    #10 std::__future_base::_Task_setter\u003cstd::unique_ptr\u003cstd::__future_base::_Result\u003cvoid\u003e, std::__future_base::_Result_base::_Deleter\u003e, std::__future_base::_Task_state\u003cstd::function\u003cvoid ()\u003e, std::allocator\u003cint\u003e, void ()\u003e::_M_run()::{lambda()#1}, void\u003e::operator()() const /usr/include/c++/7/future:1362 (gdb+0x72a5db)\n    #11 std::_Function_handler\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e (), std::__future_base::_Task_setter\u003cstd::unique_ptr\u003cstd::__future_base::_Result\u003cvoid\u003e, std::__future_base::_Result_base::_Deleter\u003e, std::__future_base::_Task_state\u003cstd::function\u003cvoid ()\u003e, std::allocator\u003cint\u003e, void ()\u003e::_M_run()::{lambda()#1}, void\u003e \u003e::_M_invoke(std::_Any_data const\u0026) /usr/include/c++/7/bits/std_function.h:302 (gdb+0x72a5db)\n    #12 std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e::operator()() const /usr/include/c++/7/bits/std_function.h:706 (gdb+0x724954)\n    #13 std::__future_base::_State_baseV2::_M_do_set(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*) /usr/include/c++/7/future:561 (gdb+0x724954)\n    #14 void std::__invoke_impl\u003cvoid, void (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026) /usr/include/c++/7/bits/invoke.h:73 (gdb+0x72434a)\n    #15 std::__invoke_result\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e::type std::__invoke\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026) /usr/include/c++/7/bits/invoke.h:95 (gdb+0x72434a)\n    #16 std::call_once\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(std::once_flag\u0026, void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026)::{lambda()#1}::operator()() const /usr/include/c++/7/mutex:672 (gdb+0x72434a)\n    #17 std::call_once\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(std::once_flag\u0026, void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026)::{lambda()#2}::operator()() const /usr/include/c++/7/mutex:677 (gdb+0x72434a)\n    #18 std::call_once\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(std::once_flag\u0026, void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026)::{lambda()#2}::_FUN() /usr/include/c++/7/mutex:677 (gdb+0x72434a)\n    #19 pthread_once \u003cnull\u003e (libtsan.so.0+0x4457c)\n    #20 __gthread_once /usr/include/c++/7/x86_64-suse-linux/bits/gthr-default.h:699 (gdb+0x72532b)\n    #21 void std::call_once\u003cvoid (std::__future_base::_State_baseV2::*)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*\u003e(std::once_flag\u0026, void (std::__future_base::_State_baseV2::*\u0026\u0026)(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*, bool*), std::__future_base::_State_baseV2*\u0026\u0026, std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e*\u0026\u0026, bool*\u0026\u0026) /usr/include/c++/7/mutex:684 (gdb+0x72532b)\n    #22 std::__future_base::_State_baseV2::_M_set_result(std::function\u003cstd::unique_ptr\u003cstd::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter\u003e ()\u003e, bool) /usr/include/c++/7/future:401 (gdb+0x174570d)\n    #23 std::__future_base::_Task_state\u003cstd::function\u003cvoid ()\u003e, std::allocator\u003cint\u003e, void ()\u003e::_M_run() /usr/include/c++/7/future:1423 (gdb+0x174570d)\n    #24 std::packaged_task\u003cvoid ()\u003e::operator()() /usr/include/c++/7/future:1556 (gdb+0x174570d)\n    #25 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (gdb+0x174570d)\n    #26 void std::__invoke_impl\u003cvoid, void (gdb::thread_pool::*)(), gdb::thread_pool*\u003e(std::__invoke_memfun_deref, void (gdb::thread_pool::*\u0026\u0026)(), gdb::thread_pool*\u0026\u0026) /usr/include/c++/7/bits/invoke.h:73 (gdb+0x17480c0)\n    #27 std::__invoke_result\u003cvoid (gdb::thread_pool::*)(), gdb::thread_pool*\u003e::type std::__invoke\u003cvoid (gdb::thread_pool::*)(), gdb::thread_pool*\u003e(void (gdb::thread_pool::*\u0026\u0026)(), gdb::thread_pool*\u0026\u0026) /usr/include/c++/7/bits/invoke.h:95 (gdb+0x17480c0)\n    #28 decltype (__invoke((_S_declval\u003c0ul\u003e)(), (_S_declval\u003c1ul\u003e)())) std::thread::_Invoker\u003cstd::tuple\u003cvoid (gdb::thread_pool::*)(), gdb::thread_pool*\u003e \u003e::_M_invoke\u003c0ul, 1ul\u003e(std::_Index_tuple\u003c0ul, 1ul\u003e) /usr/include/c++/7/thread:234 (gdb+0x17480c0)\n    #29 std::thread::_Invoker\u003cstd::tuple\u003cvoid (gdb::thread_pool::*)(), gdb::thread_pool*\u003e \u003e::operator()() /usr/include/c++/7/thread:243 (gdb+0x17480c0)\n    #30 std::thread::_State_impl\u003cstd::thread::_Invoker\u003cstd::tuple\u003cvoid (gdb::thread_pool::*)(), gdb::thread_pool*\u003e \u003e \u003e::_M_run() /usr/include/c++/7/thread:186 (gdb+0x17480c0)\n    #31 \u003cnull\u003e \u003cnull\u003e (libstdc++.so.6+0xdcac2)\n  ...\nSUMMARY: ThreadSanitizer: data race gdb/dwarf2/read.c:2033 in dw2_get_file_names_reader\n...\n\nThe race happens when issuing the \"file $exec\" command.\n\nThe race is between:\n- a worker thread writing the index cache, and in the process reading\n  dwarf2_per_cu_data::is_debug_type, and\n- the main thread writing to dwarf2_per_cu_data::files_read.\n\nThe two bitfields dwarf2_per_cu_data::files_read and\ndwarf2_per_cu_data::is_debug_type share the same bitfield container.\n\nFix this by making dwarf2_per_cu_data::files_read a packed\u003cbool, 1\u003e.\n\nTested on x86_64-linux.\n\nPR symtab/30718\nBug: https://sourceware.org/bugzilla/show_bug.cgi?id\u003d30718\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "44bc3ce88a0cacf813e87faa2c8c1ce7e08d9091",
      "old_mode": 33188,
      "old_path": "gdb/dwarf2/read.h",
      "new_id": "9dfc435e861c052a353d0a09a9b726a44f5da0ae",
      "new_mode": 33188,
      "new_path": "gdb/dwarf2/read.h"
    }
  ]
}
