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;
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
--- /dev/null
+/* 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);
+}
#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;
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
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. */
struct Dwfl
{
const Dwfl_Callbacks *callbacks;
+ Dwfl_Process_Tracker *tracker;
#ifdef ENABLE_LIBDEBUGINFOD
debuginfod_client *debuginfod;
#endif