summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhei Makarov <[email protected]>2025-01-20 16:38:42 -0500
committerSerhei Makarov <[email protected]>2025-01-28 12:30:50 -0500
commitd1a9b5d17c2b0148e07970ed9485aeb91802cdb0 (patch)
treec673e94dc9f6f8204aaa68565c9a1c06c27dc7d1
parenta69418baa8e20fb1d3dbafbaacd695ca2f4a41b0 (diff)
libdwfl: introduce Dwfl_Process_Tracker
New data structure to coordinate caching Elf data among multiple Dwfl structs attached to different processes. Meant to reduce the overhead for profilers that use elfutils for unwinding. The caching is well-justified, as the current approach (e.g. in eu-stacktrace, sysprof-live-unwinder) of creating a separate Dwfl per process Initial patch just introduces the struct, to be filled in by the rest of the patch series. * libdwfl/libdwfl.h (Dwfl_Process_Tracker): New struct. (dwfl_process_tracker_begin): New function. (dwfl_begin_with_tracker): New function. (dwfl_process_tracker_end): New function. * libdw/libdw.map: Add new functions. * libdwfl/libdwflP.h (struct Dwfl_Process_Tracker): New struct. (struct Dwfl): Add 'tracker' field. * libdwfl/Makefile.am (libdwfl_a_SOURCES): Add dwfl_process_tracker.c. * libdwfl/dwfl_process_tracker.c: New file. (dwfl_process_tracker_begin): Initialize the tracker. (dwfl_begin_with_tracker): Initialize Dwfl * with specified tracker. (dwfl_process_tracker_end): Deallocate the tracker.
-rw-r--r--libdw/libdw.map7
-rw-r--r--libdwfl/Makefile.am1
-rw-r--r--libdwfl/dwfl_process_tracker.c66
-rw-r--r--libdwfl/libdwfl.h17
-rw-r--r--libdwfl/libdwflP.h7
5 files changed, 97 insertions, 1 deletions
diff --git a/libdw/libdw.map b/libdw/libdw.map
index bc53385f..47bad5f4 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -385,3 +385,10 @@ ELFUTILS_0.192 {
dwfl_frame_unwound_source;
dwfl_unwound_source_str;
} ELFUTILS_0.191;
+
+ELFUTILS_0.193 {
+ global:
+ dwfl_process_tracker_begin;
+ dwfl_begin_with_tracker;
+ dwfl_process_tracker_end;
+} ELFUTILS_0.192;
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index 57c89604..7221a3d7 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -71,6 +71,7 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
link_map.c core-file.c open.c image-header.c \
dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \
linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \
+ dwfl_process_tracker.c \
gzip.c debuginfod-client.c
if BZLIB
diff --git a/libdwfl/dwfl_process_tracker.c b/libdwfl/dwfl_process_tracker.c
new file mode 100644
index 00000000..a66bcace
--- /dev/null
+++ b/libdwfl/dwfl_process_tracker.c
@@ -0,0 +1,66 @@
+/* Track multiple Dwfl structs for multiple processes.
+ Copyright (C) 2025, Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Process_Tracker *dwfl_process_tracker_begin (const Dwfl_Callbacks *callbacks)
+{
+ Dwfl_Process_Tracker *tracker = calloc (1, sizeof *tracker);
+ if (tracker == NULL)
+ {
+ __libdwfl_seterrno (DWFL_E_NOMEM);
+ return tracker;
+ }
+
+ tracker->callbacks = callbacks;
+ return tracker;
+}
+
+Dwfl *dwfl_begin_with_tracker (Dwfl_Process_Tracker *tracker)
+{
+ Dwfl *dwfl = dwfl_begin (tracker->callbacks);
+ if (dwfl == NULL)
+ return dwfl;
+
+ /* TODO: Could also share dwfl->debuginfod, but thead-safely? */
+ dwfl->tracker = tracker;
+ return dwfl;
+}
+
+void dwfl_process_tracker_end (Dwfl_Process_Tracker *tracker)
+{
+ if (tracker == NULL)
+ return;
+
+ /* TODO: Call dwfl_end for each Dwfl connected to this tracker. */
+ free (tracker);
+}
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 90523283..4ba68cc2 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -32,9 +32,12 @@
#include "libdw.h"
#include <stdio.h>
-/* Handle for a session using the library. */
+/* Handle for a session using the library to attach to a single target process. */
typedef struct Dwfl Dwfl;
+/* Handle for a session using the library to attach to more than one process. */
+typedef struct Dwfl_Process_Tracker Dwfl_Process_Tracker;
+
/* Handle for a module. */
typedef struct Dwfl_Module Dwfl_Module;
@@ -122,6 +125,18 @@ extern int dwfl_errno (void);
extern const char *dwfl_errmsg (int err);
+/* Start a new multi-process session with the library. */
+extern Dwfl_Process_Tracker *dwfl_process_tracker_begin (const Dwfl_Callbacks *callbacks)
+ __nonnull_attribute__ (1);
+
+/* Create a new Dwfl within a multi-process session. */
+extern Dwfl *dwfl_begin_with_tracker (Dwfl_Process_Tracker *tracker)
+ __nonnull_attribute__ (1);
+
+/* End a multi-process session. */
+extern void dwfl_process_tracker_end (Dwfl_Process_Tracker *tracker);
+
+
/* Start reporting the current set of segments and modules to the library.
All existing segments are wiped. Existing modules are marked to be
deleted, and will not be found via dwfl_addrmodule et al if they are not
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 6ec5c966..9bcfea6c 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -101,6 +101,12 @@ typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
+struct Dwfl_Process_Tracker
+{
+ const Dwfl_Callbacks *callbacks;
+ /* ... */
+};
+
/* Resources we might keep for the user about the core file that the
Dwfl might have been created from. Can currently only be set
through std-argp. */
@@ -114,6 +120,7 @@ struct Dwfl_User_Core
struct Dwfl
{
const Dwfl_Callbacks *callbacks;
+ Dwfl_Process_Tracker *tracker;
#ifdef ENABLE_LIBDEBUGINFOD
debuginfod_client *debuginfod;
#endif