]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Fix data race on per_objfile->sym_cu
authorTom de Vries <tdevries@suse.de>
Fri, 15 Jul 2022 11:08:22 +0000 (13:08 +0200)
committerTom de Vries <tdevries@suse.de>
Thu, 21 Jul 2022 13:06:40 +0000 (15:06 +0200)
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.

gdb/dwarf2/cu.c
gdb/dwarf2/read.c
gdb/dwarf2/read.h

index d40dd094b093771ec17bd2cec674e73b07022726..37166c00afa92652f4624402f0cf3211f78c7be2 100644 (file)
@@ -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 ("");
 }
index 82fdf4cd5c3ef4b9bf34cf885b9724634a9771a4..895bb3938e274726dd9ee7dfff2c99c1bc000fa5 100644 (file)
@@ -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
index 3a3ff6cce94086e4af403d61caf477cc2c377ff6..d357e50252672f9772e0907b9f0fef94394e089c 100644 (file)
@@ -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;