Hi Aaron,

On Fri, 2026-10-30 at 12:08 -0400, Aaron Merey wrote:
> dwarf_formref_die acquires attr->cu->dbg->dwarf_lock before interning a
> CU.  After acquiring there is a missing check for whether another thread
> interned the CU while the current thread was waiting for the lock.  Add
> this check.
> 
> Signed-off-by: Aaron Merey <[email protected]>
> ---
>  libdw/dwarf_formref_die.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
> index 1bedf5e9..15aea2f6 100644
> --- a/libdw/dwarf_formref_die.c
> +++ b/libdw/dwarf_formref_die.c
> @@ -95,7 +95,9 @@ dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result)
>         do
>           {
>             mutex_lock (attr->cu->dbg->dwarf_lock);
> -           cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types);
> +           cu = Dwarf_Sig8_Hash_find (&attr->cu->dbg->sig8_hash, sig);
> +           if (cu == NULL)
> +             cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types);
>             mutex_unlock (attr->cu->dbg->dwarf_lock);
>  
>             if (cu == NULL)

OK, so this is for resolving DW_FORM_ref_sig8. Which is first done
through Dwarf_Sig8_Hash_find. If that returns NULL it tries to find it
in either the debug_info or debug_types with __libdw_intern_next_unit.
For which it needs the dwarf_lock. But some other thread might have
raced and called __libdw_intern_next_unit already, which might have
found the signature and called Dwarf_Sig8_Hash_insert. So we now first
recheck with Dwarf_Sig8_Hash_find first.

Looks correct.

Thanks,

Mark

Reply via email to