1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 28637c099SIngo Molnar #ifndef __LINUX_STACKTRACE_H 38637c099SIngo Molnar #define __LINUX_STACKTRACE_H 48637c099SIngo Molnar 59a92a6ceSJoonsoo Kim #include <linux/types.h> 6e9b98e16SThomas Gleixner #include <asm/errno.h> 79a92a6ceSJoonsoo Kim 8897312bdSAndrew Morton struct task_struct; 99c0729dcSSoeren Sandmann Pedersen struct pt_regs; 10897312bdSAndrew Morton 118637c099SIngo Molnar #ifdef CONFIG_STACKTRACE 12e9b98e16SThomas Gleixner void stack_trace_print(unsigned long *trace, unsigned int nr_entries, 13e9b98e16SThomas Gleixner int spaces); 14e9b98e16SThomas Gleixner int stack_trace_snprint(char *buf, size_t size, unsigned long *entries, 15e9b98e16SThomas Gleixner unsigned int nr_entries, int spaces); 16e9b98e16SThomas Gleixner unsigned int stack_trace_save(unsigned long *store, unsigned int size, 17e9b98e16SThomas Gleixner unsigned int skipnr); 18e9b98e16SThomas Gleixner unsigned int stack_trace_save_tsk(struct task_struct *task, 19e9b98e16SThomas Gleixner unsigned long *store, unsigned int size, 20e9b98e16SThomas Gleixner unsigned int skipnr); 21e9b98e16SThomas Gleixner unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store, 22e9b98e16SThomas Gleixner unsigned int size, unsigned int skipnr); 23e9b98e16SThomas Gleixner unsigned int stack_trace_save_user(unsigned long *store, unsigned int size); 24e9b98e16SThomas Gleixner 25e9b98e16SThomas Gleixner /* Internal interfaces. Do not use in generic code */ 26*214d8ca6SThomas Gleixner #ifdef CONFIG_ARCH_STACKWALK 27*214d8ca6SThomas Gleixner 28*214d8ca6SThomas Gleixner /** 29*214d8ca6SThomas Gleixner * stack_trace_consume_fn - Callback for arch_stack_walk() 30*214d8ca6SThomas Gleixner * @cookie: Caller supplied pointer handed back by arch_stack_walk() 31*214d8ca6SThomas Gleixner * @addr: The stack entry address to consume 32*214d8ca6SThomas Gleixner * @reliable: True when the stack entry is reliable. Required by 33*214d8ca6SThomas Gleixner * some printk based consumers. 34*214d8ca6SThomas Gleixner * 35*214d8ca6SThomas Gleixner * Return: True, if the entry was consumed or skipped 36*214d8ca6SThomas Gleixner * False, if there is no space left to store 37*214d8ca6SThomas Gleixner */ 38*214d8ca6SThomas Gleixner typedef bool (*stack_trace_consume_fn)(void *cookie, unsigned long addr, 39*214d8ca6SThomas Gleixner bool reliable); 40*214d8ca6SThomas Gleixner /** 41*214d8ca6SThomas Gleixner * arch_stack_walk - Architecture specific function to walk the stack 42*214d8ca6SThomas Gleixner * @consume_entry: Callback which is invoked by the architecture code for 43*214d8ca6SThomas Gleixner * each entry. 44*214d8ca6SThomas Gleixner * @cookie: Caller supplied pointer which is handed back to 45*214d8ca6SThomas Gleixner * @consume_entry 46*214d8ca6SThomas Gleixner * @task: Pointer to a task struct, can be NULL 47*214d8ca6SThomas Gleixner * @regs: Pointer to registers, can be NULL 48*214d8ca6SThomas Gleixner * 49*214d8ca6SThomas Gleixner * ============ ======= ============================================ 50*214d8ca6SThomas Gleixner * task regs 51*214d8ca6SThomas Gleixner * ============ ======= ============================================ 52*214d8ca6SThomas Gleixner * task NULL Stack trace from task (can be current) 53*214d8ca6SThomas Gleixner * current regs Stack trace starting on regs->stackpointer 54*214d8ca6SThomas Gleixner * ============ ======= ============================================ 55*214d8ca6SThomas Gleixner */ 56*214d8ca6SThomas Gleixner void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, 57*214d8ca6SThomas Gleixner struct task_struct *task, struct pt_regs *regs); 58*214d8ca6SThomas Gleixner int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie, 59*214d8ca6SThomas Gleixner struct task_struct *task); 60*214d8ca6SThomas Gleixner void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, 61*214d8ca6SThomas Gleixner const struct pt_regs *regs); 62*214d8ca6SThomas Gleixner 63*214d8ca6SThomas Gleixner #else /* CONFIG_ARCH_STACKWALK */ 648637c099SIngo Molnar struct stack_trace { 658637c099SIngo Molnar unsigned int nr_entries, max_entries; 668637c099SIngo Molnar unsigned long *entries; 675a1b3999SAndi Kleen int skip; /* input argument: How many entries to skip */ 688637c099SIngo Molnar }; 698637c099SIngo Molnar 70ab1b6f03SChristoph Hellwig extern void save_stack_trace(struct stack_trace *trace); 7139581062SMasami Hiramatsu extern void save_stack_trace_regs(struct pt_regs *regs, 7239581062SMasami Hiramatsu struct stack_trace *trace); 739745512cSArjan van de Ven extern void save_stack_trace_tsk(struct task_struct *tsk, 749745512cSArjan van de Ven struct stack_trace *trace); 75af085d90SJosh Poimboeuf extern int save_stack_trace_tsk_reliable(struct task_struct *tsk, 76af085d90SJosh Poimboeuf struct stack_trace *trace); 7702b67518STörök Edwin extern void save_stack_trace_user(struct stack_trace *trace); 78*214d8ca6SThomas Gleixner #endif /* !CONFIG_ARCH_STACKWALK */ 79af085d90SJosh Poimboeuf #endif /* CONFIG_STACKTRACE */ 808637c099SIngo Molnar 81e9b98e16SThomas Gleixner #if defined(CONFIG_STACKTRACE) && defined(CONFIG_HAVE_RELIABLE_STACKTRACE) 82e9b98e16SThomas Gleixner int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store, 83e9b98e16SThomas Gleixner unsigned int size); 84e9b98e16SThomas Gleixner #else 85e9b98e16SThomas Gleixner static inline int stack_trace_save_tsk_reliable(struct task_struct *tsk, 86e9b98e16SThomas Gleixner unsigned long *store, 87e9b98e16SThomas Gleixner unsigned int size) 88e9b98e16SThomas Gleixner { 89e9b98e16SThomas Gleixner return -ENOSYS; 90e9b98e16SThomas Gleixner } 91e9b98e16SThomas Gleixner #endif 92e9b98e16SThomas Gleixner 93af085d90SJosh Poimboeuf #endif /* __LINUX_STACKTRACE_H */ 94