Hi Aaron, On Wed, Sep 30, 2026 at 03:06:47PM -0400, Aaron Merey wrote: > locs_tree is modified by three calls to eu_tsearch_nolock, each of which > occurs when intern_lock mutex is held. All calls to eu_tfind* on > locs_tree occur when intern_lock is held except one, resulting in a data > race. > > Fix this by changing this eu_tfind to eu_tfind_nolock and acquiring > intern_lock before it is called.
This looks correct. All tsearch/tfind calls on locs_tree are in dwarf_getlocation.c. One tsearch in dwarf_getlocation_implicit_value without the cu intern_lock held. One tfind/tsearch pair in is_constant_offset with the intern_lock held. > Signed-off-by: Aaron Merey <[email protected]> > --- > libdw/dwarf_getlocation.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c > index 6d7296f8..89f09874 100644 > --- a/libdw/dwarf_getlocation.c > +++ b/libdw/dwarf_getlocation.c > @@ -166,17 +166,22 @@ dwarf_getlocation_implicit_value (Dwarf_Attribute > *attr, const Dwarf_Op *op, > if (attr == NULL) > return -1; > > + mutex_lock (attr->cu->intern_lock); > + > struct loc_block_s fake = { .addr = (void *) op }; > - struct loc_block_s **found = eu_tfind (&fake, &attr->cu->locs_tree, > - loc_compare); > + struct loc_block_s **found = eu_tfind_nolock (&fake, &attr->cu->locs_tree, > + loc_compare); > if (unlikely (found == NULL)) > { > + mutex_unlock (attr->cu->intern_lock); > __libdw_seterrno (DWARF_E_NO_BLOCK); > return -1; > } > > return_block->length = (*found)->length; > return_block->data = (*found)->data; > + > + mutex_unlock (attr->cu->intern_lock); > return 0; > } OK. Thanks, Mark
