1 /* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include <linux/kallsyms.h> 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/sched.h> 10 #include <asm/sysrq.h> 11 12 /* Catch non-i386 SUBARCH's. */ 13 #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) 14 void show_trace(struct task_struct *task, unsigned long * stack) 15 { 16 unsigned long addr; 17 18 if (!stack) { 19 stack = (unsigned long*) &stack; 20 WARN_ON(1); 21 } 22 23 printk(KERN_INFO "Call Trace: \n"); 24 while (((long) stack & (THREAD_SIZE-1)) != 0) { 25 addr = *stack; 26 if (__kernel_text_address(addr)) { 27 printk(KERN_INFO "%08lx: [<%08lx>]", 28 (unsigned long) stack, addr); 29 print_symbol(KERN_CONT " %s", addr); 30 printk(KERN_CONT "\n"); 31 } 32 stack++; 33 } 34 printk(KERN_INFO "\n"); 35 } 36 #endif 37 38 /*Stolen from arch/i386/kernel/traps.c */ 39 static const int kstack_depth_to_print = 24; 40 41 /* This recently started being used in arch-independent code too, as in 42 * kernel/sched.c.*/ 43 void show_stack(struct task_struct *task, unsigned long *esp) 44 { 45 unsigned long *stack; 46 int i; 47 48 if (esp == NULL) { 49 if (task != current && task != NULL) { 50 esp = (unsigned long *) KSTK_ESP(task); 51 } else { 52 esp = (unsigned long *) &esp; 53 } 54 } 55 56 stack = esp; 57 for (i = 0; i < kstack_depth_to_print; i++) { 58 if (kstack_end(stack)) 59 break; 60 if (i && ((i % 8) == 0)) 61 printk(KERN_INFO " "); 62 printk(KERN_CONT "%08lx ", *stack++); 63 } 64 65 show_trace(task, esp); 66 } 67