aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2022-07-15 17:10:20 +0200
committerTom de Vries <tdevries@suse.de>2022-07-21 15:06:40 +0200
commitb0a46c96e426d48f8923091817701e3491dac20b (patch)
tree1131d5420882abc87fe10c5f96ee5bfe36accff6
parent19947698dedfb490ec4abde00fe8b659a1e6949f (diff)
downloadgdb-b0a46c96e426d48f8923091817701e3491dac20b.zip
gdb-b0a46c96e426d48f8923091817701e3491dac20b.tar.gz
gdb-b0a46c96e426d48f8923091817701e3491dac20b.tar.bz2
[gdb/symtab] Fix data race in get_die_type_at_offset
Data race between: ... ================== WARNING: ThreadSanitizer: data race (pid=28142) Read of size 4 at 0x7b1c0004b978 by thread T2: #0 htab_find_with_hash libiberty/hashtab.c:591 (gdb+0x1c5a254) #1 htab_find libiberty/hashtab.c:621 (gdb+0x1c5a44d) #2 get_die_type_at_offset gdb/dwarf2/read.c:23877 (gdb+0x872004) #3 get_die_type gdb/dwarf2/read.c:23890 (gdb+0x8720d0) #4 read_type_die gdb/dwarf2/read.c:21460 (gdb+0x8698e4) #5 process_die gdb/dwarf2/read.c:8674 (gdb+0x839f6e) #6 read_file_scope gdb/dwarf2/read.c:9610 (gdb+0x83ca5d) #7 process_die gdb/dwarf2/read.c:8614 (gdb+0x839e1f) #8 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x83945e) #9 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x83597d) ... and: ... Previous write of size 4 at 0x7b1c0004b978 by thread T1: #0 htab_find_with_hash libiberty/hashtab.c:591 (gdb+0x1c5a26e) #1 htab_find libiberty/hashtab.c:621 (gdb+0x1c5a44d) #2 get_die_type_at_offset gdb/dwarf2/read.c:23877 (gdb+0x872004) #3 get_die_type gdb/dwarf2/read.c:23890 (gdb+0x8720d0) #4 process_structure_scope gdb/dwarf2/read.c:14845 (gdb+0x851c12) #5 process_die gdb/dwarf2/read.c:8643 (gdb+0x839f24) #6 read_file_scope gdb/dwarf2/read.c:9610 (gdb+0x83ca5d) #7 process_die gdb/dwarf2/read.c:8614 (gdb+0x839e1f) #8 process_full_comp_unit gdb/dwarf2/read.c:8383 (gdb+0x83945e) #9 process_queue_item gdb/dwarf2/read.c:7592 (gdb+0x83597d) ... Fix by using lock, also in set_die_type.
-rw-r--r--gdb/dwarf2/read.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 895bb39..11ba01c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23773,6 +23773,10 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
&& ofs_lhs->sect_off == ofs_rhs->sect_off);
}
+#if CXX_STD_THREAD
+ static std::mutex die_type_hash_lock;
+#endif
+
/* Set the type associated with DIE to TYPE. Save it in CU's hash
table if necessary. For convenience, return TYPE.
@@ -23853,25 +23857,30 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
}
- if (per_objfile->die_type_hash == NULL)
- per_objfile->die_type_hash
- = htab_up (htab_create_alloc (127,
- per_cu_offset_and_type_hash,
- per_cu_offset_and_type_eq,
- NULL, xcalloc, xfree));
-
- ofs.per_cu = cu->per_cu;
- ofs.sect_off = die->sect_off;
- ofs.type = type;
- slot = (struct dwarf2_per_cu_offset_and_type **)
- htab_find_slot (per_objfile->die_type_hash.get (), &ofs, INSERT);
- if (*slot)
- complaint (_("A problem internal to GDB: DIE %s has type already set"),
- sect_offset_str (die->sect_off));
- *slot = XOBNEW (objfile->objfile_obstack (),
- struct dwarf2_per_cu_offset_and_type);
- **slot = ofs;
- return type;
+ {
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (die_type_hash_lock);
+#endif
+ if (per_objfile->die_type_hash == NULL)
+ per_objfile->die_type_hash
+ = htab_up (htab_create_alloc (127,
+ per_cu_offset_and_type_hash,
+ per_cu_offset_and_type_eq,
+ NULL, xcalloc, xfree));
+
+ ofs.per_cu = cu->per_cu;
+ ofs.sect_off = die->sect_off;
+ ofs.type = type;
+ slot = (struct dwarf2_per_cu_offset_and_type **)
+ htab_find_slot (per_objfile->die_type_hash.get (), &ofs, INSERT);
+ if (*slot)
+ complaint (_("A problem internal to GDB: DIE %s has type already set"),
+ sect_offset_str (die->sect_off));
+ *slot = XOBNEW (objfile->objfile_obstack (),
+ struct dwarf2_per_cu_offset_and_type);
+ **slot = ofs;
+ return type;
+ }
}
/* Look up the type for the die at SECT_OFF in PER_CU in die_type_hash,
@@ -23882,6 +23891,10 @@ get_die_type_at_offset (sect_offset sect_off,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile)
{
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (die_type_hash_lock);
+#endif
+
struct dwarf2_per_cu_offset_and_type *slot, ofs;
if (per_objfile->die_type_hash == NULL)