From: Serhei Makarov Date: Fri, 14 Feb 2025 21:57:14 +0000 (-0500) Subject: DRAFT eu-stacktrace: use dwfl_process_tracker_find_pid X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e05eddd643a46c004795df7a628373f220ea36b2;p=thirdparty%2Felfutils.git DRAFT eu-stacktrace: use dwfl_process_tracker_find_pid Will need to switch to storing statistics in dwfl->process->callbacks_arg? Requires a more careful design for how table entries are replaced when a pid is reused. * src/stacktrace.c (sysprof_init_dwfl): New function. (sysprof_find_dwfl): Rename the existing sysprof_init_dwfl. Also use dwfl_process_tracker_find_pid with callback. (sysprof_unwind_cb): Rename the existing sysprof_init_dwfl. --- diff --git a/src/stacktrace.c b/src/stacktrace.c index 566fcd75..c712eec5 100644 --- a/src/stacktrace.c +++ b/src/stacktrace.c @@ -95,7 +95,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. */ /************************************* @@ -989,7 +989,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 (Dwfl_Process_Tracker *cb_tracker, + pid_t pid, + void *arg __attribute__ ((unused))) +{ + Dwfl *dwfl = dwfl_begin_with_tracker (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) { @@ -1007,37 +1034,19 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, return NULL; } - Dwfl *dwfl = pid_find_dwfl(pid); + Dwfl *dwfl = dwfl_process_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 = dwfl_begin_with_tracker (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; - err = find_procfile (dwfl, &pid, &elf, &elf_fd); + int err = find_procfile (dwfl, &pid, &elf, &elf_fd); if (err < 0) { if (show_failures) @@ -1074,7 +1083,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, @@ -1235,7 +1244,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) @@ -1245,7 +1254,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; }