1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Stack trace management functions 4 * 5 * Copyright IBM Corp. 2006 6 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 7 */ 8 9 #include <linux/sched.h> 10 #include <linux/sched/debug.h> 11 #include <linux/stacktrace.h> 12 #include <linux/kallsyms.h> 13 #include <linux/export.h> 14 #include <asm/stacktrace.h> 15 #include <asm/unwind.h> 16 17 void save_stack_trace(struct stack_trace *trace) 18 { 19 struct unwind_state state; 20 21 unwind_for_each_frame(&state, current, NULL, 0) { 22 if (trace->nr_entries >= trace->max_entries) 23 break; 24 if (trace->skip > 0) 25 trace->skip--; 26 else 27 trace->entries[trace->nr_entries++] = state.ip; 28 } 29 } 30 EXPORT_SYMBOL_GPL(save_stack_trace); 31 32 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 33 { 34 struct unwind_state state; 35 36 unwind_for_each_frame(&state, tsk, NULL, 0) { 37 if (trace->nr_entries >= trace->max_entries) 38 break; 39 if (in_sched_functions(state.ip)) 40 continue; 41 if (trace->skip > 0) 42 trace->skip--; 43 else 44 trace->entries[trace->nr_entries++] = state.ip; 45 } 46 } 47 EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 48 49 void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) 50 { 51 struct unwind_state state; 52 53 unwind_for_each_frame(&state, current, regs, 0) { 54 if (trace->nr_entries >= trace->max_entries) 55 break; 56 if (trace->skip > 0) 57 trace->skip--; 58 else 59 trace->entries[trace->nr_entries++] = state.ip; 60 } 61 } 62 EXPORT_SYMBOL_GPL(save_stack_trace_regs); 63