1 /* 2 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2007-2009 PetaLogix 4 * Copyright (C) 2006 Atmark Techno, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/kallsyms.h> 13 #include <linux/module.h> 14 #include <linux/sched.h> 15 #include <linux/debug_locks.h> 16 17 #include <asm/exceptions.h> 18 #include <asm/system.h> 19 20 void trap_init(void) 21 { 22 __enable_hw_exceptions(); 23 } 24 25 void __bad_xchg(volatile void *ptr, int size) 26 { 27 printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", 28 __builtin_return_address(0), ptr, size); 29 BUG(); 30 } 31 EXPORT_SYMBOL(__bad_xchg); 32 33 static int kstack_depth_to_print = 24; 34 35 static int __init kstack_setup(char *s) 36 { 37 kstack_depth_to_print = strict_strtoul(s, 0, 0); 38 39 return 1; 40 } 41 __setup("kstack=", kstack_setup); 42 43 void show_trace(struct task_struct *task, unsigned long *stack) 44 { 45 unsigned long addr; 46 47 if (!stack) 48 stack = (unsigned long *)&stack; 49 50 printk(KERN_NOTICE "Call Trace: "); 51 #ifdef CONFIG_KALLSYMS 52 printk(KERN_NOTICE "\n"); 53 #endif 54 while (!kstack_end(stack)) { 55 addr = *stack++; 56 /* 57 * If the address is either in the text segment of the 58 * kernel, or in the region which contains vmalloc'ed 59 * memory, it *may* be the address of a calling 60 * routine; if so, print it so that someone tracing 61 * down the cause of the crash will be able to figure 62 * out the call path that was taken. 63 */ 64 if (kernel_text_address(addr)) 65 print_ip_sym(addr); 66 } 67 printk(KERN_NOTICE "\n"); 68 69 if (!task) 70 task = current; 71 72 debug_show_held_locks(task); 73 } 74 75 void show_stack(struct task_struct *task, unsigned long *sp) 76 { 77 unsigned long *stack; 78 int i; 79 80 if (sp == NULL) { 81 if (task) 82 sp = (unsigned long *) ((struct thread_info *) 83 (task->stack))->cpu_context.r1; 84 else 85 sp = (unsigned long *)&sp; 86 } 87 88 stack = sp; 89 90 printk(KERN_INFO "\nStack:\n "); 91 92 for (i = 0; i < kstack_depth_to_print; i++) { 93 if (kstack_end(sp)) 94 break; 95 if (i && ((i % 8) == 0)) 96 printk("\n "); 97 printk("%08lx ", *sp++); 98 } 99 printk("\n"); 100 show_trace(task, stack); 101 } 102 103 void dump_stack(void) 104 { 105 show_stack(NULL, NULL); 106 } 107 EXPORT_SYMBOL(dump_stack); 108