1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Stack trace management functions 4 * 5 * Copyright IBM Corp. 2006 6 * Author(s): Heiko Carstens <[email protected]> 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 if (trace->nr_entries < trace->max_entries) 30 trace->entries[trace->nr_entries++] = ULONG_MAX; 31 } 32 EXPORT_SYMBOL_GPL(save_stack_trace); 33 34 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 35 { 36 struct unwind_state state; 37 38 unwind_for_each_frame(&state, tsk, NULL, 0) { 39 if (trace->nr_entries >= trace->max_entries) 40 break; 41 if (in_sched_functions(state.ip)) 42 continue; 43 if (trace->skip > 0) 44 trace->skip--; 45 else 46 trace->entries[trace->nr_entries++] = state.ip; 47 } 48 if (trace->nr_entries < trace->max_entries) 49 trace->entries[trace->nr_entries++] = ULONG_MAX; 50 } 51 EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 52 53 void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) 54 { 55 struct unwind_state state; 56 57 unwind_for_each_frame(&state, current, regs, 0) { 58 if (trace->nr_entries >= trace->max_entries) 59 break; 60 if (trace->skip > 0) 61 trace->skip--; 62 else 63 trace->entries[trace->nr_entries++] = state.ip; 64 } 65 if (trace->nr_entries < trace->max_entries) 66 trace->entries[trace->nr_entries++] = ULONG_MAX; 67 } 68 EXPORT_SYMBOL_GPL(save_stack_trace_regs); 69