61#ifndef HEPHAESTUS_STACKSTASH_H
62#define HEPHAESTUS_STACKSTASH_H
164#define STACK_ELEMENT_BEGIN_P(element) (*((element)-1) == 0)
168#define STACK_ELEMENT_NODE(element) \
169 ((StackNode*)((char*)((element)-1) - offsetof(StackNode, p)))
173#define STACK_ELEMENT_NODEPARENT(element) (STACK_ELEMENT_NODE(element)->parent)
176#define STACK_NODE_NTH_ELEMENT(node, n) ((node)->p[n+1])
179#define STACK_NODE_NTH_CHILD(node, n) \
180 (*(StackNode**)&((node)->p[n+1+(node)->nelts]))
183#define STACK_ELEMENT_NONNULL(elt) ((elt) ? (elt) : (StackElement)1)
186#define STACK_NODE_SET_ELEMENT(node, n, elt) do{ (node)->p[n+1] = STACK_ELEMENT_NONNULL(elt); } while(0)
198#define STACK_HANDLE_ELEMENT(handle) ((handle)->element)
201#define STACK_HANDLE_ADDR(handle) \
202 STACK_ELEMENT_ADDR(STACK_HANDLE_ELEMENT(handle))
205#define STACK_HANDLE_PARENT(handle) \
206 STACK_ELEMENT_PARENT(STACK_HANDLE_ELEMENT(handle))
209#define STACK_HANDLE_IS_ROOT(handle) \
210 STACK_ELEMENT_IS_ROOT(STACK_HANDLE_ELEMENT(handle))
217#define STACK_ELEMENT_ADDR(element) (*(element))
221#define STACK_ELEMENT_PARENT(element) hhh_stack_element_parent(element)
224#define STACK_ELEMENT_IS_ROOT(element) (*(element) == 0)
231#define STACK_CURSOR_ELEMENT(cursor) ((cursor).elt)
234#define STACK_CURSOR_ELEMENT_ADDR(cursor) STACK_ELEMENT_ADDR(STACK_CURSOR_ELEMENT(cursor))
237#define STACK_CURSOR_INIT_ROOT(cursor) hhh_Cursor_initRoot(&cursor)
240#define STACK_CURSOR_INIT_HANDLE(cursor, handle) hhh_Cursor_initHandle(&cursor, handle)
243#define STACK_CURSOR_IS_ROOT(cursor) STACK_ELEMENT_IS_ROOT(STACK_CURSOR_ELEMENT(cursor))
246#define STACK_CURSOR_PARENT(cursor) hhh_Cursor_parent(&cursor)
249#define STACK_CURSOR_NCHILDREN(cursor) hhh_Cursor_nchildren(&cursor)
252#define STACK_CURSOR_CHILD(cursor, n) hhh_Cursor_child(&cursor, n)
255#define STACK_CURSOR_NEXT(cursor) hhh_Cursor_next(&cursor)
void hhh_Cursor_child(StackCursor *cursor, int n)
Move to the cursor to the nth child.
void * StackElement
One element of a stack trace.
struct StackCursor_ StackCursor
int hhh_Cursor_nchildren(StackCursor *cursor)
Return the number of children.
struct StackHandle_ StackHandle
void hhh_Cursor_next(StackCursor *cursor)
Visit next element in depth-first order.
void hhh_Cursor_initRoot(StackCursor *cursor)
Initialize a cursor to point at the root of the tree.
struct StackNode_ StackNode
void hhh_Cursor_parent(StackCursor *cursor)
Move to the cursor to the parent node.
void hhh_Cursor_initHandle(StackCursor *cursor, StackHandle *handle)
Initialize a cursor from a handle.
StackHandle * hhh_stackstash_store(const StackElement *addresses, int n_addresses)
Return the handle for a stack trace.
StackElement * hhh_stack_element_parent(StackElement *elt)
Function interface to iterate over a trace.
Cursor object used to move between nodes of the tree.
Unique reference for a stack trace.
struct StackHandle_ * next
Node used to store trace data.
struct StackNode_ * parent