On Thu, Apr 24, 2025 at 5:49 PM Serhei Makarov <[email protected]> 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