xref: /linux-6.15/kernel/stacktrace.c (revision 9a92a6ce)
18637c099SIngo Molnar /*
28637c099SIngo Molnar  * kernel/stacktrace.c
38637c099SIngo Molnar  *
48637c099SIngo Molnar  * Stack trace management functions
58637c099SIngo Molnar  *
68637c099SIngo Molnar  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <[email protected]>
78637c099SIngo Molnar  */
88637c099SIngo Molnar #include <linux/sched.h>
99212ddb5SIngo Molnar #include <linux/kernel.h>
109984de1aSPaul Gortmaker #include <linux/export.h>
118637c099SIngo Molnar #include <linux/kallsyms.h>
128637c099SIngo Molnar #include <linux/stacktrace.h>
138637c099SIngo Molnar 
148637c099SIngo Molnar void print_stack_trace(struct stack_trace *trace, int spaces)
158637c099SIngo Molnar {
16a5a242dcSVegard Nossum 	int i;
178637c099SIngo Molnar 
18bfeeeeb9SJohannes Berg 	if (WARN_ON(!trace->entries))
19bfeeeeb9SJohannes Berg 		return;
20bfeeeeb9SJohannes Berg 
218637c099SIngo Molnar 	for (i = 0; i < trace->nr_entries; i++) {
22a5a242dcSVegard Nossum 		printk("%*c", 1 + spaces, ' ');
23a5a242dcSVegard Nossum 		print_ip_sym(trace->entries[i]);
248637c099SIngo Molnar 	}
258637c099SIngo Molnar }
268594698eSIngo Molnar EXPORT_SYMBOL_GPL(print_stack_trace);
278637c099SIngo Molnar 
28*9a92a6ceSJoonsoo Kim int snprint_stack_trace(char *buf, size_t size,
29*9a92a6ceSJoonsoo Kim 			struct stack_trace *trace, int spaces)
30*9a92a6ceSJoonsoo Kim {
31*9a92a6ceSJoonsoo Kim 	int i;
32*9a92a6ceSJoonsoo Kim 	unsigned long ip;
33*9a92a6ceSJoonsoo Kim 	int generated;
34*9a92a6ceSJoonsoo Kim 	int total = 0;
35*9a92a6ceSJoonsoo Kim 
36*9a92a6ceSJoonsoo Kim 	if (WARN_ON(!trace->entries))
37*9a92a6ceSJoonsoo Kim 		return 0;
38*9a92a6ceSJoonsoo Kim 
39*9a92a6ceSJoonsoo Kim 	for (i = 0; i < trace->nr_entries; i++) {
40*9a92a6ceSJoonsoo Kim 		ip = trace->entries[i];
41*9a92a6ceSJoonsoo Kim 		generated = snprintf(buf, size, "%*c[<%p>] %pS\n",
42*9a92a6ceSJoonsoo Kim 				1 + spaces, ' ', (void *) ip, (void *) ip);
43*9a92a6ceSJoonsoo Kim 
44*9a92a6ceSJoonsoo Kim 		total += generated;
45*9a92a6ceSJoonsoo Kim 
46*9a92a6ceSJoonsoo Kim 		/* Assume that generated isn't a negative number */
47*9a92a6ceSJoonsoo Kim 		if (generated >= size) {
48*9a92a6ceSJoonsoo Kim 			buf += size;
49*9a92a6ceSJoonsoo Kim 			size = 0;
50*9a92a6ceSJoonsoo Kim 		} else {
51*9a92a6ceSJoonsoo Kim 			buf += generated;
52*9a92a6ceSJoonsoo Kim 			size -= generated;
53*9a92a6ceSJoonsoo Kim 		}
54*9a92a6ceSJoonsoo Kim 	}
55*9a92a6ceSJoonsoo Kim 
56*9a92a6ceSJoonsoo Kim 	return total;
57*9a92a6ceSJoonsoo Kim }
58*9a92a6ceSJoonsoo Kim EXPORT_SYMBOL_GPL(snprint_stack_trace);
59*9a92a6ceSJoonsoo Kim 
609212ddb5SIngo Molnar /*
61c624d33fSMasami Hiramatsu  * Architectures that do not implement save_stack_trace_tsk or
62c624d33fSMasami Hiramatsu  * save_stack_trace_regs get this weak alias and a once-per-bootup warning
63c624d33fSMasami Hiramatsu  * (whenever this facility is utilized - for example by procfs):
649212ddb5SIngo Molnar  */
659212ddb5SIngo Molnar __weak void
669212ddb5SIngo Molnar save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
679212ddb5SIngo Molnar {
689212ddb5SIngo Molnar 	WARN_ONCE(1, KERN_INFO "save_stack_trace_tsk() not implemented yet.\n");
699212ddb5SIngo Molnar }
70c624d33fSMasami Hiramatsu 
71c624d33fSMasami Hiramatsu __weak void
72c624d33fSMasami Hiramatsu save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
73c624d33fSMasami Hiramatsu {
74c624d33fSMasami Hiramatsu 	WARN_ONCE(1, KERN_INFO "save_stack_trace_regs() not implemented yet.\n");
75c624d33fSMasami Hiramatsu }
76