On Thu, 13 Jun 2013 15:38:33 +0200, Mark Wielaard wrote:
typedef struct Dwfl_Thread;
typedef struct Dwfl_Thread
/* Called to iterate through threads. Starting with previous *ptid
set to -1. Returns next thread id on success, a negative number on
failure and zero if there are no more threads. Should call
dwfl_thread_state () on nthread if thread can be unwound with
initial register and memory accessors. */
pid_t (*next_thread) (Dwfl *dwfl, pid_t pid, pid_t *ptid,
Dwfl_Thread *nthread, void *arg);
/* Called by dwfl_end (). */
void (*detach) (Dwfl *dwfl, pid_t pid, void *arg);
Couldn't it be merged together with Dwfl_Thread_Callbacks?
This would also remove the dwfl_thread_state function.
Dwfl_Thread_Callbacks->memory_read is a PID-related function, not TID-related.
Maybe rather Dwfl_Frame_Callbacks, I no longer remember much why I called it
dwfl_frame_state and not just dwfl_frame.
/* pid is the process id associated with the Dwfl state, arg is the
callback backend state. Both will be provided to the callbacks. */
dwfl_attach_state (Dwfl *dwfl, pid_t pid,
Dwfl_State_Callbacks *state, void *arg);
Dwfl_State_Callbacks *state_callbacks, void *arg);
/* probably needed... */
Dwfl *dwfl_thread_dwfl (Dwfl_Thread *thread);
pid_t dwfl_thread_pid (Dwfl_Thread *thread);
PID or TID? You have declared dwfl_thread_tid below. But if it should be PID
then it should be:
pid_t dwfl_pid (Dwfl *dwfl);
/* Called on initial unwind to get the initial register state of the
first frame. Should call dwfl_thread_state_registers (), possibly
multiple times for different ranges, to fill in initial (DWARF)
register values. After this call, till at least thread_detach is
called, the thread is assumed to be frozen, so that it is safe to
unwind. Returns true on success or false and sets dwfl_err() on
bool (*set_initial_registers) (Dwfl_Thread *thread, pid_t tid,
I think it should integrate dwfl_thread_state_registers, all the
dwfl_thread_state_registers parameters should be here as return-references.
/* Called during unwinding to access memory (stack) state. */
bool (*memory_read) (Dwfl_Thread *thread, pid_t tid,
Dwarf_Addr addr, Dwarf_Word *result,
/* Called when unwinding is done. No callback will be called after
this has been called. */
void (*thread_detach) (Dwfl_Thread *thread, pid_t tid, void *arg);
dwfl_thread_state (Dwfl_Thread *thread, Dwfl_Thread_Callbacks
Proposing to be removed above.
pid_t dwfl_thread_tid (Dwfl_Thread *thread);
dwfl_thread_state_registers (Dwfl_Thread *thread,
const int firstreg,
const Dwarf_Word *regs);
I would delete this function, see above. wrt its parameters:
This is apparently derived from dwfl_frame_state_data. But I do not see what
is firstreg, where is pc/pc_set and where is regs_set.
PC_SET is true if PC contains a valid value. On some archs PC is not present
in REGS. NREGS is number of valid registers in REGS and REGS_SET. REGS_SET is
a bitfield specifying which REGS are valid.
extern Dwfl_Frame_State *dwfl_frame_state_data (Dwfl *dwfl, bool pc_set,
Dwarf_Addr pc, unsigned nregs,
const uint64_t *regs_set,
const Dwarf_Addr *regs,
Then (the existing?) dwfl_linux_proc_report and
could setup the above callbacks. Or they could be setup by someone by
hand if they can provide registers and memory accessors in some other
For the user/usage side we could then have:
/* Gets the next known thread, if any. To get the initial thread
provide NULL as previous thread. */
Dwfl_Thread *dwfl_next_thread (Dwfl *dwfl, Dwfl_Thread *pthread);
/* Iterate through the frames for a thread. 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. Keeps calling the
callback with the next frame while the callback returns
DWARF_CB_OK, till there are no more frames. On start will call the
set_initial_registers callback and on return will call the
detach_thread callback of the Dwfl_Thread. */
int dwfl_getdwarf (Dwfl_Thread *thread,
I do not understand the name "getdwarf".
int (*callback) (Dwfl_Frame *, void *),
Although maybe we could rename it to Dwfl_Frame anyway.
bool dwfl_frame_state_pc (Dwfl_Frame_State *state, Dwarf_Addr *pc,