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 static unsigned long kstack_depth_to_print = 24; 26 27 static int __init kstack_setup(char *s) 28 { 29 return !strict_strtoul(s, 0, &kstack_depth_to_print); 30 } 31 __setup("kstack=", kstack_setup); 32 33 void show_trace(struct task_struct *task, unsigned long *stack) 34 { 35 unsigned long addr; 36 37 if (!stack) 38 stack = (unsigned long *)&stack; 39 40 printk(KERN_NOTICE "Call Trace: "); 41 #ifdef CONFIG_KALLSYMS 42 printk(KERN_NOTICE "\n"); 43 #endif 44 while (!kstack_end(stack)) { 45 addr = *stack++; 46 /* 47 * If the address is either in the text segment of the 48 * kernel, or in the region which contains vmalloc'ed 49 * memory, it *may* be the address of a calling 50 * routine; if so, print it so that someone tracing 51 * down the cause of the crash will be able to figure 52 * out the call path that was taken. 53 */ 54 if (kernel_text_address(addr)) 55 print_ip_sym(addr); 56 } 57 printk(KERN_NOTICE "\n"); 58 59 if (!task) 60 task = current; 61 62 debug_show_held_locks(task); 63 } 64 65 void show_stack(struct task_struct *task, unsigned long *sp) 66 { 67 unsigned long *stack; 68 int i; 69 70 if (sp == NULL) { 71 if (task) 72 sp = (unsigned long *) ((struct thread_info *) 73 (task->stack))->cpu_context.r1; 74 else 75 sp = (unsigned long *)&sp; 76 } 77 78 stack = sp; 79 80 printk(KERN_INFO "\nStack:\n "); 81 82 for (i = 0; i < kstack_depth_to_print; i++) { 83 if (kstack_end(sp)) 84 break; 85 if (i && ((i % 8) == 0)) 86 printk("\n "); 87 printk("%08lx ", *sp++); 88 } 89 printk("\n"); 90 show_trace(task, stack); 91 } 92 93 void dump_stack(void) 94 { 95 show_stack(NULL, NULL); 96 } 97 EXPORT_SYMBOL(dump_stack); 98