[gdb/symtab] Fix data race in per_cu->length
authorTom de Vries <tdevries@suse.de>
Mon, 11 Jul 2022 09:36:54 +0000 (11:36 +0200)
committerTom de Vries <tdevries@suse.de>
Mon, 11 Jul 2022 09:36:54 +0000 (11:36 +0200)
commit53a7a7e17c5d21b7b182ddf6bd8bfc092af196f5
tree5f9c61268e942a84c0e5ca8b19fc17586a8c422f
parenta4ca6efe0589d0a030920a4686b692208c82a028
[gdb/symtab] Fix data race in per_cu->length

With gdb build with -fsanitize=thread and test-case
gdb.dwarf2/dw4-sig-types.exp and target board cc-with-dwz-m we run into a data
race between:
...
  Write of size 4 at 0x7b2800002268 by thread T4:^M
    #0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \
    abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6236 \
    (gdb+0x82f525)^M
...
and this read:
...
  Previous read of size 4 at 0x7b2800002268 by thread T1:^M
    #0 dwarf2_find_containing_comp_unit gdb/dwarf2/read.c:23444 \
    (gdb+0x86e22e)^M
...

In other words, between this write:
...
    this_cu->length = cu->header.get_length ();
...
and this read:
...
      && mid_cu->sect_off + mid_cu->length > sect_off))
...
of per_cu->length.

Fix this similar to the per_cu->dwarf_version case, by only setting it if
needed, and otherwise verifying that the same value is used.  [ Note that the
same code is already present in the other cutu_reader constructor. ]

Move this logic into into a member function set_length to make sure it's used
consistenly, and make the field private in order to enforce access through the
member functions, and rename it to m_length.

This exposes (running test-case gdb.dwarf2/fission-reread.exp) that in
fill_in_sig_entry_from_dwo_entry, the m_length field is overwritten.
For now, allow for that exception.

While we're at it, make sure that the length is set before read.

Tested on x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29344
gdb/dwarf2/index-write.c
gdb/dwarf2/read.c
gdb/dwarf2/read.h