xref: /linux-6.15/kernel/stacktrace.c (revision bfeda41d)
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 
21*bfeda41dSOmar Sandoval 	for (i = 0; i < trace->nr_entries; i++)
22*bfeda41dSOmar Sandoval 		printk("%*c%pS\n", 1 + spaces, ' ', (void *)trace->entries[i]);
238637c099SIngo Molnar }
248594698eSIngo Molnar EXPORT_SYMBOL_GPL(print_stack_trace);
258637c099SIngo Molnar 
269a92a6ceSJoonsoo Kim int snprint_stack_trace(char *buf, size_t size,
279a92a6ceSJoonsoo Kim 			struct stack_trace *trace, int spaces)
289a92a6ceSJoonsoo Kim {
299a92a6ceSJoonsoo Kim 	int i;
309a92a6ceSJoonsoo Kim 	int generated;
319a92a6ceSJoonsoo Kim 	int total = 0;
329a92a6ceSJoonsoo Kim 
339a92a6ceSJoonsoo Kim 	if (WARN_ON(!trace->entries))
349a92a6ceSJoonsoo Kim 		return 0;
359a92a6ceSJoonsoo Kim 
369a92a6ceSJoonsoo Kim 	for (i = 0; i < trace->nr_entries; i++) {
37*bfeda41dSOmar Sandoval 		generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
38*bfeda41dSOmar Sandoval 				     (void *)trace->entries[i]);
399a92a6ceSJoonsoo Kim 
409a92a6ceSJoonsoo Kim 		total += generated;
419a92a6ceSJoonsoo Kim 
429a92a6ceSJoonsoo Kim 		/* Assume that generated isn't a negative number */
439a92a6ceSJoonsoo Kim 		if (generated >= size) {
449a92a6ceSJoonsoo Kim 			buf += size;
459a92a6ceSJoonsoo Kim 			size = 0;
469a92a6ceSJoonsoo Kim 		} else {
479a92a6ceSJoonsoo Kim 			buf += generated;
489a92a6ceSJoonsoo Kim 			size -= generated;
499a92a6ceSJoonsoo Kim 		}
509a92a6ceSJoonsoo Kim 	}
519a92a6ceSJoonsoo Kim 
529a92a6ceSJoonsoo Kim 	return total;
539a92a6ceSJoonsoo Kim }
549a92a6ceSJoonsoo Kim EXPORT_SYMBOL_GPL(snprint_stack_trace);
559a92a6ceSJoonsoo Kim 
569212ddb5SIngo Molnar /*
57c624d33fSMasami Hiramatsu  * Architectures that do not implement save_stack_trace_tsk or
58c624d33fSMasami Hiramatsu  * save_stack_trace_regs get this weak alias and a once-per-bootup warning
59c624d33fSMasami Hiramatsu  * (whenever this facility is utilized - for example by procfs):
609212ddb5SIngo Molnar  */
619212ddb5SIngo Molnar __weak void
629212ddb5SIngo Molnar save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
639212ddb5SIngo Molnar {
649212ddb5SIngo Molnar 	WARN_ONCE(1, KERN_INFO "save_stack_trace_tsk() not implemented yet.\n");
659212ddb5SIngo Molnar }
66c624d33fSMasami Hiramatsu 
67c624d33fSMasami Hiramatsu __weak void
68c624d33fSMasami Hiramatsu save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
69c624d33fSMasami Hiramatsu {
70c624d33fSMasami Hiramatsu 	WARN_ONCE(1, KERN_INFO "save_stack_trace_regs() not implemented yet.\n");
71c624d33fSMasami Hiramatsu }
72