summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhei Makarov <[email protected]>2025-04-23 10:44:44 -0400
committerSerhei Makarov <[email protected]>2025-04-25 10:10:07 -0400
commitbce66f1c8e3360df1e3b8787d9e38eaf2fa32499 (patch)
treecacb771ca4edceca46778199da823a2a8201c7be
parent592620d4dca43b0208f8c97a2e0567351b4666a0 (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.map1
-rw-r--r--libdwfl_stacktrace/dwflst_process_tracker.c26
-rw-r--r--libdwfl_stacktrace/libdwfl_stacktrace.h14
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);