]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Fix race condition in objfile_obstack
authorTom de Vries <tdevries@suse.de>
Fri, 15 Jul 2022 14:11:47 +0000 (16:11 +0200)
committerTom de Vries <tdevries@suse.de>
Thu, 21 Jul 2022 13:06:40 +0000 (15:06 +0200)
Race condition between:
...
  Read of size 8 at 0x7b4400096f60 by thread T1:
    #0 obstack_zalloc<compunit_symtab> gdbsupport/gdb_obstack.h:33
    #1 allocate_compunit_symtab(objfile*, char const*) gdb/symfile.c:2822
    #2 buildsym_compunit::buildsym_compunit(objfile*, char const*,
    char const*, language, unsigned long) gdb/buildsym.c:65
    #3 dwarf2_cu::start_compunit_symtab(char const*, char const*,
    unsigned long) gdb/dwarf2/cu.c:65
    #4 read_file_scope gdb/dwarf2/read.c:9587
    #5 process_die gdb/dwarf2/read.c:8614
    #6 process_full_comp_unit gdb/dwarf2/read.c:8383
    #7 process_queue_item gdb/dwarf2/read.c:7592
...
and:
...
  Previous write of size 8 at 0x7b4400096f60 by thread T2:
    #0 _obstack_newchunk libiberty/obstack.c:211
    #1 obstack_zalloc<compunit_symtab> gdbsupport/gdb_obstack.h:33
    #2 allocate_compunit_symtab(objfile*, char const*) gdb/symfile.c:2822
    #3 buildsym_compunit::buildsym_compunit(objfile*, char const*,
    char const*, language, unsigned long) gdb/buildsym.c:65
    #4 dwarf2_cu::start_compunit_symtab(char const*, char const*,
    unsigned long) gdb/dwarf2/cu.c:65
    #5 read_file_scope gdb/dwarf2/read.c:9587
    #6 process_die gdb/dwarf2/read.c:8614
    #7 process_full_comp_unit gdb/dwarf2/read.c:8383
    #8 process_queue_item gdb/dwarf2/read.c:7592
...

Fix by using poor man's thread_local.

gdb/objfiles.h

index 76d063c86f8614203551d906fe03b9e808d461d3..a35aafb876e60570205467ddce6a7ec243accc87 100644 (file)
@@ -39,6 +39,7 @@
 #include "jit.h"
 #include "quick-symbol.h"
 #include <forward_list>
+#include "gdbsupport/thread-pool.h"
 
 struct htab;
 struct objfile_data;
@@ -666,10 +667,23 @@ public:
   /* Obstack to hold objects that should be freed when we load a new symbol
      table from this object file.  */
 
-  struct obstack m_objfile_obstack {};
+  std::vector<struct obstack *> m_objfile_obstack;
   struct obstack *objfile_obstack ()
   {
-    return &m_objfile_obstack;
+    unsigned id = gdb::thread_pool::id ();
+    size_t count = gdb::thread_pool::g_thread_pool->thread_count () + 1;
+    if (m_objfile_obstack.empty ())
+      for (size_t i = 0; i < count; ++i)
+       {
+         struct obstack *p
+           = (struct obstack *)malloc (sizeof (struct obstack));
+         m_objfile_obstack.push_back (p);
+         if (i == 0)
+           /* Main thread initializes it.  */
+           continue;
+         obstack_init (m_objfile_obstack[i]);
+       }
+    return m_objfile_obstack[id];
   }
 
   /* Structure which keeps track of functions that manipulate objfile's