aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
AgeCommit message (Collapse)AuthorFilesLines
2023-08-08[gdb/build] Fix build breaker with -std=c++11Tom de Vries1-1/+6
When building with -std=c++11 I run into: ... gdb/dwarf2/cooked-index.c: In member function \ ‘void cooked_index::start_writing_index(dwarf2_per_bfd*)’: gdb/dwarf2/cooked-index.c:469:10: error: lambda capture initializers only \ available with -std=c++14 or -std=gnu++14 [-Werror] ctx = std::move (ctx)] () ^~~ ... Fix this by capturing a copy instead when using -std=c++11: ... = gdb::thread_pool::g_thread_pool->post_task ([this, per_bfd, ctx] () ... Tested by building with and without -stdc=++11 on x86_64-linux. Reported-By: Tom Tromey <tom@tromey.com> Reviewed-by: John Baldwin <jhb@FreeBSD.org>
2023-08-05[gdb/symtab] Find main language without symtab expansionTom de Vries1-0/+40
When loading an executable using "file a.out", the language is set according to a.out, which can involve looking up the language of symbol "main", which will cause the symtab expansion for the containing CU. Expansion of lto debug info can be slow, so in commit d3214198119 ("[gdb] Use partial symbol table to find language for main") a feature was added to avoid the symtab expansion. This feature stopped working after commit 7f4307436fd ("Fix "start" for D, Rust, etc"). [ The commit addresses problems related to command start, which requires finding the main function: - for language D, "main" was found instead of "D main", and - for Rust, the correct function was found, but attributed the wrong name (not fully qualified). ] Reimplement the feature by adding cooked_index_functions::lookup_global_symbol_language. Tested on x86_64-linux. PR symtab/30661 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30661
2023-08-04Consolidate calls to bfd_set_cacheableTom Tromey1-1/+0
I noticed that some spots in gdb call bfd_set_cacheable after opening a BFD. The BFD file cache is a bit odd. BFDs that are opened locally are unconditionally registered with the cache, and their underlying file descriptor will always be closed when bfd_cache_close_all is called. However, only "cacheable" BFDs will be eligible for reopening when needed -- and by default BFD decides that if a file descriptor is passed in, then it should not be cacheable. If a non-cacheable BFD's file descriptor is closed, there is no offical way to reopen it. gdb needs to call bfd_cache_close_all, because some systems cannot start an executable when it has an open file descriptor referencing it. However, gdb also will sometimes passes an open file descriptor to the various BFD open functions. And, due to lazy DWARF reading, gdb may also need to reopen these BFDs. Rather than having all the callers figure out when exactly to set the cacheable flag, I think it makes sense to consolidate this logic into the gdb_bfd.c wrapper functions. It is ok to do this because gdb always passes a filename to these open functions, so reopening should work ok. Regression tested on x86-64 Fedora 38. Reviewed-by: John Baldwin <jhb@FreeBSD.org>
2023-08-04[gdb/symtab] Fix data race on dwarf2_per_cu_data::{files_read,is_debug_types}Tom de Vries1-5/+5
With gdb build with -fsanitize=thread, and the exec from test-case gdb.base/index-cache.exp, I run into: ... $ rm -f ~/.cache/gdb/*; \ gdb -q -batch -iex "set index-cache enabled on" index-cache \ -ex "print foobar" ... WARNING: ThreadSanitizer: data race (pid=25018) Write of size 1 at 0x7b200000410d by main thread: #0 dw2_get_file_names_reader gdb/dwarf2/read.c:2033 (gdb+0x7ab023) #1 dw2_get_file_names gdb/dwarf2/read.c:2130 (gdb+0x7ab023) #2 dw_expand_symtabs_matching_file_matcher(dwarf2_per_objfile*, gdb::function_view<bool (char const*, bool)>) gdb/dwarf2/read.c:3105 (gdb+0x7ac6e9) #3 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:16812 (gdb+0x7d040f) #4 objfile::map_symtabs_matching_filename(char const*, char const*, gdb::function_view<bool (symtab*)>) gdb/symfile-debug.c:219 (gdb+0xda5b6e) #5 iterate_over_symtabs(char const*, gdb::function_view<bool (symtab*)>) gdb/symtab.c:648 (gdb+0xdc441d) #6 lookup_symtab(char const*) gdb/symtab.c:662 (gdb+0xdc4522) #7 classify_name gdb/c-exp.y:3083 (gdb+0x61afec) #8 c_yylex gdb/c-exp.y:3251 (gdb+0x61dd13) #9 c_yyparse() build/gdb/c-exp.c.tmp:1988 (gdb+0x61f07e) #10 c_parse(parser_state*) gdb/c-exp.y:3417 (gdb+0x62d864) #11 language_defn::parser(parser_state*) const gdb/language.c:598 (gdb+0x977245) #12 parse_exp_in_context gdb/parse.c:414 (gdb+0xb10b1b) #13 parse_expression(char const*, innermost_block_tracker*, enum_flags<parser_flag>) gdb/parse.c:462 (gdb+0xb1112e) #14 process_print_command_args gdb/printcmd.c:1321 (gdb+0xb4bf8c) #15 print_command_1 gdb/printcmd.c:1335 (gdb+0xb4caaa) #16 print_command gdb/printcmd.c:1468 (gdb+0xb4cdda) #17 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x65b078) #18 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 (gdb+0x65ed53) #19 execute_command(char const*, int) gdb/top.c:575 (gdb+0xe3a7ea) #20 catch_command_errors gdb/main.c:518 (gdb+0xa183fd) #21 execute_cmdargs gdb/main.c:617 (gdb+0xa185bf) #22 captured_main_1 gdb/main.c:1289 (gdb+0xa1aad8) #23 captured_main gdb/main.c:1310 (gdb+0xa1b9da) #24 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xa1b9da) #25 main gdb/gdb.c:39 (gdb+0x42506a) Previous read of size 1 at 0x7b200000410d by thread T2: #0 write_gdbindex gdb/dwarf2/index-write.c:1214 (gdb+0x75bb30) #1 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char const*, dw_index_kind) gdb/dwarf2/index-write.c:1469 (gdb+0x75f803) #2 index_cache::store(dwarf2_per_bfd*, index_cache_store_context const&) gdb/dwarf2/index-cache.c:173 (gdb+0x755a36) #3 cooked_index::maybe_write_index(dwarf2_per_bfd*, index_cache_store_context const&) gdb/dwarf2/cooked-index.c:642 (gdb+0x71c96d) #4 operator() gdb/dwarf2/cooked-index.c:471 (gdb+0x71c96d) #5 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x71c96d) #6 std::function<void ()>::operator()() const /usr/include/c++/7/bits/std_function.h:706 (gdb+0x72a57c) #7 void std::__invoke_impl<void, std::function<void ()>&>(std::__invoke_other, std::function<void ()>&) /usr/include/c++/7/bits/invoke.h:60 (gdb+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x724954) #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+0x724954) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72532b) #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+0x72532b) #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+0x174570d) #23 std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>::_M_run() /usr/include/c++/7/future:1423 (gdb+0x174570d) #24 std::packaged_task<void ()>::operator()() /usr/include/c++/7/future:1556 (gdb+0x174570d) #25 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (gdb+0x174570d) #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+0x17480c0) #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+0x17480c0) #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+0x17480c0) #29 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243 (gdb+0x17480c0) #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+0x17480c0) #31 <null> <null> (libstdc++.so.6+0xdcac2) ... SUMMARY: ThreadSanitizer: data race gdb/dwarf2/read.c:2033 in dw2_get_file_names_reader ... 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::files_read. The two bitfields dwarf2_per_cu_data::files_read and dwarf2_per_cu_data::is_debug_type share the same bitfield container. Fix this by making dwarf2_per_cu_data::files_read a packed<bool, 1>. Tested on x86_64-linux. PR symtab/30718 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30718
2023-08-04[gdb/symtab] Fix data race on dwarf2_per_cu_data::{mark,is_debug_types}Tom de Vries1-5/+5
With gdb build with -fsanitize=thread, and the exec from test-case gdb.base/index-cache.exp, I run into: ... $ rm -f ~/.cache/gdb/*; \ gdb -q -batch -iex "set index-cache enabled on" index-cache \ -ex "print foobar" ... WARNING: ThreadSanitizer: data race (pid=23970) Write of size 1 at 0x7b200000410d by main thread: #0 dw_expand_symtabs_matching_file_matcher(dwarf2_per_objfile*, gdb::function_view<bool (char const*, bool)>) gdb/dwarf2/read.c:3077 (gdb+0x7ac54e) #1 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:16812 (gdb+0x7d039f) #2 objfile::map_symtabs_matching_filename(char const*, char const*, gdb::function_view<bool (symtab*)>) gdb/symfile-debug.c:219 (gdb+0xda5aee) #3 iterate_over_symtabs(char const*, gdb::function_view<bool (symtab*)>) gdb/symtab.c:648 (gdb+0xdc439d) #4 lookup_symtab(char const*) gdb/symtab.c:662 (gdb+0xdc44a2) #5 classify_name gdb/c-exp.y:3083 (gdb+0x61afec) #6 c_yylex gdb/c-exp.y:3251 (gdb+0x61dd13) #7 c_yyparse() build/gdb/c-exp.c.tmp:1988 (gdb+0x61f07e) #8 c_parse(parser_state*) gdb/c-exp.y:3417 (gdb+0x62d864) #9 language_defn::parser(parser_state*) const gdb/language.c:598 (gdb+0x9771c5) #10 parse_exp_in_context gdb/parse.c:414 (gdb+0xb10a9b) #11 parse_expression(char const*, innermost_block_tracker*, enum_flags<parser_flag>) gdb/parse.c:462 (gdb+0xb110ae) #12 process_print_command_args gdb/printcmd.c:1321 (gdb+0xb4bf0c) #13 print_command_1 gdb/printcmd.c:1335 (gdb+0xb4ca2a) #14 print_command gdb/printcmd.c:1468 (gdb+0xb4cd5a) #15 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x65b078) #16 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 (gdb+0x65ed53) #17 execute_command(char const*, int) gdb/top.c:575 (gdb+0xe3a76a) #18 catch_command_errors gdb/main.c:518 (gdb+0xa1837d) #19 execute_cmdargs gdb/main.c:617 (gdb+0xa1853f) #20 captured_main_1 gdb/main.c:1289 (gdb+0xa1aa58) #21 captured_main gdb/main.c:1310 (gdb+0xa1b95a) #22 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xa1b95a) #23 main gdb/gdb.c:39 (gdb+0x42506a) Previous read of size 1 at 0x7b200000410d by thread T1: #0 write_gdbindex gdb/dwarf2/index-write.c:1214 (gdb+0x75bb30) #1 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char const*, dw_index_kind) gdb/dwarf2/index-write.c:1469 (gdb+0x75f803) #2 index_cache::store(dwarf2_per_bfd*, index_cache_store_context const&) gdb/dwarf2/index-cache.c:173 (gdb+0x755a36) #3 cooked_index::maybe_write_index(dwarf2_per_bfd*, index_cache_store_context const&) gdb/dwarf2/cooked-index.c:642 (gdb+0x71c96d) #4 operator() gdb/dwarf2/cooked-index.c:471 (gdb+0x71c96d) #5 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x71c96d) #6 std::function<void ()>::operator()() const /usr/include/c++/7/bits/std_function.h:706 (gdb+0x72a57c) #7 void std::__invoke_impl<void, std::function<void ()>&>(std::__invoke_other, std::function<void ()>&) /usr/include/c++/7/bits/invoke.h:60 (gdb+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x72a5db) #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+0x724954) #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+0x724954) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72434a) #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+0x72532b) #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+0x72532b) #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+0x174568d) #23 std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>::_M_run() /usr/include/c++/7/future:1423 (gdb+0x174568d) #24 std::packaged_task<void ()>::operator()() /usr/include/c++/7/future:1556 (gdb+0x174568d) #25 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (gdb+0x174568d) #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+0x1748040) #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+0x1748040) #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+0x1748040) #29 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243 (gdb+0x1748040) #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+0x1748040) #31 <null> <null> (libstdc++.so.6+0xdcac2) ... SUMMARY: ThreadSanitizer: data race gdb/dwarf2/read.c:3077 in dw_expand_symtabs_matching_file_matcher(dwarf2_per_objfile*, gdb::function_view<bool (char const*, bool)>) ... 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::mark. The two bitfields dwarf2_per_cu_data::mark and dwarf2_per_cu_data::is_debug_type share the same bitfield container. Fix this by making dwarf2_per_cu_data::mark a packed<unsigned int, 1>. Tested on x86_64-linux. PR symtab/30718 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30718
2023-08-04[gdb/symtab] Fix data race on ↵Tom de Vries1-7/+7
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
2023-08-04[gdb/symtab] Fix race on dwarf2_per_cu_data::{queued,is_debug_type}Tom de Vries1-6/+6
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... ================== WARNING: ThreadSanitizer: data race (pid=24296) Write of size 1 at 0x7b200000420d by main thread: #0 queue_comp_unit gdb/dwarf2/read.c:5564 (gdb+0x8939ce) #1 dw2_do_instantiate_symtab gdb/dwarf2/read.c:1754 (gdb+0x885b96) #2 dw2_instantiate_symtab gdb/dwarf2/read.c:1792 (gdb+0x885d86) #3 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+0x88ac77) #4 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:16915 (gdb+0x8c1c8a) #5 objfile::lookup_symbol(block_enum, char const*, domain_enum) gdb/symfile-debug.c:288 (gdb+0xf389a1) #6 lookup_symbol_via_quick_fns gdb/symtab.c:2385 (gdb+0xf66403) #7 lookup_symbol_in_objfile gdb/symtab.c:2516 (gdb+0xf66a67) #8 operator() gdb/symtab.c:2562 (gdb+0xf66bbe) #9 operator() gdb/../gdbsupport/function-view.h:305 (gdb+0xf76ffd) #10 _FUN gdb/../gdbsupport/function-view.h:299 (gdb+0xf77054) #11 gdb::function_view<bool (objfile*)>::operator()(objfile*) const gdb/../gdbsupport/function-view.h:289 (gdb+0xc3f5e3) #12 svr4_iterate_over_objfiles_in_search_order gdb/solib-svr4.c:3455 (gdb+0xeca793) #13 gdbarch_iterate_over_objfiles_in_search_order(gdbarch*, gdb::function_view<bool (objfile*)>, objfile*) gdb/gdbarch.c:5041 (gdb+0x537cad) #14 lookup_global_or_static_symbol gdb/symtab.c:2559 (gdb+0xf66e47) #15 lookup_global_symbol(char const*, block const*, domain_enum) gdb/symtab.c:2615 (gdb+0xf670cc) #16 language_defn::lookup_symbol_nonlocal(char const*, block const*, domain_enum) const gdb/symtab.c:2447 (gdb+0xf666ba) #17 lookup_symbol_aux gdb/symtab.c:2123 (gdb+0xf655ff) #18 lookup_symbol_in_language(char const*, block const*, domain_enum, language, field_of_this_result*) gdb/symtab.c:1931 (gdb+0xf646f7) #19 set_initial_language() gdb/symfile.c:1708 (gdb+0xf429c0) #20 symbol_file_add_main_1 gdb/symfile.c:1212 (gdb+0xf40f54) #21 symbol_file_command(char const*, int) gdb/symfile.c:1681 (gdb+0xf428fb) #22 file_command gdb/exec.c:554 (gdb+0x94f875) #23 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x6d9528) #24 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 (gdb+0x6e0f69) #25 execute_command(char const*, int) gdb/top.c:575 (gdb+0xff3166) #26 command_handler(char const*) gdb/event-top.c:552 (gdb+0x94af08) #27 command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) gdb/event-top.c:788 (gdb+0x94b5c5) #28 tui_command_line_handler gdb/tui/tui-interp.c:104 (gdb+0x10348c6) #29 gdb_rl_callback_handler gdb/event-top.c:259 (gdb+0x94a4ad) #30 rl_callback_read_char readline/readline/callback.c:290 (gdb+0x11bdf87) #31 gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195 (gdb+0x94a2ac) #32 gdb_rl_callback_read_char_wrapper gdb/event-top.c:234 (gdb+0x94a36d) #33 stdin_event_handler gdb/ui.c:155 (gdb+0x1074b6a) #34 handle_file_event gdbsupport/event-loop.cc:573 (gdb+0x1d9502c) #35 gdb_wait_for_event gdbsupport/event-loop.cc:694 (gdb+0x1d95764) #36 gdb_do_one_event(int) gdbsupport/event-loop.cc:264 (gdb+0x1d93b50) #37 start_event_loop gdb/main.c:412 (gdb+0xb5a49e) #38 captured_command_loop gdb/main.c:476 (gdb+0xb5a68d) #39 captured_main gdb/main.c:1320 (gdb+0xb5c80d) #40 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xb5c8bc) #41 main gdb/gdb.c:32 (gdb+0x416776) Previous read of size 1 at 0x7b200000420d by thread T12: #0 write_gdbindex gdb/dwarf2/index-write.c:1229 (gdb+0x8310c8) #1 write_dwarf_index(dwarf2_per_bfd*, char const*, char const*, char const*, dw_index_kind) gdb/dwarf2/index-write.c:1484 (gdb+0x83232f) #2 index_cache::store(dwarf2_per_bfd*, index_cache_store_context*) gdb/dwarf2/index-cache.c:177 (gdb+0x82d62b) #3 cooked_index::maybe_write_index(dwarf2_per_bfd*) gdb/dwarf2/cooked-index.c:640 (gdb+0x7f1bf7) #4 operator() gdb/dwarf2/cooked-index.c:470 (gdb+0x7f0f40) #5 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x7f2909) #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+0x1dac6da) #25 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (gdb+0x1dabffc) #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+0x1dad0ab) #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+0x1dac4dc) #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+0x1daf80e) #29 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243 (gdb+0x1daf799) #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+0x1daf74e) #31 <null> <null> (libstdc++.so.6+0xdcac2) ... SUMMARY: ThreadSanitizer: data race gdb/dwarf2/read.c:5564 in queue_comp_unit ... 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 expanding the CU containing main, and in the process setting dwarf2_per_cu_data::queued. The two bitfields dwarf2_per_cu_data::queue and dwarf2_per_cu_data::is_debug_type share the same bitfield container. Fix this by making dwarf2_per_cu_data::queued 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
2023-08-04[gdb/symtab] Fix data race on bfd::{cacheable,format}Tom de Vries3-20/+43
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... ================== WARNING: ThreadSanitizer: data race (pid=12261) Write of size 4 at 0x7b4400097d08 by main thread: #0 bfd_open_file bfd/cache.c:584 (gdb+0x148bb92) #1 bfd_cache_lookup_worker bfd/cache.c:261 (gdb+0x148b12a) #2 cache_bseek bfd/cache.c:289 (gdb+0x148b324) #3 bfd_seek bfd/bfdio.c:459 (gdb+0x1489c31) #4 _bfd_generic_get_section_contents bfd/libbfd.c:1069 (gdb+0x14977a4) #5 bfd_get_section_contents bfd/section.c:1606 (gdb+0x149cc7c) #6 gdb_bfd_scan_elf_dyntag(int, bfd*, unsigned long*, unsigned long*) gdb/solib.c:1601 (gdb+0xed8eca) #7 elf_locate_base gdb/solib-svr4.c:705 (gdb+0xec28ac) #8 svr4_iterate_over_objfiles_in_search_order gdb/solib-svr4.c:3430 (gdb+0xeca55d) #9 gdbarch_iterate_over_objfiles_in_search_order(gdbarch*, gdb::function_view<bool (objfile*)>, objfile*) gdb/gdbarch.c:5041 (gdb+0x537cad) #10 find_main_name gdb/symtab.c:6270 (gdb+0xf743a5) #11 main_language() gdb/symtab.c:6313 (gdb+0xf74499) #12 set_initial_language() gdb/symfile.c:1700 (gdb+0xf4285c) #13 symbol_file_add_main_1 gdb/symfile.c:1212 (gdb+0xf40e2a) #14 symbol_file_command(char const*, int) gdb/symfile.c:1681 (gdb+0xf427d1) #15 file_command gdb/exec.c:554 (gdb+0x94f74b) #16 do_simple_func gdb/cli/cli-decode.c:95 (gdb+0x6d9528) #17 cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 (gdb+0x6e0f69) #18 execute_command(char const*, int) gdb/top.c:575 (gdb+0xff303c) #19 command_handler(char const*) gdb/event-top.c:552 (gdb+0x94adde) #20 command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) gdb/event-top.c:788 (gdb+0x94b49b) #21 tui_command_line_handler gdb/tui/tui-interp.c:104 (gdb+0x103479c) #22 gdb_rl_callback_handler gdb/event-top.c:259 (gdb+0x94a383) #23 rl_callback_read_char readline/readline/callback.c:290 (gdb+0x11bde5d) #24 gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195 (gdb+0x94a182) #25 gdb_rl_callback_read_char_wrapper gdb/event-top.c:234 (gdb+0x94a243) #26 stdin_event_handler gdb/ui.c:155 (gdb+0x1074a40) #27 handle_file_event gdbsupport/event-loop.cc:573 (gdb+0x1d94f02) #28 gdb_wait_for_event gdbsupport/event-loop.cc:694 (gdb+0x1d9563a) #29 gdb_do_one_event(int) gdbsupport/event-loop.cc:264 (gdb+0x1d93a26) #30 start_event_loop gdb/main.c:412 (gdb+0xb5a374) #31 captured_command_loop gdb/main.c:476 (gdb+0xb5a563) #32 captured_main gdb/main.c:1320 (gdb+0xb5c6e3) #33 gdb_main(captured_main_args*) gdb/main.c:1339 (gdb+0xb5c792) #34 main gdb/gdb.c:32 (gdb+0x416776) Previous read of size 1 at 0x7b4400097d08 by thread T12: #0 bfd_check_format_matches bfd/format.c:323 (gdb+0x1492db4) #1 bfd_check_format bfd/format.c:94 (gdb+0x1492104) #2 build_id_bfd_get(bfd*) gdb/build-id.c:42 (gdb+0x6648f7) #3 index_cache::store(dwarf2_per_bfd*, index_cache_store_context*) gdb/dwarf2/index-cache.c:110 (gdb+0x82d205) #4 cooked_index::maybe_write_index(dwarf2_per_bfd*) gdb/dwarf2/cooked-index.c:640 (gdb+0x7f1bf1) #5 operator() gdb/dwarf2/cooked-index.c:470 (gdb+0x7f0f40) #6 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (gdb+0x7f28f7) #7 std::function<void ()>::operator()() const /usr/include/c++/7/bits/std_function.h:706 (gdb+0x700952) #8 void std::__invoke_impl<void, std::function<void ()>&>(std::__invoke_other, std::function<void ()>&) /usr/include/c++/7/bits/invoke.h:60 (gdb+0x7381a0) #9 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) #10 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) #11 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) #12 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) #13 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) #14 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) #15 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) #16 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) #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()#1}::operator()() const /usr/include/c++/7/mutex:672 (gdb+0x73300d) #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}::operator()() const /usr/include/c++/7/mutex:677 (gdb+0x7330b2) #19 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) #20 pthread_once <null> (libtsan.so.0+0x4457c) #21 __gthread_once /usr/include/c++/7/x86_64-suse-linux/bits/gthr-default.h:699 (gdb+0x72f5dd) #22 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) #23 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) #24 std::__future_base::_Task_state<std::function<void ()>, std::allocator<int>, void ()>::_M_run() /usr/include/c++/7/future:1423 (gdb+0x737bef) #25 std::packaged_task<void ()>::operator()() /usr/include/c++/7/future:1556 (gdb+0x1dac5b0) #26 gdb::thread_pool::thread_function() gdbsupport/thread-pool.cc:242 (gdb+0x1dabed2) #27 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+0x1dacf81) #28 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+0x1dac3b2) #29 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+0x1daf6e4) #30 std::thread::_Invoker<std::tuple<void (gdb::thread_pool::*)(), gdb::thread_pool*> >::operator()() /usr/include/c++/7/thread:243 (gdb+0x1daf66f) #31 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+0x1daf624) #32 <null> <null> (libstdc++.so.6+0xdcac2) ... SUMMARY: ThreadSanitizer: data race bfd/cache.c:584 in bfd_open_file ... The race happens when issuing the "file $exec" command. The race is between: - a worker thread getting the build id while writing the index cache, and in the process reading bfd::format, and - the main thread calling find_main_name, and in the process setting bfd::cacheable. The two bitfields bfd::cacheable and bfd::format share the same bitfield container. Fix this by capturing the build id in the main thread, and using the captured value in the worker thread. Likewise for the dwz build id, which likely suffers from the same issue. While we're at it, also move the creation of the cache directory to the index_cache_store_context constructor, to: - make sure there's no race between subsequent file commands, and - issue any related warning or error messages during the file command. 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
2023-08-04[gdb/symtab] Fix data race on index_cache::m_enabledTom de Vries4-8/+38
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
2023-08-03[gdb/symtab] Remove superfluous handling of Ada main in write_cooked_indexTom de Vries1-21/+6
I filed PR29179 about the following FAIL in test-case gdb.ada/O2_float_param.exp with target board cc-with-gdb-index: ... (gdb) break increment^M Function "increment" not defined.^M Make breakpoint pending on future shared library load? (y or [n]) n^M (gdb) FAIL: gdb.ada/O2_float_param.exp: scenario=all: gdb_breakpoint: \ set breakpoint at increment ... The FAIL was a regression since commit 2cf349be0e3 ("Do not put linkage names into .gdb_index"). Before that commit we had: ... $ readelf -w foo > READELF $ grep callee.*increment READELF [1568] callee__increment: 5 [global, function] [3115] callee.increment: 5 [global, function] ... but after only: ... $ grep callee.*increment READELF [3115] callee.increment: 5 [global, function] ... The regression was fixed by commit 67e83a0deef ("Fix regression in c-linkage-name.exp with gdb index"), which got us again: ... $ grep callee.*increment READELF [1568] callee__increment: 5 [global, function] [3115] callee.increment: 5 [global, function] ... The commit however did not claim that particular PR. A subsequent commit, commit 5fea9794325 ("Improve Ada support in .gdb_index") did claim to fix it, together with commit dd05fc7071a ("Change .gdb_index de-duplication implementation"). The commit 5fea9794325 contained the following addition in write_cooked_index: ... + if (entry->per_cu->lang () == language_ada) + { + /* We want to ensure that the Ada main function's name + appears verbatim in the index. However, this name will + be of the form "_ada_mumble", and will be rewritten by + ada_decode. So, recognize it specially here and add it + to the index by hand. */ + if (entry->tag == DW_TAG_subprogram + && strcmp (main_for_ada, name) == 0) + { + /* Leave it alone. */ + } + else + { + /* In order for the index to work when read back into + gdb, it has to use the encoded name, with any + suffixes stripped. */ + std::string encoded = ada_encode (name, false); + name = obstack_strdup (&symtab->m_string_obstack, + encoded.c_str ()); + } + } ... The code contains some special handling related to the Ada main function, so let's look at that one: foo. Before commit 67e83a0deef we have: ... $ grep foo.*function READELF [3733] foo: 7 [global, function] ... and after: ... $ grep foo.*function READELF [2738] _ada_foo: 7 [global, function] [3733] foo: 7 [global, function] ... so that looks identical to the callee.increment case. At commit 5fea9794325, we have slightly different index numbers: ... $ grep foo.*function READELF [1658] foo: 7 [global, function] [2738] _ada_foo: 7 [global, function] ... but otherwise the same result. If we disable the special handling of the Ada main function like so: ... - if (entry->tag == DW_TAG_subprogram + if (false && entry->tag == DW_TAG_subprogram ... we still have the exact same result because: ... (gdb) p main_for_ada $1 = 0x352e6a0 "_ada_foo" ... and ada_encode ("_ada_foo", false) == "_ada_foo". The comment seems to be copied from debug_names::insert, which does indeed use ada_decode, while the code in write_cooked_index uses ada_encode instead. Remove the superfluous special handling of Ada main in write_cooked_index. Tested on x86_64-linux, with target boards unix and cc-with-gdb-index. Approved-By: Tom Tromey <tom@tromey.com>
2023-07-31Fix bug in fixed-point handlingTom Tromey1-0/+2
Alexandre Oliva found a bug in gdb's handling of fixed-point -- a certain Ada fixed-point type would be misintepreted. The bug was that the DW_AT_small looked like: <1><13cd>: Abbrev Number: 16 (DW_TAG_constant) <13ce> DW_AT_GNU_numerator: 1 <13cf> DW_AT_GNU_denominator: 0x8000000000000000 ... but gdb interpreted the denominator as a negative value.
2023-07-21Fix crash with DW_FORM_implicit_constTom Tromey1-12/+17
Jakub pointed out that using DW_FORM_implicit_const with DW_AT_bit_size would cause gdb to crash. This happened because DW_FORM_implicit_const is not an "unsigned" form, causing as_unsigned to assert. This patch fixes the problem. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30651 Approved-By: Andrew Burgess <aburgess@redhat.com>
2023-07-21[gdb/symtab] Add optimized out static var to cooked indexTom de Vries1-9/+0
Consider the test-case: ... $ cat main.c int main (void) { return 0; } $ cat static-optimized-out.c static int aaa; ... compiled like this: ... $ gcc-12 static-optimized-out.c main.c -g -O2 -flto ... There's a difference in behaviour depending on symtab expansion state: ... $ gdb -q -batch a.out -ex "print aaa" No symbol "aaa" in current context. $ gdb -q -batch a.out -ex "maint expand-symtab" -ex "print aaa" $1 = <optimized out> ... The reason for the difference is that the optimized out variable aaa: ... <1><104>: Abbrev Number: 2 (DW_TAG_variable) <105> DW_AT_name : aaa <109> DW_AT_decl_file : 1 <10a> DW_AT_decl_line : 18 <10b> DW_AT_decl_column : 12 <10c> DW_AT_type : <0x110> ... is not added to the cooked index because of this clause in abbrev_table::read: ... else if (!has_location && !has_specification_or_origin && !has_external && cur_abbrev->tag == DW_TAG_variable) cur_abbrev->interesting = false; ... Fix this inconsistency by making sure that the optimized out variable is added to the cooked index. Regression tested on x86_64-linux. Add two test-cases, a C test-case gdb.opt/static-optimized-out.exp and a dwarf assembly test-case gdb.dwarf2/static-optimized-out.exp. Tested gdb.opt/static-optimized-out.exp with gcc-8 to gcc-12, for which we now consistently get: ... (gdb) print aaa^M $1 = <optimized out>^M ... and with gcc 7.5.0 and clang 13.0.1, for which we still consistently get: ... (gdb) print aaa^M No symbol "aaa" in current context.^M ... due to missing debug info for the variable. PR symtab/30656 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30656 Approved-By: Tom Tromey <tom@tromey.com>
2023-06-28Fix handling of DW_TAG_unspecified_type for AdaTom Tromey1-1/+4
Commit 80eaec735e ("[gdb/symtab] Handle named DW_TAG_unspecified_type DIE") changed the handling of DW_TAG_unspecified_type. Before this change, such types were not entered into the symbol table. It turns out that, when such a type is in the symtab, it can cause failures in Ada. In particular, a private type in another package may be seen locally as "void". Now, it would probably be better to fix this via check_typedef. However, that is somewhat difficult given the state of the DWARF reader -- in particular with gdb_index, this would require expanding potentially many CUs to find the correct type. Instead, this patch changes gdb to not enter a symbol for an unspecified type -- but only for Ada.
2023-06-20Use gdb::byte_vector in agent_exprTom Tromey1-2/+2
This changes agent_expr to use gdb::byte_vector rather than manually reimplementing a vector. Reviewed-by: John Baldwin <jhb@FreeBSD.org>
2023-06-12Simplify case DW_OP_GNU_uninit in dwarf_expr_context::execute_stack_opKevin Buettner1-6/+1
Tom Tromey pointed out that the test and call to error() for the DW_OP_GNU_uninit case in dwarf_expr_context::execute_stack_op (in gdb/dwarf2/expr.c)... if (op_ptr != op_end && *op_ptr != DW_OP_piece && *op_ptr != DW_OP_bit_piece) error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " "be the very last op in a DWARF expression or " "DW_OP_piece/DW_OP_bit_piece piece.")); ...could be replaced by a call to dwarf_expr_require_composition which performs a similar check and outputs a suitable error message.
2023-06-11Permit DW_OP_GNU_uninit to be used with DW_OP_pieceKevin Buettner1-2/+4
This commit implements a fix for a bug reported against GDB on Fedora bugzilla... https://bugzilla.redhat.com/show_bug.cgi?id=2166796 The test case in that bug report involved running gdb against the 'jq' program (which is a command-line JSON processor) on Fedora 37. Since the debug info is compiler (and compile-time option) dependent, it won't necessarily show up in other distributions or even past or future versions of Fedora. (E.g. when trying the example shown below on Fedora 38, GDB says that the value of 'value' has been optimized out. I.e. it does not demonstrate the same DWARF error that can be see when using Fedora 37.) That said, on Fedora 37, the bug could be reproduced as follows: [kev@f37-1 ~]$ gdb jq -q -ex 'b src/util.c:415' -ex 'r </dev/null' Reading symbols from jq... This GDB supports auto-downloading debuginfo from the following URLs: <https://debuginfod.fedoraproject.org/> Enable debuginfod for this session? (y or [n]) y Debuginfod has been enabled. To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit. Reading symbols from /home/kev/.cache/debuginfod_client/9d3c8b4197350a190a74972d481de32abf641aa4/debuginfo... No source file named src/util.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (src/util.c:415) pending. Starting program: /usr/bin/jq </dev/null [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, jq_util_input_next_input (state=0x55555555d7f0) at src/util.c:416 416 if (state->parser == NULL) { (gdb) p value DWARF-2 expression error: DW_OP_GNU_uninit must always be the very last op. This is undesirable - rather than output an error about the DWARF info, we'd prefer to see a value, even if it is uninitialized. Examination of the debuginfo showed the following: <1><468f1>: Abbrev Number: 112 (DW_TAG_subprogram) <468f2> DW_AT_external : 1 <468f2> DW_AT_name : (indirect string, offset: 0x4781): jq_util_input_next_input <468f6> DW_AT_decl_file : 10 <468f6> DW_AT_decl_line : 411 <468f8> DW_AT_decl_column : 4 <468f9> DW_AT_prototyped : 1 <468f9> DW_AT_type : <0x3f2> <468fd> DW_AT_sibling : <0x4692e> ... <2><46921>: Abbrev Number: 102 (DW_TAG_variable) <46922> DW_AT_name : (indirect string, offset: 0x8cb): value <46926> DW_AT_decl_file : 10 <46926> DW_AT_decl_line : 414 <46928> DW_AT_decl_column : 6 <46929> DW_AT_type : <0x3f2> Note that there's no DW_AT_location, so I looked for an abstract origin entry: <2><2dfa0>: Abbrev Number: 90 (DW_TAG_variable) <2dfa1> DW_AT_abstract_origin: <0x46921> <2dfa5> DW_AT_location : 0x27cf1 (location list) <2dfa9> DW_AT_GNU_locviews: 0x27ce1 (Note that the DW_AT_abstract_origin attribute's value is 0x46921 which is the DIE for the local variable "value".) Looking at the location list, I see: 00027cf1 v000000000000000 v000000000000000 views at 00027ce1 for: 000000000002f8fe 000000000002f92e (DW_OP_reg13 (r13); DW_OP_GNU_uninit; DW_OP_piece: 8; DW_OP_reg12 (r12); DW_OP_GNU_uninit; DW_OP_piece: 8) While DW_OP_GNU_uninit is not the very last op, it is the last op prior to DW_OP_piece. The fix involved changing the DW_OP_GNU_uninit case in dwarf_expr_context::execute_stack_op in gdb/dwarf2/expr.c so that DW_OP_GNU_uninit may appear just before DW_OP_piece. With the fix in place, attempting to print 'value' now looks like this: (gdb) p value $1 = [uninitialized] {kind_flags = 0 '\000', pad_ = 0 '\000', offset = 0, size = 0, u = {ptr = 0x0, number = 0}} Note that "[uninitialized]" is part of the output. (But also note that there's an extra space character.) I've made a new test case, gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp, by adapting an existing one, gdb.dwarf2/opt-out-not-implptr.exp. Since it uses the DWARF assembler, the test case does not depend on a specific compiler version or compiler options. Tested on Fedora 37 and Fedora 38.
2023-06-05Use unrelocated_addr in dwarf2_fdeTom Tromey1-32/+39
This changes dwarf2_fde to use the unrelocated_addr type. This pointed out a latent bug in dwarf2_frame_cache, where a relocated address is compared to an unrelocated address.
2023-06-05Use local "text offset" variable in dwarf2_frame_cacheTom Tromey1-5/+6
A few spots in dwarf2_frame_cache use: cache->per_objfile->objfile->text_section_offset () ... and a subsequent patch will add more, so move this into a local variable.
2023-06-05Constify dwarf2_cie::augmentationTom Tromey1-3/+3
I noticed that dwarf2_cie::augmentation could be 'const'.
2023-06-05Use unrelocated_addr in dwarf_decode_linesTom Tromey1-11/+7
This changes dwarf_decode_lines to accept an unrelocated_addr and fixes up the fallout.
2023-06-05Use unrelocated_addr in the DWARF readerTom Tromey13-306/+335
This changes various spots in the DWARF reader to use unrelocated_addr.
2023-06-05Minor cleanup in loclist_describe_locationTom Tromey1-3/+3
loclist_describe_location already has a per_objfile local variable, so use it consistently.
2023-06-05Remove baseaddr parameter from dwarf2_record_block_rangesTom Tromey1-5/+6
dwarf2_record_block_ranges is only ever called with the text section offset, so this patch removes the parameter entirely. This makes a subsequent patch a little simpler.
2023-06-05[gdb] Fix more typosTom de Vries1-1/+1
Fix some more typos: - distinquish -> distinguish - actualy -> actually - singe -> single - frash -> frame - chid -> child - dissassembler -> disassembler - uninitalized -> uninitialized - precontidion -> precondition - regsiters -> registers - marge -> merge - sate -> state - garanteed -> guaranteed - explictly -> explicitly - prefices (nonstandard plural) -> prefixes - bondary -> boundary - formated -> formatted - ithe -> the - arrav -> array - coresponding -> corresponding - owend -> owned - fials -> fails - diasm -> disasm - ture -> true - tpye -> type There's one code change, the name of macro SIG_CODE_BONDARY_FAULT changed to SIG_CODE_BOUNDARY_FAULT. Tested on x86_64-linux.
2023-06-03[gdb] Fix typosTom de Vries2-4/+4
Fix a few typos: - implemention -> implementation - convertion(s) -> conversion(s) - backlashes -> backslashes - signoring -> ignoring - (un)ambigious -> (un)ambiguous - occured -> occurred - hidding -> hiding - temporarilly -> temporarily - immediatelly -> immediately - sillyness -> silliness - similiar -> similar - porkuser -> pokeuser - thats -> that - alway -> always - supercede -> supersede - accomodate -> accommodate - aquire -> acquire - priveleged -> privileged - priviliged -> privileged - priviledges -> privileges - privilige -> privilege - recieve -> receive - (p)refered -> (p)referred - succesfully -> successfully - successfuly -> successfully - responsability -> responsibility - wether -> whether - wich -> which - disasbleable -> disableable - descriminant -> discriminant - construcstor -> constructor - underlaying -> underlying - underyling -> underlying - structureal -> structural - appearences -> appearances - terciarily -> tertiarily - resgisters -> registers - reacheable -> reachable - likelyhood -> likelihood - intepreter -> interpreter - disassemly -> disassembly - covnersion -> conversion - conviently -> conveniently - atttribute -> attribute - struction -> struct - resonable -> reasonable - popupated -> populated - namespaxe -> namespace - intialize -> initialize - identifer(s) -> identifier(s) - expection -> exception - exectuted -> executed - dungerous -> dangerous - dissapear -> disappear - completly -> completely - (inter)changable -> (inter)changeable - beakpoint -> breakpoint - automativ -> automatic - alocating -> allocating - agressive -> aggressive - writting -> writing - reguires -> requires - registed -> registered - recuding -> reducing - opeartor -> operator - ommitted -> omitted - modifing -> modifying - intances -> instances - imbedded -> embedded - gdbaarch -> gdbarch - exection -> execution - direcive -> directive - demanged -> demangled - decidely -> decidedly - argments -> arguments - agrument -> argument - amespace -> namespace - targtet -> target - supress(ed) -> suppress(ed) - startum -> stratum - squence -> sequence - prompty -> prompt - overlow -> overflow - memember -> member - languge -> language - geneate -> generate - funcion -> function - exising -> existing - dinking -> syncing - destroh -> destroy - clenaed -> cleaned - changep -> changedp (name of variable) - arround -> around - aproach -> approach - whould -> would - symobl -> symbol - recuse -> recurse - outter -> outer - freeds -> frees - contex -> context Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-15Correctly handle forward DIE references in scannerTom Tromey1-3/+2
The cooked index scanner has special code to handle forward DIE references. However, a bug report lead to the discovery that this code does not work -- the "deferred_entry::spec_offset" field is written to but never used, i.e., the lookup is done using the wrong key. This patch fixes the bug and adds a regression test. The test in the bug itself used a thread_local variable, which provoked a failure at runtime. This test instead uses "maint print objfiles" and then inspects to ensure that the entry in question has a parent. This lets us avoid a clang dependency in the test. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30271
2023-05-12Handle Ada Pragma Import and Pragma ExportTom Tromey3-0/+252
Ada can import C APIs and also export Ada constructs to C via Pragma Import and Pragma Export. This patch adds support for these to gdb, by arranging to either defer some aspects of a symbol to the underlying C symbol (for Import) or by introducing a second symbol (for Export). A somewhat tricky approach is needed, both because gdb doesn't generally handle symbol aliasing, and because Ada treats symbol names in an unusual way (as compared to the rest of gdb).
2023-05-12Add dynamic_prop::is_constantTom Tromey1-5/+5
I noticed many spots checking whether a dynamic property's kind is PROP_CONST. Some spots, I think, are doing a slightly incorrect check -- checking for != PROP_UNDEFINED where == PROP_CONST is actually required, the key thing being that const_val may only be called for PROP_CONST properties. This patch adds dynamic::is_constant and then updates these checks to use it. Regression tested on x86-64 Fedora 36.
2023-05-11Do not print <synthetic pointer> when piece is optimized outTom Tromey1-6/+13
A user reported a bug where printing a certain array of integer types would result in the nonsensical: (gdb) p l_126 $1 = {6639779683436459270, <synthetic pointer>, <synthetic pointer>, <synthetic pointer>} I tracked this down to some issues in the DWARF expression code. First, check_pieced_synthetic_pointer did not account for the situation where a location expression does not describe all the bits of a value -- in this case it returned true, meaning there is a synthetic pointer, but in fact these bits are optimized out. (It turns out this incorrect output had already been erroneously tested for as well.) Next, rw_pieced_value did not mark these bits as optimized-out, either. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30296
2023-05-05Simplify decode_locdescTom Tromey1-137/+66
While looking into another bug, I noticed that the DWARF cooked indexer picks up an address for this symbol: <1><82>: Abbrev Number: 2 (DW_TAG_variable) <83> DW_AT_specification: <0x9f> <87> DW_AT_location : 10 byte block: e 0 0 0 0 0 0 0 0 e0 (DW_OP_const8u: 0 0; DW_OP_GNU_push_tls_address or DW_OP_HP_unknown) <92> DW_AT_linkage_name: (indirect string, offset: 0x156): _ZN9container8tlsvar_0E This happens because decode_locdesc allows the use of DW_OP_GNU_push_tls_address. This didn't make sense to me. I looked into it a bit more, and I think decode_locdesc is used in three ways: 1. Find a constant address of a symbol that happens to be encoded as a location expression. 2. Find the offset of a function in a virtual table. (This one should probably be replaced by code to just evaluate the expression in gnu-v3-abi.c -- but there's no point yet because no compiler actually seems to emit correct DWARF here, see the bug linked in the patch.) 3. Find the offset of a field, if the offset is a constant. None of these require TLS. This patch simplifies decode_locdesc by removing any opcodes that don't fit into the above. It also changes the API a little, to make it less difficult to use. Regression tested on x86-64 Fedora 36.
2023-04-29gdb: Fix building with latest libc++Manoj Gupta1-1/+1
Latest libc++[1] causes transitive include to <locale> when <mutex> or <thread> header is included. This causes gdb to not build[2] since <locale> defines isupper/islower etc. functions that are explicitly macroed-out in safe-ctype.h to prevent their use. Use the suggestion from libc++ to include <locale> internally when building in C++ mode to avoid build errors. Use safe-gdb-ctype.h as the include instead of "safe-ctype.h" to keep this isolated to gdb since rest of binutils does not seem to use much C++. [1]: https://reviews.llvm.org/D144331 [2]: https://issuetracker.google.com/issues/277967395
2023-04-21Handle function descriptors in call_site_targetTom Tromey1-1/+5
call_site_target::iterate_over_addresses may look up a minimal symbol. On platforms like PPC64 that use function descriptors, this may find an unexpected address. The fix is to use gdbarch_convert_from_func_ptr_addr to convert from a function descriptor to the address recorded at the call site. I've added a new test case that is based on the internal AdaCore test that provoked this bug. However, I'm unable to test it as-is on PPC64.
2023-04-18PowerPC: fix _Float128 type output stringCarl Love1-4/+19
PowerPC supports two 128-bit floating point formats, the IBM long double and IEEE 128-bit float. The issue is the DWARF information does not distinguish between the two. There have been proposals of how to extend the DWARF information as discussed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104194 but has not been fully implemented. GCC introduced the _Float128 internal type as a work around for the issue. The workaround is not transparent to GDB. The internal _Float128 type name is printed rather then the user specified long double type. This patch adds a new gdbarch method to allow PowerPC to detect the GCC workaround. The workaround checks for "_Float128" name when reading the base typedef from the die_info. If the workaround is detected, the type and format fields from the _Float128 typedef are copied to the long double typedef. The same is done for the complex long double typedef. This patch fixes 74 regression test failures in gdb.base/whatis-ptype-typedefs.exp on PowerPC with IEEE float 128 as the default on GCC. It fixes one regression test failure in gdb.base/complex-parts.exp. The patch has been tested on Power 10 where GCC defaults to IEEE Float 128-bit and on Power 10 where GCC defaults to the IBM 128-bit float. The patch as also been tested on X86-64 with no new regression failures.
2023-04-17[gdb/symtab] Handle empty file name in .debug_line sectionTom de Vries1-0/+4
With DWARF 5, it's possible to produce an empty file name in the File Name Table of the .debug_line section: ... The File Name Table (offset 0x112, lines 1, columns 2): Entry Dir Name 0 1 (indirect line string, offset: 0x2d): ... Currently, when gdb reads an exec containing such debug info, it segfaults: ... Thread 1 "gdb" received signal SIGSEGV, Segmentation fault. 0x000000000072cd38 in dwarf2_start_subfile (cu=0x2badc50, fe=..., lh=...) at \ gdb/dwarf2/read.c:18716 18716 if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL) ... because read_direct_string transforms "" into a nullptr, and we end up dereferencing the nullptr. Note that the behaviour of read_direct_string has been present since repo creation. Fix this in read_formatted_entries, by transforming nullptr filenames in to "" filenames. Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com> PR symtab/30357 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30357
2023-04-10gdb/dwarf: Fix MinGW buildThiago Jung Bauermann1-1/+1
Unfortunately MinGW doesn't support std::future yet, so this causes the build to fail. Use GDB's version which provides a fallback for this case. Tested for regressions on native aarch64-linux. Approved-By: Tom Tromey <tromey@adacore.com>
2023-03-31Fix race in background index-cache writingTom Tromey3-11/+24
Tom de Vries pointed out a bug in the index-cache background writer -- sometimes it will fail. He also noted that it fails when the number of worker threads is set to zero. These turn out to be the same problem -- the cache can't be written to until the per-BFD's "index_table" member is set. This patch avoids the race by rearranging the code slightly, to ensure the cache cannot possibly be written before the member is set. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30261
2023-03-31GDB: Bring back the handling of DW_CC_programMaciej W. Rozycki1-1/+27
Fix a functional regression and restore the handling of DW_CC_program code of DW_AT_calling_convention attribute for determining the name of the starting function of the program where the DW_AT_main_subprogram attribute has not been provided, such as with Fortran code compiled with GCC versions 4.5.4 and below, or where DWARF version 3 or below has been requested. Without it "main" is considered the starting function. Cf. GCC PR fortran/43414. Original code was removed with commit 6209cde4ddb8 ("Delete DWARF psymtab code"), and then an update to complement commit 81873cc81eff ("[gdb/symtab] Support DW_AT_main_subprogram with -readnow.") has also been included here.
2023-03-29Use the correct frame when evaluating a dynamic propertyTom Tromey1-2/+2
The test case in this patch shows an unusual situation: an Ada array has a dynamic bound, but the bound comes from a frame that's referred to by the static link. This frame is correctly found when evaluating the array variable itself, but is lost when evaluating the array's bounds. This patch fixes the problem by passing this frame through to value_at_lazy in the DWARF expression evaluator.
2023-03-27Populate seen_names hash in cooked_index_shard::do_finalizeTom Tromey1-0/+1
Hannes pointed out that cooked_index_shard::do_finalize never populates the seen_names hash table. This patch adds the necessary store. This reduces memory use a little for "gdb gdb": (before) Space used: 28909568 (+0 for this command) (after) Space used: 28884992 (+0 for this command) What this means, btw, is that in gdb there are not many symbols that are both mentioned in many CUs and that also require name canonicalization. It's possible this would differ in other programs.
2023-03-24[gdb/symtab] Fix line number of static const class memberTom de Vries1-2/+1
Since commit 6d263fe46e0 ("Avoid bad breakpoints with --gc-sections"), there was a silent regression on openSUSE Leap 15.4 for test-case gdb.cp/m-static.exp, from: ... (gdb) info variable everywhere^M All variables matching regular expression "everywhere":^M ^M File /home/vries/tmp.local-remote-host-native/m-static.h:^M 8: const int gnu_obj_4::everywhere;^M (gdb) ... to: ... (gdb) info variable everywhere^M All variables matching regular expression "everywhere":^M ^M File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static.h:^M 8: const int gnu_obj_4::everywhere;^M ^M File /data/vries/gdb/src/gdb/testsuite/gdb.cp/m-static1.cc:^M 8: const int gnu_obj_4::everywhere;^M (gdb) ... Another regression was found due to that commit, and it was fixed in commit 99d679e7b30 ("[gdb/symtab] Fix "file index out of range" complaint") by limiting the scope of the fix in the original commit. Fix this regression by yet further limiting the scope of that fix, making sure that this bit in dwarf_decode_lines is executed again for m-static1.cc: ... /* Make sure a symtab is created for every file, even files which contain only variables (i.e. no code with associated line numbers). */ ... Tested on x86_64-linux. PR symtab/30265 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30265
2023-03-22Remove unnecessary castTom Tromey1-2/+1
I found an upcast from template_symbol to symbol. This was necessary long ago, but since symbols use inheritance now, it is not. This patch removes it. Tested by rebuilding.
2023-03-18Rename objfile_type to builtin_typeTom Tromey2-9/+9
This renames objfile_type to be an overload of builtin_type, in preparation for their unification. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Use type allocator for set typesTom Tromey1-1/+2
This changes the set type creation function to accept a type allocator, and updates all the callers. Note that symbol readers should generally allocate on the relevant objfile, regardless of the underlying type of the set, which is what this patch implements. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Use type allocator for array typesTom Tromey1-4/+5
This changes the array type creation functions to accept a type allocator, and updates all the callers. Note that symbol readers should generally allocate on the relevant objfile, regardless of the placement of the index type of the array, which is what this patch implements. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Use type allocator for range typesTom Tromey1-7/+11
This changes the range type creation functions to accept a type allocator, and updates all the callers. Note that symbol readers should generally allocate on the relevant objfile, regardless of the underlying type of the range, which is what this patch implements. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Unify arch_pointer_type and init_pointer_typeTom Tromey1-1/+1
This unifies arch_pointer_type and init_pointer_type by using a type allocator. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Unify arch_decfloat_type and init_decfloat_typeTom Tromey1-1/+1
This unifies arch_decfloat_type and init_decfloat_type by using a type allocator. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Unify arch_float_type and init_float_typeTom Tromey1-1/+1
This unifies arch_float_type and init_float_type by using a type allocator. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18Unify arch_boolean_type and init_boolean_typeTom Tromey1-1/+1
This unifies arch_boolean_type and init_boolean_type by using a type allocator. Reviewed-By: Simon Marchi <simon.marchi@efficios.com>