1 /* 2 * Copyright (C) 1991, 1992 Linus Torvalds 3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 4 */ 5 #include <linux/kallsyms.h> 6 #include <linux/kprobes.h> 7 #include <linux/uaccess.h> 8 #include <linux/utsname.h> 9 #include <linux/hardirq.h> 10 #include <linux/kdebug.h> 11 #include <linux/module.h> 12 #include <linux/ptrace.h> 13 #include <linux/kexec.h> 14 #include <linux/bug.h> 15 #include <linux/nmi.h> 16 #include <linux/sysfs.h> 17 18 #include <asm/stacktrace.h> 19 20 #include "dumpstack.h" 21 22 void dump_trace(struct task_struct *task, struct pt_regs *regs, 23 unsigned long *stack, unsigned long bp, 24 const struct stacktrace_ops *ops, void *data) 25 { 26 int graph = 0; 27 28 if (!task) 29 task = current; 30 31 if (!stack) { 32 unsigned long dummy; 33 stack = &dummy; 34 if (task && task != current) 35 stack = (unsigned long *)task->thread.sp; 36 } 37 38 #ifdef CONFIG_FRAME_POINTER 39 if (!bp) { 40 if (task == current) { 41 /* Grab bp right from our regs */ 42 get_bp(bp); 43 } else { 44 /* bp is the last reg pushed by switch_to */ 45 bp = *(unsigned long *) task->thread.sp; 46 } 47 } 48 #endif 49 50 for (;;) { 51 struct thread_info *context; 52 53 context = (struct thread_info *) 54 ((unsigned long)stack & (~(THREAD_SIZE - 1))); 55 bp = print_context_stack(context, stack, bp, ops, 56 data, NULL, &graph); 57 58 stack = (unsigned long *)context->previous_esp; 59 if (!stack) 60 break; 61 if (ops->stack(data, "IRQ") < 0) 62 break; 63 touch_nmi_watchdog(); 64 } 65 } 66 EXPORT_SYMBOL(dump_trace); 67 68 void 69 show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, 70 unsigned long *sp, unsigned long bp, char *log_lvl) 71 { 72 unsigned long *stack; 73 int i; 74 75 if (sp == NULL) { 76 if (task) 77 sp = (unsigned long *)task->thread.sp; 78 else 79 sp = (unsigned long *)&sp; 80 } 81 82 stack = sp; 83 for (i = 0; i < kstack_depth_to_print; i++) { 84 if (kstack_end(stack)) 85 break; 86 if (i && ((i % STACKSLOTS_PER_LINE) == 0)) 87 printk("\n%s", log_lvl); 88 printk(" %08lx", *stack++); 89 touch_nmi_watchdog(); 90 } 91 printk("\n"); 92 show_trace_log_lvl(task, regs, sp, bp, log_lvl); 93 } 94 95 96 void show_registers(struct pt_regs *regs) 97 { 98 int i; 99 100 print_modules(); 101 __show_regs(regs, 0); 102 103 printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", 104 TASK_COMM_LEN, current->comm, task_pid_nr(current), 105 current_thread_info(), current, task_thread_info(current)); 106 /* 107 * When in-kernel, we also print out the stack and code at the 108 * time of the fault.. 109 */ 110 if (!user_mode_vm(regs)) { 111 unsigned int code_prologue = code_bytes * 43 / 64; 112 unsigned int code_len = code_bytes; 113 unsigned char c; 114 u8 *ip; 115 116 printk(KERN_EMERG "Stack:\n"); 117 show_stack_log_lvl(NULL, regs, ®s->sp, 118 0, KERN_EMERG); 119 120 printk(KERN_EMERG "Code: "); 121 122 ip = (u8 *)regs->ip - code_prologue; 123 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { 124 /* try starting at IP */ 125 ip = (u8 *)regs->ip; 126 code_len = code_len - code_prologue + 1; 127 } 128 for (i = 0; i < code_len; i++, ip++) { 129 if (ip < (u8 *)PAGE_OFFSET || 130 probe_kernel_address(ip, c)) { 131 printk(" Bad EIP value."); 132 break; 133 } 134 if (ip == (u8 *)regs->ip) 135 printk("<%02x> ", c); 136 else 137 printk("%02x ", c); 138 } 139 } 140 printk("\n"); 141 } 142 143 int is_valid_bugaddr(unsigned long ip) 144 { 145 unsigned short ud2; 146 147 if (ip < PAGE_OFFSET) 148 return 0; 149 if (probe_kernel_address((unsigned short *)ip, ud2)) 150 return 0; 151 152 return ud2 == 0x0b0f; 153 } 154 155