diff options
author | Serhei Makarov <[email protected]> | 2025-04-23 10:44:44 -0400 |
---|---|---|
committer | Serhei Makarov <[email protected]> | 2025-04-25 10:10:07 -0400 |
commit | bce66f1c8e3360df1e3b8787d9e38eaf2fa32499 (patch) | |
tree | cacb771ca4edceca46778199da823a2a8201c7be | |
parent | 592620d4dca43b0208f8c97a2e0567351b4666a0 (diff) |
libdwfl_stacktrace [9/12]: add dwflst_tracker_find_pid
Changes for v6:
- Minor fixes as requested.
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.
-rw-r--r-- | libdw/libdw.map | 1 | ||||
-rw-r--r-- | libdwfl_stacktrace/dwflst_process_tracker.c | 26 | ||||
-rw-r--r-- | libdwfl_stacktrace/libdwfl_stacktrace.h | 14 |
3 files changed, 41 insertions, 0 deletions
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 c0678cb8..779f25f0 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. */ + } + + return dwfl; +} void internal_function diff --git a/libdwfl_stacktrace/libdwfl_stacktrace.h b/libdwfl_stacktrace/libdwfl_stacktrace.h index 286409b8..064c97b2 100644 --- a/libdwfl_stacktrace/libdwfl_stacktrace.h +++ b/libdwfl_stacktrace/libdwfl_stacktrace.h @@ -81,6 +81,20 @@ 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, which should return + a Dwfl linked to the tracker (or NULL if Dwfl creation also fails). + The Dwfl will be automatically added to the tracker's internal + table when its pid is confirmed by calling dwfl_attach_state. + Returns NULL if Dwfl was not found and 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); |