From: Tom de Vries Date: Fri, 15 Jul 2022 14:11:47 +0000 (+0200) Subject: [gdb/symtab] Fix race condition in objfile_obstack X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=fa25a1fa4aea226494e191455928142dfa1ab512;p=thirdparty%2Fbinutils-gdb.git [gdb/symtab] Fix race condition in objfile_obstack Race condition between: ... Read of size 8 at 0x7b4400096f60 by thread T1: #0 obstack_zalloc 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 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. --- diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 76d063c86f8..a35aafb876e 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -39,6 +39,7 @@ #include "jit.h" #include "quick-symbol.h" #include +#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 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