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