]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/symtab] Fix data race in lookup_die_type
authorTom de Vries <tdevries@suse.de>
Fri, 15 Jul 2022 17:17:47 +0000 (19:17 +0200)
committerTom de Vries <tdevries@suse.de>
Thu, 21 Jul 2022 13:06:40 +0000 (15:06 +0200)
Data race between:
...
  Write of size 8 at 0x7b8009b483f8 by main thread:
    #0 read_tag_pointer_type gdb/dwarf2/read.c:16171 (gdb+0x8580b3)
    #1 read_type_die_1 gdb/dwarf2/read.c:21508 (gdb+0x869b69)
    #2 read_type_die gdb/dwarf2/read.c:21474 (gdb+0x869a53)
    #3 lookup_die_type gdb/dwarf2/read.c:21446 (gdb+0x8699ad)
    #4 die_type gdb/dwarf2/read.c:21300 (gdb+0x869286)
    #5 dwarf2_add_field gdb/dwarf2/read.c:13535 (gdb+0x84aabd)
    #6 handle_struct_member_die gdb/dwarf2/read.c:14803 (gdb+0x851ad2)
    #7 process_structure_scope gdb/dwarf2/read.c:14865 (gdb+0x851e70)
    #8 process_die gdb/dwarf2/read.c:8649 (gdb+0x83a048)
    #9 read_file_scope gdb/dwarf2/read.c:9616 (gdb+0x83cb81)
    #10 process_die gdb/dwarf2/read.c:8620 (gdb+0x839f43)
    #11 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x839509)
    #12 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x8359f5)
...
and:
...
  Previous read of size 8 at 0x7b8009b483f8 by thread T3:
    #0 dwarf2_cu::addr_type() const gdb/dwarf2/cu.c:99 (gdb+0x7b8d42)
    #1 set_die_type gdb/dwarf2/read.c:23850 (gdb+0x871e4e)
    #2 read_subroutine_type gdb/dwarf2/read.c:16539 (gdb+0x8591c8)
    #3 read_type_die_1 gdb/dwarf2/read.c:21499 (gdb+0x869b15)
    #4 read_type_die gdb/dwarf2/read.c:21474 (gdb+0x869a53)
    #5 lookup_die_type gdb/dwarf2/read.c:21446 (gdb+0x8699ad)
    #6 die_type gdb/dwarf2/read.c:21300 (gdb+0x869286)
    #7 read_tag_pointer_type gdb/dwarf2/read.c:16114 (gdb+0x857d91)
    #8 read_type_die_1 gdb/dwarf2/read.c:21508 (gdb+0x869b69)
    #9 read_type_die gdb/dwarf2/read.c:21474 (gdb+0x869a53)
    #10 lookup_die_type gdb/dwarf2/read.c:21446 (gdb+0x8699ad)
    #11 die_type gdb/dwarf2/read.c:21300 (gdb+0x869286)
    #12 new_symbol gdb/dwarf2/read.c:20742 (gdb+0x8671fe)
    #13 read_variable gdb/dwarf2/read.c:12623 (gdb+0x848823)
    #14 process_die gdb/dwarf2/read.c:8716 (gdb+0x83a28c)
    #15 read_file_scope gdb/dwarf2/read.c:9616 (gdb+0x83cb81)
    #16 process_die gdb/dwarf2/read.c:8620 (gdb+0x839f43)
    #17 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x839509)
    #18 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x8359f5)
...

Fix this by adding a lock in lookup_die_type.

Also in read_type_die and set_die_type.

Hmm, we already use another lock in set_die_type.  This needs more work.

gdb/dwarf2/read.c

index d0452ab8ba29d2cf78b1c9cfeb46a6f7dbc2b72b..c0d65218172543341b8541b9e31fad310697ecb4 100644 (file)
@@ -21396,6 +21396,10 @@ build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
   return init_type (objfile, TYPE_CODE_ERROR, 0, saved);
 }
 
+#if CXX_STD_THREAD
+static std::recursive_mutex lookup_die_type_lock;
+#endif
+
 /* Look up the type of DIE in CU using its type attribute ATTR.
    ATTR must be one of: DW_AT_type, DW_AT_GNAT_descriptive_type,
    DW_AT_containing_type.
@@ -21405,6 +21409,9 @@ static struct type *
 lookup_die_type (struct die_info *die, const struct attribute *attr,
                 struct dwarf2_cu *cu)
 {
+#if CXX_STD_THREAD
+  std::lock_guard<std::recursive_mutex> guard (lookup_die_type_lock);
+#endif
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct type *this_type;
@@ -21481,6 +21488,9 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
 static struct type *
 read_type_die (struct die_info *die, struct dwarf2_cu *cu)
 {
+#if CXX_STD_THREAD
+  std::lock_guard<std::recursive_mutex> guard (lookup_die_type_lock);
+#endif
   struct type *this_type;
 
   this_type = get_die_type (die, cu);
@@ -23809,6 +23819,9 @@ static struct type *
 set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
              bool skip_data_location)
 {
+#if CXX_STD_THREAD
+  std::lock_guard<std::recursive_mutex> guard (lookup_die_type_lock);
+#endif
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_offset_and_type **slot, ofs;
   struct objfile *objfile = per_objfile->objfile;
@@ -23869,7 +23882,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
   {
 #if CXX_STD_THREAD
-    std::lock_guard<std::mutex> guard (die_type_hash_lock);
+    std::lock_guard<std::mutex> guard2 (die_type_hash_lock);
 #endif
     if (per_objfile->die_type_hash == NULL)
       per_objfile->die_type_hash