Hello,

I've been concerned to get libdwfl_stacktrace out of the weird 'experimental' 
limbo we put it in for the last elfutils release. To do that, we need to 
stabilize the API.

My full prototype of a more mature API is delayed for reasons beyond my 
control, but sometime in September is the likely ETA. For now I want to get 
people's opinions (mjw? amerey?) on the most crucial change. To avoid depending 
on the Linux kernel specific perf_events API, we need a 
dwflst_sample_getframes() function that doesn't take perf_events formatted data.

The header-only patch below illustrates the planned API change.
The base solution is for dwflst_sample_getframes() to take a pointer to 
regs_mapping, which, for each item in regs[] array, specifies its position in 
the full register file expected by the DWARF functionality. (This avoids the 
need to take a perf_events regs bitmap that can only be interpreted with the 
aid of a weird enum header buried in the linux kernel tree.)

The regs_mapping array is most likely to stay constant for an entire profiling 
session, so this is not a high-overhead interface.

(A bit controversially, I'm allowing n_regs_mapping != n_regs, which might 
smoothly deal with cases where dwflst_sample_getframes is passed a profiling 
data packet with malformed or truncated regs array.)

We *keep* the existing dwflst_perf_sample_getframes as a convenience variant of 
dwflst_sample_getframes. It clearly says 'perf', and I think it's fine to have 
this perf-specific API as long as it's not the *only* API.

I believe this is the most significant obstacle to turning libdwfl_stacktrace 
into a stable API.
mjw, do any other major issues come to mind?
(I'm sure we will find minor things to fix when we bikeshed this header, of 
course.)

I could add functions to generate a plausible regs_mapping for various 
architectures,
though I'd like a non perf_events test case for that. I've looked at BSD 
PmcTools,
for one example, but not 100% sure yet how to bolt libdwfl_stacktrace into it.

All the best,
    Serhei

diff --git a/libdwfl_stacktrace/libdwfl_stacktrace.h b/libdwfl_stacktrace/libdw\
fl_stacktrace.h
index b236ddc4..b8987c6f 100644
--- a/libdwfl_stacktrace/libdwfl_stacktrace.h
+++ b/libdwfl_stacktrace/libdwfl_stacktrace.h
@@ -113,14 +113,28 @@ extern int dwflst_tracker_linux_proc_find_elf (Dwfl_Modul\
e *mod, void **userdata
                                               const char *module_name, Dwarf_A\
ddr base,
                                               char **file_name, Elf **);

-
 /* Like dwfl_thread_getframes, but iterates through the frames for a
-   linux perf_events stack sample rather than a live thread.  Calls
-   dwfl_attach_state on DWFL, with architecture specified by ELF, ELF
-   must remain valid during Dwfl lifetime.  Returns zero if all frames
-   have been processed by the callback, returns -1 on error, or the
-   value of the callback when not DWARF_CB_OK.  -1 returned on error
-   will set dwfl_errno ().  */
+   stack sample rather than a live thread.  Calls dwfl_attach_state on
+   DWFL, with architecture specified by ELF, ELF must remain vaild
+   during Dwfl lifetime.  Returns zero if all frames have been
+   processed by the callback, returns -1 on error, or the value of the
+   callback when not DWARF_CB_OK. -1 returned on error will set
+   dwfl_errno (). */
+int dwflst_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid,
+                                 const void *stack, size_t stack_size,
+                                 const Dwarf_Word *regs, uint32_t n_regs,
+                                 const int *regs_mapping, uint32_t 
n_regs_mapping,
+                                 int (*callback) (Dwfl_Frame *state, void 
*arg),
+                                 void *arg)
+    __nonnull_attribute__ (1, 5, 7, 9, 11);
+
+/* Adapts dwflst_sample_getframes to linux perf_events stack sample
+   and register file data format.  Calls dwfl_attach_state on DWFL,
+   with architecture specified by ELF, ELF must remain valid during
+   Dwfl lifetime.  Returns zero if all frames have been processed by
+   the callback, returns -1 on error, or the value of the callback
+   when not DWARF_CB_OK. -1 returned on error will set dwfl_errno
+   (). */
 int dwflst_perf_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid,
                                  const void *stack, size_t stack_size,
                                  const Dwarf_Word *regs, uint32_t n_regs,

Reply via email to