]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl_stacktrace [9/12]: add dwflst_tracker_find_pid
authorSerhei Makarov <serhei@serhei.io>
Fri, 25 Apr 2025 14:55:51 +0000 (10:55 -0400)
committerAaron Merey <amerey@redhat.com>
Fri, 25 Apr 2025 15:55:20 +0000 (11:55 -0400)
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.

Signed-off-by: Serhei Makarov <serhei@serhei.io>
libdw/libdw.map
libdwfl_stacktrace/dwflst_process_tracker.c
libdwfl_stacktrace/libdwfl_stacktrace.h

index 46d0878ad1aef76be13221a0ef6d2dc873be8061..688e415c0107a92d259201afa0c731e0c21670c3 100644 (file)
@@ -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;
 };
index bea22c7c8b9f5e60994823aa6eeac78e1f27af16..967c51ec5b0184f6d2fe42203e4f68aff8b01dbb 100644 (file)
@@ -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
index 286409b8eea711899cbec893e304d6dea5409e71..064c97b2a987dee2a8cd9278571a5e9dd36b5e3f 100644 (file)
@@ -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);