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