On Thu, Apr 24, 2025 at 5:49 PM Serhei Makarov <ser...@serhei.io> wrote:
>
> Changes for v4:
>
> - Separate out libdwfl_stacktrace, as requested.
>
> Changes for v2:
>
> - Add locking for dwfltab.
>
> * * *
>
> New function that retrieves the Dwfl for a particular PID, or,
> if the Dwfl is absent, creates it via a provided callback
> and adds it to the table later, when the PID is confirmed
> via dwfl_attach_state.
>
> * libdwfl_stacktrace/libdwfl_stacktrace.h (dwflst_tracker_find_pid):
>   New function.
> * libdwfl_stacktrace/dwfl_process_tracker.c (dwflst_tracker_find_pid):
>   New function; find a Dwfl in the dwfltab or create one using the
>   provided callback.  The newly created Dwfl will be added to the
>   dwfltab automatically when its pid is confirmed by a call to
>   dwfl_attach_state.
> * libdw/libdw.map: Add dwflst_tracker_find_pid.
> ---
>  libdw/libdw.map                             |  1 +
>  libdwfl_stacktrace/dwflst_process_tracker.c | 26 +++++++++++++++++++++
>  libdwfl_stacktrace/libdwfl_stacktrace.h     | 11 +++++++++
>  3 files changed, 38 insertions(+)
>
> diff --git a/libdw/libdw.map b/libdw/libdw.map
> index 46d0878a..688e415c 100644
> --- a/libdw/libdw.map
> +++ b/libdw/libdw.map
> @@ -404,4 +404,5 @@ ELFUTILS_0.193_EXPERIMENTAL {
>      dwflst_tracker_cache_elf;
>      dwflst_module_gettracker;
>      dwflst_tracker_linux_proc_find_elf;
> +    dwflst_tracker_find_pid;
>  };
> diff --git a/libdwfl_stacktrace/dwflst_process_tracker.c 
> b/libdwfl_stacktrace/dwflst_process_tracker.c
> index f72b72b0..fc019b23 100644
> --- a/libdwfl_stacktrace/dwflst_process_tracker.c
> +++ b/libdwfl_stacktrace/dwflst_process_tracker.c
> @@ -67,6 +67,32 @@ Dwfl *dwflst_tracker_dwfl_begin (Dwflst_Process_Tracker 
> *tracker)
>    return dwfl;
>  }
>
> +Dwfl *dwflst_tracker_find_pid (Dwflst_Process_Tracker *tracker,
> +                              pid_t pid,
> +                              Dwfl *(*callback) (Dwflst_Process_Tracker *,
> +                                                 pid_t, void *),
> +                              void *arg)
> +{
> +  Dwfl *dwfl = NULL;
> +
> +  rwlock_rdlock (tracker->dwfltab_lock);
> +  dwflst_tracker_dwfl_info *ent
> +    = dwflst_tracker_dwfltab_find(&tracker->dwfltab, pid);
> +  rwlock_unlock (tracker->dwfltab_lock);
> +
> +  if (ent != NULL && !ent->invalid)
> +    dwfl = ent->dwfl;
> +  if (dwfl == NULL && callback != NULL)
> +    dwfl = callback(tracker, pid, arg);
> +  if (dwfl != NULL)
> +    {
> +      assert (dwfl->tracker == tracker);
> +      /* XXX: dwfl added to dwfltab when dwfl->process set in 
> dwfl_attach_state.
> +         Prior to that, the pid is not confirmed. */

Should this information be incorporated into the libdw_stacktrace.h
doc comment for dwflst_process_tracker?

> +    }
> +
> +  return dwfl;
> +}
>
>  void
>  internal_function
> diff --git a/libdwfl_stacktrace/libdwfl_stacktrace.h 
> b/libdwfl_stacktrace/libdwfl_stacktrace.h
> index d29dc640..ed6a6a5c 100644
> --- a/libdwfl_stacktrace/libdwfl_stacktrace.h
> +++ b/libdwfl_stacktrace/libdwfl_stacktrace.h
> @@ -79,6 +79,17 @@ extern bool dwflst_tracker_cache_elf 
> (Dwflst_Process_Tracker *tracker,
>                                       Elf *elf, int fd)
>    __nonnull_attribute__ (1, 2);
>
> +/* Find the Dwfl corresponding to PID.  If CALLBACK is non-NULL and
> +   the Dwfl has not been created, invoke CALLBACK to create the Dwfl
> +   and then store it in the tracker.  */

I would mention what a return value of NULL means (ex. callback failed).

> +extern Dwfl *dwflst_tracker_find_pid (Dwflst_Process_Tracker *tracker,
> +                                     pid_t pid,
> +                                     Dwfl *(*callback) 
> (Dwflst_Process_Tracker *tracker,
> +                                                        pid_t pid,
> +                                                        void *arg),
> +                                     void *arg)
> +  __nonnull_attribute__ (1);
> +
>  /* For implementing a find_elf callback based on the prior two functions.
>     Returns the Dwflst_Process_Tracker corresponding to MOD.  */
>  extern Dwflst_Process_Tracker *dwflst_module_gettracker (Dwfl_Module *mod);
> --
> 2.47.0
>

Aaron

Reply via email to