Hi Aaron,

On Sun, 2025-03-16 at 21:51 -0400, Aaron Merey wrote:
>       * libdw/dwarf_begin_elf.c (dwarf_begin_elf): Init macro_lock.
>       * libdw/dwarf_end.c (cu_free): Free src_lock.
>       (dwarf_end): Free macro_lock.
>       * libdw/dwarf_getsrcfiles.c (dwarf_getsrcfiles): Use src_lock.
>       * libdw/dwarf_getsrclines.c (dwarf_getsrclines): Ditto.
>       * libdw/dwarf_macro_getsrclines.c (dwarf_macro_getsrclines): Use
>       macro_lock.
>       * libdw/libdwP.h (struct Dwarf): Define macro_lock.
>       (struct Dwarf_CU): Define src_lock.
>       * libdw/libdw_findcu.c (__libdw_intern_next_unit): Init src_lock.

Looks good. Just one comment about a comment below.

> Signed-off-by: Aaron Merey <ame...@redhat.com>
> ---
> v3: 
> https://patchwork.sourceware.org/project/elfutils/patch/20250220043644.2058519-3-ame...@redhat.com/
> 
> v4: Instead of using dwarf_lock, define a new lock for dwarf_getsrclines and
> dwarf_getsrcfiles as well as dwarf_macro_getsrcfiles.
> 
>  libdw/dwarf_begin_elf.c         |  1 +
>  libdw/dwarf_end.c               |  2 ++
>  libdw/dwarf_getsrcfiles.c       | 11 +++++++----
>  libdw/dwarf_getsrclines.c       | 25 +++++++++++++++++++------
>  libdw/dwarf_macro_getsrcfiles.c | 10 +++++++++-
>  libdw/libdwP.h                  | 10 ++++++++--
>  libdw/libdw_findcu.c            |  1 +
>  7 files changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
> index 8a3a939b..58a309e9 100644
> --- a/libdw/dwarf_begin_elf.c
> +++ b/libdw/dwarf_begin_elf.c
> @@ -580,6 +580,7 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
>        return NULL;
>      }
>    mutex_init (result->dwarf_lock);
> +  mutex_init (result->macro_lock);
>    eu_search_tree_init (&result->cu_tree);
>    eu_search_tree_init (&result->tu_tree);
>    eu_search_tree_init (&result->split_tree);
> diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
> index 92389c07..c12815e1 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->src_lock);
>  
>        /* Free split dwarf one way (from skeleton to split).  */
>        if (p->unit_type == DW_UT_skeleton
> @@ -130,6 +131,7 @@ dwarf_end (Dwarf *dwarf)
>          free (dwarf->mem_tails);
>        pthread_rwlock_destroy (&dwarf->mem_rwl);
>        mutex_fini (dwarf->dwarf_lock);
> +      mutex_fini (dwarf->macro_lock);
>  
>        /* Free the pubnames helper structure.  */
>        free (dwarf->pubnames_sets);
> diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
> index 24e4b7d2..9becd1d5 100644
> --- a/libdw/dwarf_getsrcfiles.c
> +++ b/libdw/dwarf_getsrcfiles.c
> @@ -47,9 +47,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, 
> size_t *nfiles)
>      }
>  
>    int res = -1;
> +  struct Dwarf_CU *const cu = cudie->cu;
> +  mutex_lock (cudie->cu->src_lock);
>  
>    /* Get the information if it is not already known.  */
> -  struct Dwarf_CU *const cu = cudie->cu;
>    if (cu->files == NULL)
>      {
>        /* For split units there might be a simple file table (without lines).
> @@ -96,7 +97,10 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, 
> size_t *nfiles)
>         Dwarf_Off debug_line_offset;
>         if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
>                              NULL, &debug_line_offset) == NULL)
> -         return -1;
> +         {
> +           mutex_unlock (cudie->cu->src_lock);
> +           return -1;
> +         }
>  
>         res = __libdw_getsrcfiles (cu->dbg, debug_line_offset,
>                                    __libdw_getcompdir (cudie),
> @@ -115,8 +119,7 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, 
> size_t *nfiles)
>       *nfiles = cu->files->nfiles;
>      }
>  
> -  // XXX Eventually: unlocking here.
> -
> +  mutex_unlock (cudie->cu->src_lock);
>    return res;
>  }
>  INTDEF (dwarf_getsrcfiles)
> diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
> index da78db67..be10cdee 100644
> --- a/libdw/dwarf_getsrclines.c
> +++ b/libdw/dwarf_getsrclines.c
> @@ -1442,8 +1442,10 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines 
> **lines, size_t *nlines)
>        return -1;
>      }
>  
> -  /* Get the information if it is not already known.  */
>    struct Dwarf_CU *const cu = cudie->cu;
> +  mutex_lock (cu->src_lock);
> +
> +  /* Get the information if it is not already known.  */
>    if (cu->lines == NULL)
>      {
>        /* For split units always pick the lines from the skeleton.  */
> @@ -1464,10 +1466,13 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines 
> **lines, size_t *nlines)
>                 *lines = cu->lines;
>                 *nlines = cu->lines->nlines;
>               }
> +
> +           mutex_unlock (cu->src_lock);
>             return res;
>           }
>  
>         __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
> +       mutex_unlock (cu->src_lock);
>         return -1;
>       }
>  
> @@ -1485,21 +1490,29 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines 
> **lines, size_t *nlines)
>        Dwarf_Off debug_line_offset;
>        if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
>                          NULL, &debug_line_offset) == NULL)
> -     return -1;
> +     {
> +       mutex_unlock (cu->src_lock);
> +       return -1;
> +     }
>  
>        if (__libdw_getsrclines (cu->dbg, debug_line_offset,
>                              __libdw_getcompdir (cudie),
>                              cu->address_size, &cu->lines, &cu->files) < 0)
> -     return -1;
> +     {
> +       mutex_unlock (cu->src_lock);
> +       return -1;
> +     }
>      }
>    else if (cu->lines == (void *) -1l)
> -    return -1;
> +    {
> +      mutex_unlock (cu->src_lock);
> +      return -1;
> +    }
>  
>    *lines = cu->lines;
>    *nlines = cu->lines->nlines;
>  
> -  // XXX Eventually: unlocking here.
> -
> +  mutex_unlock (cu->src_lock);
>    return 0;
>  }
>  INTDEF(dwarf_getsrclines)
> diff --git a/libdw/dwarf_macro_getsrcfiles.c b/libdw/dwarf_macro_getsrcfiles.c
> index 5e02935d..6ccbeadb 100644
> --- a/libdw/dwarf_macro_getsrcfiles.c
> +++ b/libdw/dwarf_macro_getsrcfiles.c
> @@ -41,6 +41,8 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
>  
>    /* macro is declared NN */
>    Dwarf_Macro_Op_Table *const table = macro->table;
> +
> +  mutex_lock (table->dbg->macro_lock);
>    if (table->files == NULL)
>      {
>        Dwarf_Off line_offset = table->line_offset;
> @@ -48,6 +50,7 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
>       {
>         *files = NULL;
>         *nfiles = 0;
> +       mutex_unlock (table->dbg->macro_lock);
>         return 0;
>       }
>  
> @@ -80,9 +83,14 @@ dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
>      }
>  
>    if (table->files == (void *) -1)
> -    return -1;
> +    {
> +      mutex_unlock (table->dbg->macro_lock);
> +      return -1;
> +    }
>  
>    *files = table->files;
>    *nfiles = table->files->nfiles;
> +
> +  mutex_unlock (table->dbg->macro_lock);
>    return 0;
>  }
> diff --git a/libdw/libdwP.h b/libdw/libdwP.h
> index d121914d..974d6a50 100644
> --- a/libdw/libdwP.h
> +++ b/libdw/libdwP.h
> @@ -265,11 +265,13 @@ struct Dwarf
>    pthread_rwlock_t mem_rwl;
>  
>    /* Recursive mutex intended for setting/getting alt_dwarf, next_tu_offset,
> -     and next_cu_offset.  Covers dwarf_getsrclines, dwarf_getsrcfiles and
> -     dwarf_macro_getsrcfiles.  Should also be held when calling
> +     and next_cu_offset.  Should be held when calling
>       __libdw_intern_next_unit.  */
>    mutex_define(, dwarf_lock);
>  
> +  /* Synchronize access to dwarf_macro_getsrcfiles.  */
> +  mutex_define(, macro_lock);
> +

Maybe say: /* Used inside dwarf_macro_getsrcfiles to guard access to
the Dwarf_Macro table struct.  */ ?

>    /* Internal memory handling.  This is basically a simplified thread-local
>       reimplementation of obstacks.  Unfortunately the standard obstack
>       implementation is not usable in libraries.  */
> @@ -461,6 +463,10 @@ struct Dwarf_CU
>       Covers __libdw_find_split_unit.  */
>    rwlock_define(, split_lock);
>  
> +  /* Synchronize access to the lines and files members.
> +     Covers dwarf_getsrclines and dwarf_getsrcfiles.  */
> +  mutex_define(, src_lock);
> +
>    /* Memory boundaries of this CU.  */
>    void *startp;
>    void *endp;
> diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
> index 613f61c8..f0243643 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->src_lock);
>  
>    /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
>    if (debug_types)

Reply via email to