Bug 33775 - [gdb/symtab] data race in dwarf2_per_cu::{set_addr_size,set_offset_size,set_ref_addr_size}
Summary: [gdb/symtab] data race in dwarf2_per_cu::{set_addr_size,set_offset_size,set_r...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: symtab (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 17.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 29366
  Show dependency treegraph
 
Reported: 2026-01-08 16:21 UTC by Tom de Vries
Modified: 2026-01-14 21:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
Project(s) to access:
ssh public key:


Attachments
gdb.log.gz (866.06 KB, application/gzip)
2026-01-08 20:40 UTC, Tom de Vries
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2026-01-08 16:21:20 UTC
I build gdb with thread sanitizer on aarch64-linux, and I'm running into:
...
$ grep SUMMARY: gdb.log | sort | uniq -c
    346 SUMMARY: ThreadSanitizer: data race /home/vries/gdb/src/gdb/dwarf2/read.h:314 in dwarf2_per_cu::set_addr_size(unsigned char)
    170 SUMMARY: ThreadSanitizer: data race /home/vries/gdb/src/gdb/dwarf2/read.h:327 in dwarf2_per_cu::set_offset_size(unsigned char)
    208 SUMMARY: ThreadSanitizer: data race /home/vries/gdb/src/gdb/dwarf2/read.h:340 in dwarf2_per_cu::set_ref_addr_size(unsigned char)
...

Functions introduced by:
...
commit c20beece0854fa2fe2541b4a121d9b73188387f1
Date:   Fri Nov 21 15:14:03 2025 -0500

    gdb/dwarf: store addr/offset/ref_addr sizes in dwarf2_per_cu
...
so possibly a regression since that commit.
Comment 1 Simon Marchi 2026-01-08 17:01:48 UTC
Does this reproduce on x86 Linux, or should I specifically look for an aarch64 machine?

Can you name one test in particular that fails, so I can start investigating there?
Comment 2 Tom de Vries 2026-01-08 20:21:31 UTC
(In reply to Tom de Vries from comment #0)
> Functions introduced by:
> ...
> commit c20beece0854fa2fe2541b4a121d9b73188387f1
> Date:   Fri Nov 21 15:14:03 2025 -0500
> 
>     gdb/dwarf: store addr/offset/ref_addr sizes in dwarf2_per_cu
> ...
> so possibly a regression since that commit.

I build gdb at c20beece0854^ and ran the testsuite, and at gdb.threads I only have:
...
$ grep -a SUMMARY: gdb.log | sort | uniq -c
      1 SUMMARY: ThreadSanitizer: data race /home/vries/gdb/src/gdbsupport/print-utils.cc:34 in get_print_cell()
...
which should be fixed by:
...
commit 8543102f51fa6edb5b2c63081378965adfc900ca
Date:   Tue Jan 6 21:05:46 2026 +0100

    [gdbsupport] Fix get_print_cell use in threads    
...
Comment 3 Tom de Vries 2026-01-08 20:24:41 UTC
(In reply to Simon Marchi from comment #1)
> Does this reproduce on x86 Linux, or should I specifically look for an
> aarch64 machine?
> 

I don't know yet.

> Can you name one test in particular that fails, so I can start investigating
> there?

The first one that failed for me was gdb.ada/bp_reset.exp, but when running it individually, it didn't reproduce.
Comment 4 Simon Marchi 2026-01-08 20:37:22 UTC
If you could give the stack traces printed by TSan, it could be useful.

If each unit is self contained, I don't see how it could happen, because they are all indexed in isolation.  However, perhaps it's when one unit 'DW_AT_import's another, then I guess that two threads could try to set those properties on the same unit.
Comment 5 Tom de Vries 2026-01-08 20:40:29 UTC
Created attachment 16556 [details]
gdb.log.gz
Comment 6 Simon Marchi 2026-01-08 20:59:34 UTC
(In reply to Tom de Vries from comment #5)
> Created attachment 16556 [details]
> gdb.log.gz

Thanks, I think that's what I said earlier.  The write of thread 1 is:

WARNING: ThreadSanitizer: data race (pid=1535364)
  Write of size 1 at 0xfffed1813515 by thread T1:
    #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #4 cooked_indexer::scan_attributes(dwarf2_per_cu*, cutu_reader*, unsigned char const*, unsigned char const*, abbrev_info const*, char const**, char const**, enum_flags<cooked_index_flag_enum>*, sect_offset*, cooked_index_entry const**, parent_map::addr_type*, bool*, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:316 (gdb+0x88ed1c) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:539 (gdb+0x88fa50) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #6 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #7 cooked_index_worker_debug_info::process_unit(dwarf2_per_cu*, dwarf2_per_objfile*, cooked_index_worker_result*) /home/vries/gdb/src/gdb/dwarf2/read.c:3503 (gdb+0x948128) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)


The write of thread 2 is

  Previous write of size 1 at 0xfffed1813515 by thread T4:
    #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #4 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:431 (gdb+0x88f454) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #6 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:434 (gdb+0x88f4ac) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #7 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #8 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
    #9 cooked_index_worker_debug_info::process_unit(dwarf2_per_cu*, dwarf2_per_objfile*, cooked_index_worker_result*) /home/vries/gdb/src/gdb/dwarf2/read.c:3503 (gdb+0x948128) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)

Notice the "index_imported_unit" frames. This is used when there is a DW_TAG_imported_unit / DW_AT_import.
Comment 7 Simon Marchi 2026-01-08 21:21:16 UTC
An option would be to make them atomic.  Can you test this?

diff --git i/gdb/dwarf2/read.h w/gdb/dwarf2/read.h
index 4e89f0ed1fc8..c24399ff882d 100644
--- i/gdb/dwarf2/read.h
+++ w/gdb/dwarf2/read.h
@@ -229,9 +229,9 @@ struct dwarf2_per_cu
 private:
   /* Sizes for an address, an offset, and a section offset.  These fields are
      set by cutu_reader when the unit is read.  */
-  std::uint8_t m_addr_size = 0;
-  std::uint8_t m_offset_size = 0;
-  std::uint8_t m_ref_addr_size = 0;
+  std::atomic<std::uint8_t> m_addr_size = 0;
+  std::atomic<std::uint8_t> m_offset_size = 0;
+  std::atomic<std::uint8_t> m_ref_addr_size = 0;
 
 public:
   /* Our index in the unshared "symtabs" vector.  */

Even if multiple cutu_readers write these values, they should all write the same value.
Comment 8 Tom de Vries 2026-01-09 13:22:44 UTC
(In reply to Simon Marchi from comment #7)
> An option would be to make them atomic.  Can you test this?
> 
> diff --git i/gdb/dwarf2/read.h w/gdb/dwarf2/read.h
> index 4e89f0ed1fc8..c24399ff882d 100644
> --- i/gdb/dwarf2/read.h
> +++ w/gdb/dwarf2/read.h
> @@ -229,9 +229,9 @@ struct dwarf2_per_cu
>  private:
>    /* Sizes for an address, an offset, and a section offset.  These fields
> are
>       set by cutu_reader when the unit is read.  */
> -  std::uint8_t m_addr_size = 0;
> -  std::uint8_t m_offset_size = 0;
> -  std::uint8_t m_ref_addr_size = 0;
> +  std::atomic<std::uint8_t> m_addr_size = 0;
> +  std::atomic<std::uint8_t> m_offset_size = 0;
> +  std::atomic<std::uint8_t> m_ref_addr_size = 0;
>  
>  public:
>    /* Our index in the unshared "symtabs" vector.  */
> 

Yes, that works.

> Even if multiple cutu_readers write these values, they should all write the
> same value.

FWIW, my preference is to check this sort assumption if it's cheap to do so, and I'm guessing it is cheap because it's a per-CU thingy.  See f.i. unit_type/set_unit_type.
Comment 9 Tom de Vries 2026-01-10 16:02:32 UTC
Reproduces on gdb 17 branch.
Comment 11 Sourceware Commits 2026-01-12 18:38:04 UTC
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

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

commit 10dc500696f6625b3dcc70560e7762c9a9b01391
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Sat Jan 10 22:40:30 2026 -0500

    gdb/dwarf: make dwarf2_per_cu size fields atomic
    
    Make m_addr_size, m_offset_size, and m_ref_addr_size use std::atomic.
    Multiple indexer threads may set these values concurrently, which
    currently causes a TSan failure:
    
         WARNING: ThreadSanitizer: data race (pid=1535364)
           Write of size 1 at 0xfffed1813515 by thread T1:
             #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #4 cooked_indexer::scan_attributes(dwarf2_per_cu*, cutu_reader*, unsigned char const*, unsigned char const*, abbrev_info const*, char const**, char const**, enum_flags<cooked_index_flag_enum>*, sect_offset*, cooked_index_entry const**, parent_map::addr_type*, bool*, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:316 (gdb+0x88ed1c) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:539 (gdb+0x88fa50) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #6 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             ...
    
          Previous write of size 1 at 0xfffed1813515 by thread T4:
            #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #4 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:431 (gdb+0x88f454) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #6 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:434 (gdb+0x88f4ac) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #7 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #8 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            ...
    
    It's fine for multiple threads to try to set these values concurrently.
    The only condition is that either the previous value was 0 (unset) or
    equals the new value being set.
    
    Change-Id: Ib13218707cefdf33a51b3246ba5773a7800463b9
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33775
    Reviewed-By: Tom de Vries <tdevries@suse.de>
Comment 12 Simon Marchi 2026-01-12 18:41:57 UTC
Fixed, but I would propose pushing this to GDB 17 as well.
Comment 13 Tom de Vries 2026-01-13 10:14:06 UTC
(In reply to Simon Marchi from comment #12)
> Fixed, but I would propose pushing this to GDB 17 as well.

Agreed (I already set the target milestone to 17.2).
Comment 14 Sourceware Commits 2026-01-13 17:29:24 UTC
The gdb-17-branch branch has been updated by Simon Marchi <simark@sourceware.org>:

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

commit 32adc7212e4b32effdb7768250e08050a2f5532c
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Sat Jan 10 22:40:30 2026 -0500

    gdb/dwarf: make dwarf2_per_cu size fields atomic
    
    Make m_addr_size, m_offset_size, and m_ref_addr_size use std::atomic.
    Multiple indexer threads may set these values concurrently, which
    currently causes a TSan failure:
    
         WARNING: ThreadSanitizer: data race (pid=1535364)
           Write of size 1 at 0xfffed1813515 by thread T1:
             #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #4 cooked_indexer::scan_attributes(dwarf2_per_cu*, cutu_reader*, unsigned char const*, unsigned char const*, abbrev_info const*, char const**, char const**, enum_flags<cooked_index_flag_enum>*, sect_offset*, cooked_index_entry const**, parent_map::addr_type*, bool*, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:316 (gdb+0x88ed1c) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:539 (gdb+0x88fa50) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             #6 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
             ...
    
          Previous write of size 1 at 0xfffed1813515 by thread T4:
            #0 dwarf2_per_cu::set_addr_size(unsigned char) /home/vries/gdb/src/gdb/dwarf2/read.h:291 (gdb+0x98af68) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #1 cutu_reader::cutu_reader(dwarf2_per_cu&, dwarf2_per_objfile&, abbrev_table const*, dwarf2_cu*, bool, language, abbrev_table_cache const*) /home/vries/gdb/src/gdb/dwarf2/read.c:3114 (gdb+0x9472b4) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #2 std::__detail::_MakeUniq<cutu_reader>::__single_object std::make_unique<cutu_reader, dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr), decltype(nullptr), bool, language, abbrev_table_cache const*>(dwarf2_per_cu&, dwarf2_per_objfile&, decltype(nullptr)&&, decltype(nullptr)&&, bool&&, language&&, abbrev_table_cache const*&&) /usr/include/c++/15/bits/unique_ptr.h:1084 (gdb+0x891f98) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #3 cooked_indexer::ensure_cu_exists(cutu_reader*, section_and_offset const&, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:118 (gdb+0x88e1e8) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #4 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:431 (gdb+0x88f454) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #5 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #6 cooked_indexer::index_imported_unit(cutu_reader*, unsigned char const*, abbrev_info const*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:434 (gdb+0x88f4ac) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #7 cooked_indexer::index_dies(cutu_reader*, unsigned char const*, std::variant<cooked_index_entry const*, parent_map::addr_type>, bool) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:498 (gdb+0x88f770) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            #8 cooked_indexer::make_index(cutu_reader*) /home/vries/gdb/src/gdb/dwarf2/cooked-indexer.c:718 (gdb+0x890430) (BuildId: cce1d3c72972f5759cd1746e1a001e90d7498301)
            ...
    
    It's fine for multiple threads to try to set these values concurrently.
    The only condition is that either the previous value was 0 (unset) or
    equals the new value being set.
    
    Change-Id: Ib13218707cefdf33a51b3246ba5773a7800463b9
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33775
    Reviewed-By: Tom de Vries <tdevries@suse.de>
    (cherry picked from commit 10dc500696f6625b3dcc70560e7762c9a9b01391)
Comment 15 Tom de Vries 2026-01-14 21:37:53 UTC
Fixed.