Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-09 10:10:56

0001 /* Interfaces for libdwfl_stacktrace.
0002 
0003    XXX: This is an experimental initial version of the API, and is
0004    liable to change in future releases of elfutils, especially as
0005    we figure out how to generalize the work to other sample data
0006    formats in addition to perf_events.
0007 
0008    Copyright (C) 2025 Red Hat, Inc.
0009    This file is part of elfutils.
0010 
0011    This file is free software; you can redistribute it and/or modify
0012    it under the terms of either
0013 
0014      * the GNU Lesser General Public License as published by the Free
0015        Software Foundation; either version 3 of the License, or (at
0016        your option) any later version
0017 
0018    or
0019 
0020      * the GNU General Public License as published by the Free
0021        Software Foundation; either version 2 of the License, or (at
0022        your option) any later version
0023 
0024    or both in parallel, as here.
0025 
0026    elfutils is distributed in the hope that it will be useful, but
0027    WITHOUT ANY WARRANTY; without even the implied warranty of
0028    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0029    General Public License for more details.
0030 
0031    You should have received copies of the GNU General Public License and
0032    the GNU Lesser General Public License along with this program.  If
0033    not, see <http://www.gnu.org/licenses/>.  */
0034 
0035 #ifndef _LIBDWFL_STACKTRACE_H
0036 #define _LIBDWFL_STACKTRACE_H  1
0037 
0038 #include "libdwfl.h"
0039 
0040 #ifdef __cplusplus
0041 extern "C" {
0042 #endif
0043 
0044 /* Keeps track of and caches Elf structs across multiple libdwfl
0045    sessions corresponding to different processes.  */
0046 typedef struct Dwflst_Process_Tracker Dwflst_Process_Tracker;
0047 
0048 
0049 /* Initialize a new tracker for multiple libdwfl sessions.  Since Elf
0050    data will shared between the libdwfl sessions, each Dwfl must use
0051    the same Dwfl_Callbacks CALLBACKS provided when the tracker is
0052    created.  */
0053 extern Dwflst_Process_Tracker *dwflst_tracker_begin (const Dwfl_Callbacks *callbacks)
0054   __nonnull_attribute__ (1);
0055 
0056 /* Create a new Dwfl linked to this tracker.  */
0057 extern Dwfl *dwflst_tracker_dwfl_begin (Dwflst_Process_Tracker *tracker)
0058   __nonnull_attribute__ (1);
0059 
0060 /* Try to find a cached Elf corresponding to MODULE_NAME.  Verifies
0061    that the cached Elf has dev/ino/mtime matching the file on disk.
0062    Non-NULL MODULE_PATH specifies an alternate location for the module
0063    e.g. /proc/PID/root/MODULE_NAME.  Stores FILE_NAME and ELFP values.
0064    Returns fd similar to the find_elf callbacks, or -1 if cached Elf
0065    was not found.  */
0066 extern int dwflst_tracker_find_cached_elf (Dwflst_Process_Tracker *tracker,
0067                        const char *module_name,
0068                        const char *module_path,
0069                        char **file_name, Elf **elfp)
0070   __nonnull_attribute__ (1, 2, 4, 5);
0071 
0072 /* Store an Elf corresponding to MODULE_NAME in the tracker's cache.
0073    FILE_NAME and FD values must be provided, similar to the output of
0074    a find_elf callback.  Returns TRUE iff the Elf was successfully
0075    stored in the cache.  The tracker will retain the Elf* via libelf's
0076    reference counting mechanism, and release its reference during
0077    dwflst_tracker_end.  */
0078 extern bool dwflst_tracker_cache_elf (Dwflst_Process_Tracker *tracker,
0079                       const char *module_name,
0080                       const char *file_name,
0081                       Elf *elf, int fd)
0082   __nonnull_attribute__ (1, 2);
0083 
0084 /* Find the Dwfl corresponding to PID.  If CALLBACK is non-NULL and
0085    the Dwfl has not been created, invoke CALLBACK, which should return
0086    a Dwfl linked to the tracker (or NULL if Dwfl creation also fails).
0087    The Dwfl will be automatically added to the tracker's internal
0088    table when its pid is confirmed by calling dwfl_attach_state.
0089    Returns NULL if Dwfl was not found and callback failed.  */
0090 extern Dwfl *dwflst_tracker_find_pid (Dwflst_Process_Tracker *tracker,
0091                       pid_t pid,
0092                       Dwfl *(*callback) (Dwflst_Process_Tracker *tracker,
0093                              pid_t pid,
0094                              void *arg),
0095                       void *arg)
0096   __nonnull_attribute__ (1);
0097 
0098 /* For implementing a find_elf callback based on the prior two functions.
0099    Returns the Dwflst_Process_Tracker corresponding to MOD.  */
0100 extern Dwflst_Process_Tracker *dwflst_module_gettracker (Dwfl_Module *mod);
0101 
0102 /* End all libdwfl sessions with this tracker.  */
0103 extern void dwflst_tracker_end (Dwflst_Process_Tracker *tracker);
0104 
0105 
0106 /* Adaptation of the dwfl_linux_proc_find_elf callback from libdwfl,
0107    except this first attempts to look up a cached Elf* and fd from the
0108    Dwfl_Module's Dwflst_Process_Tracker (if any).  If a new Elf* is
0109    created, this callback saves it to the tracker's cache.
0110    The cache will retain the Elf* via libelf's reference counting
0111    mechanism, and release its reference during dwflst_tracker_end.  */
0112 extern int dwflst_tracker_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
0113                            const char *module_name, Dwarf_Addr base,
0114                            char **file_name, Elf **);
0115 
0116 
0117 /* Like dwfl_thread_getframes, but iterates through the frames for a
0118    linux perf_events stack sample rather than a live thread.  Calls
0119    dwfl_attach_state on DWFL, with architecture specified by ELF, ELF
0120    must remain valid during Dwfl lifetime.  Returns zero if all frames
0121    have been processed by the callback, returns -1 on error, or the
0122    value of the callback when not DWARF_CB_OK.  -1 returned on error
0123    will set dwfl_errno ().  */
0124 int dwflst_perf_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid,
0125                   const void *stack, size_t stack_size,
0126                   const Dwarf_Word *regs, uint32_t n_regs,
0127                   uint64_t perf_regs_mask, uint32_t abi,
0128                   int (*callback) (Dwfl_Frame *state, void *arg),
0129                   void *arg)
0130   __nonnull_attribute__ (1, 5, 7, 11);
0131 
0132 /* Returns the linux perf_events register mask describing a set of
0133    registers sufficient for unwinding on MACHINE, or 0 if libdwfl does
0134    not handle perf_events samples for MACHINE.  Does not take a Dwfl*
0135    or Elf* since this is meant to allow a profiling tool to configure
0136    perf_events to produce meaningful data for a libdwfl session to be
0137    opened later.  */
0138 uint64_t dwflst_perf_sample_preferred_regs_mask (GElf_Half machine);
0139 
0140 #ifdef __cplusplus
0141 }
0142 #endif
0143 
0144 #endif  /* libdwfl_stacktrace.h */