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