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/libdwfl.h (dwfl_process_tracker_find_pid): New function. * libdwfl/dwfl_process_tracker.h (dwfl_process_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 dwfl_process_tracker_find_pid. --- libdw/libdw.map | 1 + libdwfl/dwfl_process_tracker.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/libdw/libdw.map b/libdw/libdw.map index 77be3906..489d0a8f 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -398,4 +398,5 @@ ELFUTILS_0.193 { dwfl_process_tracker_cache_elf; dwfl_module_gettracker; dwfl_process_tracker_find_elf; + dwfl_process_tracker_find_pid; } ELFUTILS_0.192; diff --git a/libdwfl/dwfl_process_tracker.c b/libdwfl/dwfl_process_tracker.c index 200b622b..e473ebd7 100644 --- a/libdwfl/dwfl_process_tracker.c +++ b/libdwfl/dwfl_process_tracker.c @@ -67,6 +67,32 @@ Dwfl *dwfl_begin_with_tracker (Dwfl_Process_Tracker *tracker) return dwfl; } +Dwfl *dwfl_process_tracker_find_pid (Dwfl_Process_Tracker *tracker, + pid_t pid, + Dwfl *(*callback) (Dwfl_Process_Tracker *, + pid_t, void *), + void *arg) +{ + Dwfl *dwfl = NULL; + + rwlock_rdlock (tracker->dwfltab_lock); + dwfltracker_dwfl_info *ent = dwfltracker_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. */ + } + + return dwfl; +} + void __libdwfl_add_dwfl_to_tracker (Dwfl *dwfl) { Dwfl_Process_Tracker *tracker = dwfl->tracker; assert (tracker != NULL); -- 2.47.0