diff options
author | Tom de Vries <tdevries@suse.de> | 2022-07-15 17:10:20 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2022-07-21 15:06:40 +0200 |
commit | b0a46c96e426d48f8923091817701e3491dac20b (patch) | |
tree | 1131d5420882abc87fe10c5f96ee5bfe36accff6 | |
parent | 19947698dedfb490ec4abde00fe8b659a1e6949f (diff) | |
download | gdb-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.c | 51 |
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) |