Bug 31697 - heap-use-after-free in symtab
Summary: heap-use-after-free in symtab
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: symtab (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 15.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-05-03 11:43 UTC by Hannes Domani
Modified: 2024-05-08 15:01 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
valgrind log (2.78 KB, text/plain)
2024-05-03 11:43 UTC, Hannes Domani
Details
heob output as html (2.86 KB, text/html)
2024-05-03 11:46 UTC, Hannes Domani
Details
asan.log (2.42 KB, text/plain)
2024-05-03 12:31 UTC, Tom de Vries
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Hannes Domani 2024-05-03 11:43:50 UTC
Created attachment 15486 [details]
valgrind log

With current gdb 14 I get heap-use-after-free crash when 'start'ing inside TUI triggers a file reload.
The file reload was happening because of PR31636, but can be reproduced when 'touch'ing the executable beforehand.
It happens with all executables when doing the steps in this order:

> $ gdb -q gdb-12213.exe
> Reading symbols from gdb-12213.exe...
> (gdb) tui enable
> ---------- TUI ----------
> (gdb) !touch gdb-12213.exe
> (gdb) start
> `C:\src\tests\gdb-12213.exe' has changed; re-reading symbols.

Here it crashes, heob tells me it's because acces to already-freed memory:

> unhandled exception code: 0xC0000005 (ACCESS_VIOLATION)
>   exception on: '1 [19992]'
>     0x00007FF7DF430000   C:\src\repos\gdb64\bin\gdb.exe
>       0x00007FF7DF7B70B7   C:\src\repos\binutils-gdb.git\gdb\symtab.h:503:12 [general_symbol_info::language() const]
>                            C:\src\repos\binutils-gdb.git\gdb\symtab.c:1108:16 [general_symbol_info::search_name() const]
>                            C:\src\repos\binutils-gdb.git\gdb\symtab.c:1246:57 [eq_symbol_entry]
>                            C:\src\repos\binutils-gdb.git\gdb\symtab.c:1431:23 [symbol_cache_lookup]
>                            C:\src\repos\binutils-gdb.git\gdb\symtab.c:2573:32 [lookup_global_or_static_symbol]
>       0x00007FF7DF7B8206   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2641:38 [lookup_global_symbol(char const*, block const*, domain_enum)]
>       0x00007FF7DF7B82C5   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2473:31 [language_defn::lookup_symbol_nonlocal(char const*, block const*, domain_enum) const]
>       0x00007FF7DF7BF545   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2150:44 [lookup_symbol_aux]
>       0x00007FF7DF7BF896   C:\src\repos\binutils-gdb.git\gdb\symtab.c:1955:28 [lookup_symbol_in_language(char const*, block const*, domain_enum, language, field_of_this_result*)]
>       0x00007FF7DF7BF918   C:\src\repos\binutils-gdb.git\gdb\symtab.c:1968:36 [lookup_symbol(char const*, block const*, domain_enum, field_of_this_result*)]
>       0x00007FF7DF785F4A   C:\src\repos\binutils-gdb.git\gdb\source.c:319:37 [select_source_symtab()]
>       0x00007FF7DF80CD1D   C:\src\repos\binutils-gdb.git\gdb\tui\tui-disasm.c:401:39 [tui_get_begin_asm_address(gdbarch**, unsigned long long*)]
>       0x00007FF7DF821B2E   C:\src\repos\binutils-gdb.git\gdb\tui\tui-winsource.c:55:33 [tui_display_main()]
>       0x00007FF7DF7AC922   c:\msys64\mingw64\x86_64-w64-mingw32\include\c++\11.2.0\bits\std_function.h:560:9 [std::function<void (program_space*)>::operator()(program_space*) const]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\observable.h:166:9 [gdb::observers::observable<program_space*>::notify(program_space*) const]
>                            C:\src\repos\binutils-gdb.git\gdb\symfile.c:2918:47 [clear_symtab_users(enum_flags<symfile_add_flag>)]
>       0x00007FF7DF7AE61C   C:\src\repos\binutils-gdb.git\gdb\symfile.c:2690:26 [reread_symbols(int)]
>       0x00007FF7DF63E8F3   C:\src\repos\binutils-gdb.git\gdb\infcmd.c:398:18 [run_command_1]
>       0x00007FF7DF4EE4C5   C:\src\repos\binutils-gdb.git\gdb\cli\cli-decode.c:2735:17 [cmd_func(cmd_list_element*, char const*, int)]
>       0x00007FF7DF7FA2E0   C:\src\repos\binutils-gdb.git\gdb\top.c:575:11 [execute_command(char const*, int)]
>       0x00007FF7DF5C16EE   C:\src\repos\binutils-gdb.git\gdb\event-top.c:552:23 [command_handler(char const*)]
>       0x00007FF7DF5C29D7   C:\src\repos\binutils-gdb.git\gdb\event-top.c:788:23 [command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&)]
>       0x00007FF7DF5C2075   C:\src\repos\binutils-gdb.git\gdb\event-top.c:259:25 [gdb_rl_callback_handler]
>       0x00007FF7DF87B484   C:\src\repos\binutils-gdb.git\readline\readline\callback.c:290:5 [rl_callback_read_char]
>       0x00007FF7DF5C122D   C:\src\repos\binutils-gdb.git\gdb\event-top.c:195:29 [gdb_rl_callback_read_char_wrapper_noexcept]
>       0x00007FF7DF5C1F23   C:\src\repos\binutils-gdb.git\gdb\event-top.c:234:51 [gdb_rl_callback_read_char_wrapper]
>       0x00007FF7DF82A4CD   C:\src\repos\binutils-gdb.git\gdb\ui.c:155:22 [stdin_event_handler]
>       0x00007FF7DF980EDA   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:573:22 [handle_file_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:716:25 [gdb_wait_for_event]
>       0x00007FF7DF9818DC   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:593:3 [gdb_wait_for_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:264:29 [gdb_do_one_event(int)]
>       0x00007FF7DF683E21   C:\src\repos\binutils-gdb.git\gdb\main.c:407:30 [start_event_loop]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:471:20 [captured_command_loop]
>       0x00007FF7DF6878F4   C:\src\repos\binutils-gdb.git\gdb\main.c:1324:26 [captured_main]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:1343:21 [gdb_main(captured_main_args*)]
>       0x00007FF7DFE5D44F   C:\src\repos\binutils-gdb.git\gdb\gdb.c:39:19 [main]
>       0x00007FF7DF431430   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:345:15 [__tmainCRTStartup]
>       0x00007FF7DF4315B5   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:220:9 [mainCRTStartup]
>   read access violation at 0x0000014125ED0A68
>   freed block 0x0000014125ED0020 (size 4064, offset +2632)
>   allocated on: (#10393) '1 [19992]'
>                            [malloc]
>     0x00007FF7DF430000   C:\src\repos\gdb64\bin\gdb.exe
>       0x00007FF7DF4640AB   C:\src\repos\binutils-gdb.git\gdb\alloc.c:57:16 [xmalloc]
>       0x00007FF7DF96D000   C:\src\repos\binutils-gdb.git\libiberty\obstack.c:94:12 [call_chunkfun]
>                            C:\src\repos\binutils-gdb.git\libiberty\obstack.c:206:43 [_obstack_newchunk]
>       0x00007FF7DF5A730C   C:\src\repos\binutils-gdb.git\gdbsupport\gdb_obstack.h:144:12 [allocate_on_obstack::operator new(unsigned long long, obstack*)]
>                            C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:19004:40 [new_symbol]
>       0x00007FF7DF5AA5BD   C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:6718:18 [process_die]
>       0x00007FF7DF5AA6F8   C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:7686:16 [read_file_scope]
>                            C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:6658:23 [process_die]
>       0x00007FF7DF5AFEE2   C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:6422:15 [process_full_comp_unit]
>                            C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:5696:26 [process_queue]
>                            C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:1770:19 [dw2_do_instantiate_symtab]
>                            C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:1792:33 [dw2_instantiate_symtab]
>       0x00007FF7DF5B0663   C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:3042:27 [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*)>)]
>       0x00007FF7DF5B0EFE   C:\src\repos\binutils-gdb.git\gdb\dwarf2\read.c:16954:41 [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)]
>       0x00007FF7DF7A6865   C:\src\repos\binutils-gdb.git\gdb\symfile-debug.c:285:42 [objfile::lookup_symbol(block_enum, char const*, domain_enum)]
>       0x00007FF7DF7B594C   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2411:33 [lookup_symbol_via_quick_fns]
>                            C:\src\repos\binutils-gdb.git\gdb\symtab.c:2542:40 [lookup_symbol_in_objfile]
>       0x00007FF7DF7B5AD4   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2588:39 [operator()]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\function-view.h:305:33 [operator()]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\function-view.h:299:17 [_FUN]
>       0x00007FF7DF85DF6D   C:\src\repos\binutils-gdb.git\gdbsupport\function-view.h:289:12 [gdb::function_view<bool (objfile*)>::operator()(objfile*) const]
>                            C:\src\repos\binutils-gdb.git\gdb\windows-tdep.c:586:9 [windows_iterate_over_objfiles_in_search_order]
>       0x00007FF7DF47FBD4   C:\src\repos\binutils-gdb.git\gdb\gdbarch.c:5078:50 [gdbarch_iterate_over_objfiles_in_search_order(gdbarch*, gdb::function_view<bool (objfile*)>, objfile*)]
>       0x00007FF7DF7B700A   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2585:7 [lookup_global_or_static_symbol]
>       0x00007FF7DF7B8206   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2641:38 [lookup_global_symbol(char const*, block const*, domain_enum)]
>       0x00007FF7DF7B82C5   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2473:31 [language_defn::lookup_symbol_nonlocal(char const*, block const*, domain_enum) const]
>       0x00007FF7DF7BF545   C:\src\repos\binutils-gdb.git\gdb\symtab.c:2150:44 [lookup_symbol_aux]
>       0x00007FF7DF7BF896   C:\src\repos\binutils-gdb.git\gdb\symtab.c:1955:28 [lookup_symbol_in_language(char const*, block const*, domain_enum, language, field_of_this_result*)]
>       0x00007FF7DF7BF918   C:\src\repos\binutils-gdb.git\gdb\symtab.c:1968:36 [lookup_symbol(char const*, block const*, domain_enum, field_of_this_result*)]
>       0x00007FF7DF785F4A   C:\src\repos\binutils-gdb.git\gdb\source.c:319:37 [select_source_symtab()]
>       0x00007FF7DF80CD1D   C:\src\repos\binutils-gdb.git\gdb\tui\tui-disasm.c:401:39 [tui_get_begin_asm_address(gdbarch**, unsigned long long*)]
>       0x00007FF7DF821B2E   C:\src\repos\binutils-gdb.git\gdb\tui\tui-winsource.c:55:33 [tui_display_main()]
>       0x00007FF7DF823C4C   C:\src\repos\binutils-gdb.git\gdb\tui\tui.c:499:22 [tui_enable()]
>       0x00007FF7DF8240C1   C:\src\repos\binutils-gdb.git\gdb\tui\tui.c:123:15 [tui_rl_switch_mode]
>       0x00007FF7DF864A46   C:\src\repos\binutils-gdb.git\readline\readline\readline.c:892:9 [_rl_dispatch_subseq]
>       0x00007FF7DF86551D   C:\src\repos\binutils-gdb.git\readline\readline\readline.c:801:11 [_rl_dispatch_callback]
>       0x00007FF7DF87B5CE   C:\src\repos\binutils-gdb.git\readline\readline\callback.c:233:10 [rl_callback_read_char]
>       0x00007FF7DF5C122D   C:\src\repos\binutils-gdb.git\gdb\event-top.c:195:29 [gdb_rl_callback_read_char_wrapper_noexcept]
>       0x00007FF7DF5C1F23   C:\src\repos\binutils-gdb.git\gdb\event-top.c:234:51 [gdb_rl_callback_read_char_wrapper]
>       0x00007FF7DF82A4CD   C:\src\repos\binutils-gdb.git\gdb\ui.c:155:22 [stdin_event_handler]
>       0x00007FF7DF980EDA   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:573:22 [handle_file_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:716:25 [gdb_wait_for_event]
>       0x00007FF7DF9818DC   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:593:3 [gdb_wait_for_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:264:29 [gdb_do_one_event(int)]
>       0x00007FF7DF683E21   C:\src\repos\binutils-gdb.git\gdb\main.c:407:30 [start_event_loop]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:471:20 [captured_command_loop]
>       0x00007FF7DF6878F4   C:\src\repos\binutils-gdb.git\gdb\main.c:1324:26 [captured_main]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:1343:21 [gdb_main(captured_main_args*)]
>       0x00007FF7DFE5D44F   C:\src\repos\binutils-gdb.git\gdb\gdb.c:39:19 [main]
>       0x00007FF7DF431430   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:345:15 [__tmainCRTStartup]
>       0x00007FF7DF4315B5   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:220:9 [mainCRTStartup]
>   freed on: '1 [19992]'
>                            [free]
>     0x00007FF7DF430000   C:\src\repos\gdb64\bin\gdb.exe
>       0x00007FF7DF96D151   C:\src\repos\binutils-gdb.git\libiberty\obstack.c:103:5 [call_freefun]
>                            C:\src\repos\binutils-gdb.git\libiberty\obstack.c:280:7 [_obstack_free]
>       0x00007FF7DF7AEADE   C:\src\repos\binutils-gdb.git\gdb\symfile.c:2579:4 [reread_symbols(int)]
>       0x00007FF7DF63E8F3   C:\src\repos\binutils-gdb.git\gdb\infcmd.c:398:18 [run_command_1]
>       0x00007FF7DF4EE4C5   C:\src\repos\binutils-gdb.git\gdb\cli\cli-decode.c:2735:17 [cmd_func(cmd_list_element*, char const*, int)]
>       0x00007FF7DF7FA2E0   C:\src\repos\binutils-gdb.git\gdb\top.c:575:11 [execute_command(char const*, int)]
>       0x00007FF7DF5C16EE   C:\src\repos\binutils-gdb.git\gdb\event-top.c:552:23 [command_handler(char const*)]
>       0x00007FF7DF5C29D7   C:\src\repos\binutils-gdb.git\gdb\event-top.c:788:23 [command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&)]
>       0x00007FF7DF5C2075   C:\src\repos\binutils-gdb.git\gdb\event-top.c:259:25 [gdb_rl_callback_handler]
>       0x00007FF7DF87B484   C:\src\repos\binutils-gdb.git\readline\readline\callback.c:290:5 [rl_callback_read_char]
>       0x00007FF7DF5C122D   C:\src\repos\binutils-gdb.git\gdb\event-top.c:195:29 [gdb_rl_callback_read_char_wrapper_noexcept]
>       0x00007FF7DF5C1F23   C:\src\repos\binutils-gdb.git\gdb\event-top.c:234:51 [gdb_rl_callback_read_char_wrapper]
>       0x00007FF7DF82A4CD   C:\src\repos\binutils-gdb.git\gdb\ui.c:155:22 [stdin_event_handler]
>       0x00007FF7DF980EDA   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:573:22 [handle_file_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:716:25 [gdb_wait_for_event]
>       0x00007FF7DF9818DC   C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:593:3 [gdb_wait_for_event]
>                            C:\src\repos\binutils-gdb.git\gdbsupport\event-loop.cc:264:29 [gdb_do_one_event(int)]
>       0x00007FF7DF683E21   C:\src\repos\binutils-gdb.git\gdb\main.c:407:30 [start_event_loop]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:471:20 [captured_command_loop]
>       0x00007FF7DF6878F4   C:\src\repos\binutils-gdb.git\gdb\main.c:1324:26 [captured_main]
>                            C:\src\repos\binutils-gdb.git\gdb\main.c:1343:21 [gdb_main(captured_main_args*)]
>       0x00007FF7DFE5D44F   C:\src\repos\binutils-gdb.git\gdb\gdb.c:39:19 [main]
>       0x00007FF7DF431430   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:345:15 [__tmainCRTStartup]
>       0x00007FF7DF4315B5   C:\gcc\src\mingw-w64-v8.0.2\mingw-w64-crt\crt\crtexe.c:220:9 [mainCRTStartup]

I see the same when I use valgrind on linux, the log is attached.
Note that I can't confirm if this bug also exists on master, since there gdb crashes much earlier because of PR31694.
Comment 1 Hannes Domani 2024-05-03 11:46:09 UTC
Created attachment 15487 [details]
heob output as html
Comment 2 Tom de Vries 2024-05-03 12:20:28 UTC
With current trunk build on aarch64-linux and a hello world a.out, I run into a segmentation fault using:
...
$ gdb -q -batch a.out -ex "tui enable" -ex "shell touch a.out" -ex start
...
Comment 3 Tom de Vries 2024-05-03 12:31:59 UTC
Created attachment 15489 [details]
asan.log

Produced using:
...
$ ( export TERM=xterm-mono; export ASAN_OPTIONS=detect_leaks=0:log_path=asan.log; ./gdb.sh -q -batch a.out -ex "tui enable" -ex "shell touch a.out" -ex start )
...
Comment 4 Tom de Vries 2024-05-03 12:40:25 UTC
Workaround: Use "maint flush symbol-cache".
Comment 5 Tom de Vries 2024-05-03 12:49:47 UTC
At first glance, seems to be an ordering problem.

tui_all_objfiles_removed should be executed after symtab_all_objfiles_removed.

This demonstrator patch fixes it by calling symtab_all_objfiles_removed at the start of tui_all_objfiles_removed:
...
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 58648a8779d..f79c1641cab 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1726,9 +1726,11 @@ symtab_new_objfile_observer (struct objfile *objfile)
   symbol_cache_flush (objfile->pspace);
 }
 
+extern void symtab_all_objfiles_removed (program_space *pspace);
+
 /* This module's 'all_objfiles_removed' observer.  */
 
-static void
+void
 symtab_all_objfiles_removed (program_space *pspace)
 {
   symbol_cache_flush (pspace);
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
index cf48e709ed8..7baebb5e6a8 100644
--- a/gdb/tui/tui-hooks.c
+++ b/gdb/tui/tui-hooks.c
@@ -58,9 +58,14 @@ static void
 tui_new_objfile_hook (struct objfile* objfile)
 { tui_on_objfiles_changed (); }
 
+extern void symtab_all_objfiles_removed (program_space *pspace);
+
 static void
 tui_all_objfiles_removed (program_space *pspace)
-{ tui_on_objfiles_changed (); }
+{
+  symtab_all_objfiles_removed (pspace);
+  tui_on_objfiles_changed ();
+}
 
 /* Observer for the register_changed notification.  */
 
...
Comment 6 Hannes Domani 2024-05-03 13:14:37 UTC
(In reply to Tom de Vries from comment #5)
> At first glance, seems to be an ordering problem.

Yes, I came to the same conclusion.

I can 'fix' it by simply removing the tui_all_objfiles_removed hook, and I wonder if it is even needed at all.
Comment 8 Sourceware Commits 2024-05-07 17:30:16 UTC
The master branch has been updated by Hannes Domani <ssbssa@sourceware.org>:

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

commit d68f983f88c7469befddcf221228070990cf25e1
Author: Hannes Domani <ssbssa@yahoo.de>
Date:   Tue May 7 19:29:21 2024 +0200

    Fix heap-use-after-free because all_objfiles_removed triggers tui_display_main
    
    Since gdb-10 there is a heap-use-after free happening if starting the
    target in TUI triggers a re-reading of symbols.
    
    It can be reproduced with:
    
    $ gdb -q -batch a.out -ex "tui enable" -ex "shell touch a.out" -ex start
    
    ==28392== Invalid read of size 1
    ==28392==    at 0x79E97E: lookup_global_or_static_symbol(char const*, block_enum, objfile*, domain_enum) (symtab.h:503)
    ==28392==    by 0x79F859: lookup_global_symbol(char const*, block const*, domain_enum) (symtab.c:2641)
    ==28392==    by 0x79F8E9: language_defn::lookup_symbol_nonlocal(char const*, block const*, domain_enum) const (symtab.c:2473)
    ==28392==    by 0x7A66EE: lookup_symbol_aux(char const*, symbol_name_match_type, block const*, domain_enum, language, field_of_this_result*) (symtab.c:2150)
    ==28392==    by 0x7A68C9: lookup_symbol_in_language(char const*, block const*, domain_enum, language, field_of_this_result*) (symtab.c:1958)
    ==28392==    by 0x7A6A25: lookup_symbol(char const*, block const*, domain_enum, field_of_this_result*) (symtab.c:1970)
    ==28392==    by 0x77120F: select_source_symtab() (source.c:319)
    ==28392==    by 0x7EE2D5: tui_get_begin_asm_address(gdbarch**, unsigned long*) (tui-disasm.c:401)
    ==28392==    by 0x807558: tui_display_main() (tui-winsource.c:55)
    ==28392==    by 0x7937B5: clear_symtab_users(enum_flags<symfile_add_flag>) (functional:2464)
    ==28392==    by 0x794F40: reread_symbols(int) (symfile.c:2690)
    ==28392==    by 0x6497D1: run_command_1(char const*, int, run_how) (infcmd.c:398)
    ==28392==  Address 0x4e67848 is 3,864 bytes inside a block of size 4,064 free'd
    ==28392==    at 0x4A0A430: free (vg_replace_malloc.c:446)
    ==28392==    by 0x936B63: _obstack_free (obstack.c:280)
    ==28392==    by 0x79541E: reread_symbols(int) (symfile.c:2579)
    ==28392==    by 0x6497D1: run_command_1(char const*, int, run_how) (infcmd.c:398)
    ==28392==    by 0x4FFC45: cmd_func(cmd_list_element*, char const*, int) (cli-decode.c:2735)
    ==28392==    by 0x7DAB50: execute_command(char const*, int) (top.c:575)
    ==28392==    by 0x5D2B43: command_handler(char const*) (event-top.c:552)
    ==28392==    by 0x5D3A50: command_line_handler(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) (event-top.c:788)
    ==28392==    by 0x5D1F4B: gdb_rl_callback_handler(char*) (event-top.c:259)
    ==28392==    by 0x857B3F: rl_callback_read_char (callback.c:290)
    ==28392==    by 0x5D215D: gdb_rl_callback_read_char_wrapper_noexcept() (event-top.c:195)
    ==28392==    by 0x5D232F: gdb_rl_callback_read_char_wrapper(void*) (event-top.c:234)
    
    The problem is that tui_display_main is called by the all_objfiles_removed
    hook, which tries to access the symbol cache.
    This symbol cache is actually stale at this point, and would have been
    flushed immediately afterwards by that same all_objfiles_removed hook.
    
    It's not possible to tell the hook to call the observers in a specific
    order, but in this case the tui_all_objfiles_removed observer is actually
    not needed, since it only calls tui_display_main, and a 'main' can only
    be found if objfiles are added, not removed.
    
    So the fix is to simply remove the tui_all_objfiles_removed observer.
    
    The clearing of the source window (if symbols were removed by e.g. 'file'
    without arguments) still works, since this is done by the
    tui_before_prompt observer.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31697
    Approved-By: Tom Tromey <tom@tromey.com>
Comment 9 Hannes Domani 2024-05-07 17:32:05 UTC
Fixed.
Comment 10 Sourceware Commits 2024-05-08 15:01:40 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

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

commit 0fd705062ee0bb570ac7a1201d6f3cc2ed96f95d
Author: Tom de Vries <tdevries@suse.de>
Date:   Wed May 8 17:02:15 2024 +0200

    [gdb/testsuite] Add gdb.tui/reread.exp
    
    Add a regression test for commit d68f983f88c ("Fix heap-use-after-free because
    all_objfiles_removed triggers tui_display_main").
    
    When building with address sanitizer, and reverting the commit it triggers the
    heap-use-after-free.
    
    Tested on aarch64-linux.
    
    PR symtab/31697
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31697