diff options
author | Heather McIntyre <[email protected]> | 2024-08-20 16:42:03 -0400 |
---|---|---|
committer | Aaron Merey <[email protected]> | 2024-08-20 20:19:13 -0400 |
commit | 2630bce7476b70e2abb42da0aabaa63006b290cf (patch) | |
tree | f4af2528e8d22adf05b77289d311884139b63d64 | |
parent | 28b74a1bf73b86ec461c20e17c405d8b64bdba77 (diff) |
libdw: Make libdw_find_split_unit thread-safe
* libdw/dwarf_end.c (cu_free): Free split_lock.
* libdw/dwarf_formref_die.c (dwarf_formref_die): Add locking
around call to __libdw_intern_next_unit.
* libdw/libdwP.h (struct Dwarf_CU): Add split_lock.
* libdw/libdw_find_split_unit.c (__libdw_find_split_unit):
Add locking.
* libdw/libdw_findcu.c (__libdw_intern_next_unit): Init
split_lock.
Signed-off-by: Heather S. McIntyre <[email protected]>
Signed-off-by: Aaron Merey <[email protected]>
Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r-- | libdw/dwarf_end.c | 1 | ||||
-rw-r--r-- | libdw/dwarf_formref_die.c | 3 | ||||
-rw-r--r-- | libdw/libdwP.h | 3 | ||||
-rw-r--r-- | libdw/libdw_find_split_unit.c | 15 | ||||
-rw-r--r-- | libdw/libdw_findcu.c | 1 |
5 files changed, 21 insertions, 2 deletions
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index 487d6ce7..ee3ed74e 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -69,6 +69,7 @@ cu_free (void *arg) { Dwarf_Abbrev_Hash_free (&p->abbrev_hash); rwlock_fini (p->abbrev_lock); + rwlock_fini (p->split_lock); /* Free split dwarf one way (from skeleton to split). */ if (p->unit_type == DW_UT_skeleton diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c index 48ba8194..69d1bf1c 100644 --- a/libdw/dwarf_formref_die.c +++ b/libdw/dwarf_formref_die.c @@ -92,7 +92,10 @@ dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result) bool scan_debug_types = false; do { + rwlock_wrlock(attr->cu->dbg->dwarf_lock); cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types); + rwlock_unlock(attr->cu->dbg->dwarf_lock); + if (cu == NULL) { if (scan_debug_types == false) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 8ba87463..d6bab606 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -455,6 +455,9 @@ struct Dwarf_CU refers to this Dwarf_CU. */ rwlock_define(, abbrev_lock); + /* Synchronize access to the split member of this Dwarf_CU. */ + rwlock_define(, split_lock); + /* Memory boundaries of this CU. */ void *startp; void *endp; diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c index 4005793b..f4f34c5d 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -150,9 +150,18 @@ Dwarf_CU * internal_function __libdw_find_split_unit (Dwarf_CU *cu) { + /* Set result before releasing the lock. */ + Dwarf_CU *result; + + rwlock_wrlock(cu->split_lock); + /* Only try once. */ if (cu->split != (Dwarf_CU *) -1) - return cu->split; + { + result = cu->split; + rwlock_unlock(cu->split_lock); + return result; + } /* We need a skeleton unit with a comp_dir and [GNU_]dwo_name attributes. The split unit will be the first in the dwo file and should have the @@ -207,5 +216,7 @@ __libdw_find_split_unit (Dwarf_CU *cu) if (cu->split == (Dwarf_CU *) -1) cu->split = NULL; - return cu->split; + result = cu->split; + rwlock_unlock(cu->split_lock); + return result; } diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 0f46d777..c74e895e 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -178,6 +178,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->endp = data->d_buf + newp->end; eu_search_tree_init (&newp->locs_tree); rwlock_init (newp->abbrev_lock); + rwlock_init (newp->split_lock); /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types) |