[PATCH 3/9 v3] libdwP.h: Add locking to str_offsets_base_off

Aaron Merey amerey@redhat.com
Thu Feb 20 04:36:38 GMT 2025


	* libdw/dwarf_end.c (cu_free): Free str_off_base_lock.
	* libdw/libdwP.h (struct Dwarf_CU): Add str_off_base_lock member.
	(str_offsets_base_off): Add locking.
	* libdw/libdw_findcu.c (__libdw_intern_next_unit): Initialize
	str_off_base_lock.

Signed-off-by: Aaron Merey <amerey@redhat.com>

---
v3 changes:
This patch replaces v2 04/10.  04/10 added a lock to dwarf_offdie that
was unnecessary but happened to prevent the reporting of a race condition
in str_offsets_base_off.  This patch addresses the source of the race
condition.

 libdw/dwarf_end.c    |  1 +
 libdw/libdwP.h       | 20 ++++++++++++++++++--
 libdw/libdw_findcu.c |  1 +
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 92389c07..d8830823 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -70,6 +70,7 @@ cu_free (void *arg)
       Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
       rwlock_fini (p->abbrev_lock);
       rwlock_fini (p->split_lock);
+      mutex_fini (p->str_off_base_lock);
 
       /* Free split dwarf one way (from skeleton to split).  */
       if (p->unit_type == DW_UT_skeleton
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index d121914d..27e968ae 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -461,6 +461,10 @@ struct Dwarf_CU
      Covers __libdw_find_split_unit.  */
   rwlock_define(, split_lock);
 
+  /* Synchronize access to the str_off_base of this Dwarf_CU.
+     Covers __libdw_str_offsets_base_off.  */
+  mutex_define(, str_off_base_lock);
+
   /* Memory boundaries of this CU.  */
   void *startp;
   void *endp;
@@ -1202,6 +1206,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
   Dwarf_Off off = 0;
   if (cu != NULL)
     {
+      mutex_lock (cu->str_off_base_lock);
       if (cu->str_off_base == (Dwarf_Off) -1)
 	{
 	  Dwarf_Off dwp_offset;
@@ -1216,6 +1221,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 	      if (dwarf_formudata (&attr, &base) == 0)
 		{
 		  cu->str_off_base = off + base;
+		  mutex_unlock (cu->str_off_base_lock);
 		  return cu->str_off_base;
 		}
 	    }
@@ -1223,6 +1229,7 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 	  if (cu->version < 5)
 	    {
 	      cu->str_off_base = off;
+	      mutex_unlock (cu->str_off_base_lock);
 	      return cu->str_off_base;
 	    }
 
@@ -1230,7 +1237,12 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 	    dbg = cu->dbg;
 	}
       else
-	return cu->str_off_base;
+	{
+	  mutex_unlock (cu->str_off_base_lock);
+	  return cu->str_off_base;
+	}
+
+      mutex_unlock (cu->str_off_base_lock);
     }
 
   /* No str_offsets_base attribute, we have to assume "zero".
@@ -1280,7 +1292,11 @@ str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
 
  no_header:
   if (cu != NULL)
-    cu->str_off_base = off;
+    {
+      mutex_lock (cu->str_off_base_lock);
+      cu->str_off_base = off;
+      mutex_unlock (cu->str_off_base_lock);
+    }
 
   return off;
 }
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 613f61c8..1e96110b 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -179,6 +179,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   eu_search_tree_init (&newp->locs_tree);
   rwlock_init (newp->abbrev_lock);
   rwlock_init (newp->split_lock);
+  mutex_init (newp->str_off_base_lock);
 
   /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
   if (debug_types)
-- 
2.48.1



More information about the Elfutils-devel mailing list