diff options
author | Tom de Vries <tdevries@suse.de> | 2022-07-15 13:08:22 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2022-07-21 15:06:40 +0200 |
commit | 3164537f2563aaf79630f0ec690859e9f9333618 (patch) | |
tree | efc6b84f9d9a7c4fd0ca30755d94c68b43459545 | |
parent | fa25a1fa4aea226494e191455928142dfa1ab512 (diff) | |
download | gdb-3164537f2563aaf79630f0ec690859e9f9333618.zip gdb-3164537f2563aaf79630f0ec690859e9f9333618.tar.gz gdb-3164537f2563aaf79630f0ec690859e9f9333618.tar.bz2 |
[gdb/symtab] Fix data race on per_objfile->sym_cu
We have both:
...
gdb/dwarf2/read.c:9590: internal-error: read_file_scope: \
Assertion `per_objfile->sym_cu == nullptr' failed.
...
and a data race between:
...
#0 read_file_scope gdb/dwarf2/read.c:9590 (gdb+0x83c8ca)
#1 process_die gdb/dwarf2/read.c:8614 (gdb+0x839dc1)
#2 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x839400)
#3 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x83591f)
...
and:
...
Previous write of size 8 at 0x7b4400096f20 by thread T1:
#0 scoped_restore_tmpl<dwarf2_cu*>::scoped_restore_tmpl<dwarf2_cu*>
(dwarf2_cu**, dwarf2_cu*) gdbsupport/scoped_restore.h:73 (gdb+0x89d23e)
#1 scoped_restore_tmpl<dwarf2_cu*> make_scoped_restore<dwarf2_cu*,
dwarf2_cu*>(dwarf2_cu**, dwarf2_cu*) gdbsupport/scoped_restore.h:115
(gdb+0x890543)
#2 read_file_scope gdb/dwarf2/read.c:9592 (gdb+0x83c924)
#3 process_die gdb/dwarf2/read.c:8614 (gdb+0x839dc1)
#4 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x839400)
#5 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x83591f)
...
Fix again by using poor man's thread local.
-rw-r--r-- | gdb/dwarf2/cu.c | 5 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 7 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 9 |
3 files changed, 14 insertions, 7 deletions
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c index d40dd09..37166c0 100644 --- a/gdb/dwarf2/cu.c +++ b/gdb/dwarf2/cu.c @@ -21,6 +21,7 @@ #include "dwarf2/cu.h" #include "dwarf2/read.h" #include "objfiles.h" +#include "gdbsupport/thread-pool.h" /* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */ @@ -161,8 +162,8 @@ dwarf2_cu::get_builder () if (m_builder != nullptr) return m_builder.get (); - if (per_objfile->sym_cu != nullptr) - return per_objfile->sym_cu->m_builder.get (); + if (per_objfile->sym_cu[gdb::thread_pool::id()] != nullptr) + return per_objfile->sym_cu[gdb::thread_pool::id()]->m_builder.get (); gdb_assert_not_reached (""); } diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 82fdf4c..895bb39 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -9603,9 +9603,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile), lowpc); - gdb_assert (per_objfile->sym_cu == nullptr); + gdb_assert (per_objfile->sym_cu[gdb::thread_pool::id()] == nullptr); scoped_restore restore_sym_cu - = make_scoped_restore (&per_objfile->sym_cu, cu); + = make_scoped_restore (&per_objfile->sym_cu[gdb::thread_pool::id()], cu); /* Decode line number information if present. We do this before processing child DIEs, so that the line header table is available @@ -9627,7 +9627,8 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) child_die = child_die->sibling; } } - per_objfile->sym_cu = nullptr; + + per_objfile->sym_cu[gdb::thread_pool::id()] = nullptr; /* Decode macro information, if present. Dwarf 2 macro information refers to information in the line number info statement program diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 3a3ff6c..d357e50 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -587,7 +587,12 @@ struct dwarf2_per_objfile { dwarf2_per_objfile (struct objfile *objfile, dwarf2_per_bfd *per_bfd) : objfile (objfile), per_bfd (per_bfd) - {} + { + for (int i = 0; + i < gdb::thread_pool::g_thread_pool->thread_count () + 1; + ++i) + sym_cu.push_back (nullptr); + } ~dwarf2_per_objfile (); @@ -655,7 +660,7 @@ struct dwarf2_per_objfile htab_up line_header_hash; /* The CU containing the m_builder in scope. */ - dwarf2_cu *sym_cu = nullptr; + std::vector<dwarf2_cu *> sym_cu; /* CUs that are queued to be read. */ gdb::optional<std::deque<dwarf2_queue_item>> queue; |