1 /* 2 * Copyright (C) 1991, 1992 Linus Torvalds 3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 4 * Copyright (C) 2009 Matt Fleming 5 */ 6 #include <linux/kallsyms.h> 7 #include <linux/ftrace.h> 8 #include <linux/debug_locks.h> 9 #include <asm/unwinder.h> 10 #include <asm/stacktrace.h> 11 12 void printk_address(unsigned long address, int reliable) 13 { 14 printk(" [<%p>] %s%pS\n", (void *) address, 15 reliable ? "" : "? ", (void *) address); 16 } 17 18 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 19 static void 20 print_ftrace_graph_addr(unsigned long addr, void *data, 21 const struct stacktrace_ops *ops, 22 struct thread_info *tinfo, int *graph) 23 { 24 struct task_struct *task = tinfo->task; 25 unsigned long ret_addr; 26 int index = task->curr_ret_stack; 27 28 if (addr != (unsigned long)return_to_handler) 29 return; 30 31 if (!task->ret_stack || index < *graph) 32 return; 33 34 index -= *graph; 35 ret_addr = task->ret_stack[index].ret; 36 37 ops->address(data, ret_addr, 1); 38 39 (*graph)++; 40 } 41 #else 42 static inline void 43 print_ftrace_graph_addr(unsigned long addr, void *data, 44 const struct stacktrace_ops *ops, 45 struct thread_info *tinfo, int *graph) 46 { } 47 #endif 48 49 void 50 stack_reader_dump(struct task_struct *task, struct pt_regs *regs, 51 unsigned long *sp, const struct stacktrace_ops *ops, 52 void *data) 53 { 54 struct thread_info *context; 55 int graph = 0; 56 57 context = (struct thread_info *) 58 ((unsigned long)sp & (~(THREAD_SIZE - 1))); 59 60 while (!kstack_end(sp)) { 61 unsigned long addr = *sp++; 62 63 if (__kernel_text_address(addr)) { 64 ops->address(data, addr, 1); 65 66 print_ftrace_graph_addr(addr, data, ops, 67 context, &graph); 68 } 69 } 70 } 71 72 static void 73 print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) 74 { 75 printk(data); 76 print_symbol(msg, symbol); 77 printk("\n"); 78 } 79 80 static void print_trace_warning(void *data, char *msg) 81 { 82 printk("%s%s\n", (char *)data, msg); 83 } 84 85 static int print_trace_stack(void *data, char *name) 86 { 87 printk("%s <%s> ", (char *)data, name); 88 return 0; 89 } 90 91 /* 92 * Print one address/symbol entries per line. 93 */ 94 static void print_trace_address(void *data, unsigned long addr, int reliable) 95 { 96 printk(data); 97 printk_address(addr, reliable); 98 } 99 100 static const struct stacktrace_ops print_trace_ops = { 101 .warning = print_trace_warning, 102 .warning_symbol = print_trace_warning_symbol, 103 .stack = print_trace_stack, 104 .address = print_trace_address, 105 }; 106 107 void show_trace(struct task_struct *tsk, unsigned long *sp, 108 struct pt_regs *regs) 109 { 110 if (regs && user_mode(regs)) 111 return; 112 113 printk("\nCall trace:\n"); 114 115 unwind_stack(tsk, regs, sp, &print_trace_ops, ""); 116 117 printk("\n"); 118 119 if (!tsk) 120 tsk = current; 121 122 debug_show_held_locks(tsk); 123 } 124