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