On Thu, Apr 24, 2025 at 5:49 PM Serhei Makarov <ser...@serhei.io> wrote:
>
> Changes for v4:
>
> - Separate out libdwfl_stacktrace, as requested.
>
> * * *
>
> Initial minimal change to ensure dwflst_tracker_find_pid is
> tested. For now, we keep the additional dwfltab implementation in
> stacktrace.c, since it's being used to track statistics.
>
> In future follow-ups, it will be good to switch to storing
> eu-stacktrace statistics e.g. in dwfl->process->callbacks_arg. This
> requires some additional design to keep the statistics from being lost
> when a pid is reused and the corresponding processtracker table entry
> is replaced.
>
> * src/stacktrace.c (sysprof_init_dwfl): New function.
>   (sysprof_find_dwfl): Rename the existing sysprof_init_dwfl.
>   Also use dwflst_tracker_find_pid with callback.
>   (sysprof_unwind_cb): Rename the existing sysprof_init_dwfl.
> ---
>  src/stacktrace.c | 63 +++++++++++++++++++++++++++---------------------
>  1 file changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/src/stacktrace.c b/src/stacktrace.c
> index c0c9929d..dd58ef3b 100644
> --- a/src/stacktrace.c
> +++ b/src/stacktrace.c
> @@ -96,7 +96,7 @@
>  #include ELFUTILS_HEADER(ebl)
>  /* #include ELFUTILS_HEADER(dwfl) */
>  #include "../libdwfl/libdwflP.h"
> -/* XXX: Private header needed for find_procfile, sysprof_init_dwfl,
> +/* XXX: Private header needed for find_procfile, sysprof_find_dwfl,
>     sample_set_initial_registers. */
>  #include ELFUTILS_HEADER(dwfl_stacktrace)
>
> @@ -1014,7 +1014,34 @@ find_procfile (Dwfl *dwfl, pid_t *pid, Elf **elf, int 
> *elf_fd)
>  }
>
>  Dwfl *
> -sysprof_init_dwfl (struct sysprof_unwind_info *sui,
> +sysprof_init_dwfl (Dwflst_Process_Tracker *cb_tracker,

Just a nit but I would include _cb or _callback in the name to make it
more clear this function is a callback. Otherwise LGTM.

> +                   pid_t pid,
> +                   void *arg __attribute__ ((unused)))
> +{
> +  Dwfl *dwfl = dwflst_tracker_dwfl_begin (cb_tracker);
> +
> +  int err = dwfl_linux_proc_report (dwfl, pid);
> +  if (err < 0)
> +    {
> +      if (show_failures)
> +       fprintf(stderr, "dwfl_linux_proc_report pid %lld: %s",
> +               (long long) pid, dwfl_errmsg (-1));
> +      return NULL;
> +    }
> +  err = dwfl_report_end (dwfl, NULL, NULL);
> +  if (err != 0)
> +    {
> +      if (show_failures)
> +       fprintf(stderr, "dwfl_report_end pid %lld: %s",
> +               (long long) pid, dwfl_errmsg (-1));
> +      return NULL;
> +    }
> +
> +  return dwfl;
> +}
> +
> +Dwfl *
> +sysprof_find_dwfl (struct sysprof_unwind_info *sui,
>                    SysprofCaptureStackUser *ev,
>                    SysprofCaptureUserRegs *regs)
>  {
> @@ -1027,42 +1054,24 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui,
>    if (regs->n_regs < EXPECTED_REGS) /* XXX expecting everything except FLAGS 
> */
>      {
>        if (show_failures)
> -       fprintf(stderr, N_("sysprof_init_dwfl: n_regs=%d, expected %d\n"),
> +       fprintf(stderr, N_("sysprof_find_dwfl: n_regs=%d, expected %d\n"),
>                 regs->n_regs, EXPECTED_REGS);
>        return NULL;
>      }
>
> -  Dwfl *dwfl = pid_find_dwfl(pid);
> +  Dwfl *dwfl = dwflst_tracker_find_pid (tracker, pid, sysprof_init_dwfl, 
> NULL);
>    struct __sample_arg *sample_arg;
>    bool cached = false;
> -  if (dwfl != NULL)
> +  if (dwfl != NULL && dwfl->process != NULL)
>      {
>        sample_arg = dwfl->process->callbacks_arg; /* XXX requires libdwflP.h 
> */
>        cached = true;
>        goto reuse;
>      }
> -  dwfl = dwflst_tracker_dwfl_begin (tracker);
> -
> -  int err = dwfl_linux_proc_report (dwfl, pid);
> -  if (err < 0)
> -    {
> -      if (show_failures)
> -       fprintf(stderr, "dwfl_linux_proc_report pid %lld: %s",
> -               (long long) pid, dwfl_errmsg (-1));
> -      return NULL;
> -    }
> -  err = dwfl_report_end (dwfl, NULL, NULL);
> -  if (err != 0)
> -    {
> -      if (show_failures)
> -       fprintf(stderr, "dwfl_report_end pid %lld: %s",
> -               (long long) pid, dwfl_errmsg (-1));
> -      return NULL;
> -    }
>
>    Elf *elf = NULL;
>    int elf_fd = -1;
> -  err = find_procfile (dwfl, &pid, &elf, &elf_fd);
> +  int err = find_procfile (dwfl, &pid, &elf, &elf_fd);
>    if (err < 0)
>      {
>        if (show_failures)
> @@ -1099,7 +1108,7 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui,
>
>    if (show_frames) {
>      bool is_abi32 = (sample_arg->abi == PERF_SAMPLE_REGS_ABI_32);
> -    fprintf(stderr, "sysprof_init_dwfl pid %lld%s: size=%ld%s pc=%lx 
> sp=%lx+(%lx)\n",
> +    fprintf(stderr, "sysprof_find_dwfl pid %lld%s: size=%ld%s pc=%lx 
> sp=%lx+(%lx)\n",
>             (long long) pid, cached ? " (cached)" : "",
>             sample_arg->size, is_abi32 ? " (32-bit)" : "",
>             sample_arg->pc, sample_arg->base_addr,
> @@ -1260,7 +1269,7 @@ sysprof_unwind_cb (SysprofCaptureFrame *frame, void 
> *arg)
>    SysprofCaptureUserRegs *regs = (SysprofCaptureUserRegs *)tail_ptr;
>    if (show_frames)
>      fprintf(stderr, "\n"); /* extra newline for padding */
> -  Dwfl *dwfl = sysprof_init_dwfl (sui, ev, regs);
> +  Dwfl *dwfl = sysprof_find_dwfl (sui, ev, regs);
>    if (dwfl == NULL)
>      {
>        if (show_summary)
> @@ -1270,7 +1279,7 @@ sysprof_unwind_cb (SysprofCaptureFrame *frame, void 
> *arg)
>           dwfl_ent->lost_samples++;
>         }
>        if (show_failures)
> -       fprintf(stderr, "sysprof_init_dwfl pid %lld (%s) (failed)\n",
> +       fprintf(stderr, "sysprof_find_dwfl pid %lld (%s) (failed)\n",
>                 (long long)frame->pid, comm);
>        return SYSPROF_CB_OK;
>      }
> --
> 2.47.0
>

Aaron

Reply via email to