Commit f6054e21 authored by Sebastian Siewior's avatar Sebastian Siewior Committed by Linus Torvalds

m68knommu: add pretty back strace

With this patch and
 CONFIG_FRAME_POINTER=y
 CONFIG_KALLSYMS=y
The backtrace shows resolved function names and their numeric
address.
Signed-off-by: default avatarSebastian Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarGreg Ungerer <gerg@uclinux.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 008150f5
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/fpu.h> #include <asm/fpu.h>
...@@ -102,56 +103,47 @@ asmlinkage void buserr_c(struct frame *fp) ...@@ -102,56 +103,47 @@ asmlinkage void buserr_c(struct frame *fp)
force_sig(SIGSEGV, current); force_sig(SIGSEGV, current);
} }
int kstack_depth_to_print = 48; int kstack_depth_to_print = 48;
void show_stack(struct task_struct *task, unsigned long *stack) static void __show_stack(struct task_struct *task, unsigned long *stack)
{ {
unsigned long *endstack, addr; unsigned long *endstack, addr;
extern char _start, _etext; unsigned long *last_stack;
int i; int i;
if (!stack) { if (!stack)
if (task)
stack = (unsigned long *)task->thread.ksp; stack = (unsigned long *)task->thread.ksp;
else
stack = (unsigned long *)&stack;
}
addr = (unsigned long) stack; addr = (unsigned long) stack;
endstack = (unsigned long *) PAGE_ALIGN(addr); endstack = (unsigned long *) PAGE_ALIGN(addr);
printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack); printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) { for (i = 0; i < kstack_depth_to_print; i++) {
if (stack + 1 > endstack) if (stack + 1 + i > endstack)
break; break;
if (i % 8 == 0) if (i % 8 == 0)
printk("\n" KERN_EMERG " "); printk("\n" KERN_EMERG " ");
printk(" %08lx", *stack++); printk(" %08lx", *(stack + i));
} }
printk("\n"); printk("\n");
printk(KERN_EMERG "Call Trace:"); #ifdef CONFIG_FRAME_POINTER
i = 0; printk(KERN_EMERG "Call Trace:\n");
while (stack + 1 <= endstack) {
addr = *stack++; last_stack = stack - 1;
/* while (stack <= endstack && stack > last_stack) {
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed addr = *(stack + 1);
* memory, it *may* be the address of a calling printk(KERN_EMERG " [%08lx] ", addr);
* routine; if so, print it so that someone tracing print_symbol(KERN_CONT "%s\n", addr);
* down the cause of the crash will be able to figure
* out the call path that was taken. last_stack = stack;
*/ stack = (unsigned long *)*stack;
if (((addr >= (unsigned long) &_start) &&
(addr <= (unsigned long) &_etext))) {
if (i % 4 == 0)
printk("\n" KERN_EMERG " ");
printk(" [<%08lx>]", addr);
i++;
}
} }
printk("\n"); printk("\n");
#else
printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic call trace\n");
#endif
} }
void bad_super_trap(struct frame *fp) void bad_super_trap(struct frame *fp)
...@@ -298,19 +290,47 @@ asmlinkage void set_esp0(unsigned long ssp) ...@@ -298,19 +290,47 @@ asmlinkage void set_esp0(unsigned long ssp)
current->thread.esp0 = ssp; current->thread.esp0 = ssp;
} }
/* /*
* The architecture-independent backtrace generator * The architecture-independent backtrace generator
*/ */
void dump_stack(void) void dump_stack(void)
{ {
unsigned long stack; /*
* We need frame pointers for this little trick, which works as follows:
*
* +------------+ 0x00
* | Next SP | -> 0x0c
* +------------+ 0x04
* | Caller |
* +------------+ 0x08
* | Local vars | -> our stack var
* +------------+ 0x0c
* | Next SP | -> 0x18, that is what we pass to show_stack()
* +------------+ 0x10
* | Caller |
* +------------+ 0x14
* | Local vars |
* +------------+ 0x18
* | ... |
* +------------+
*/
show_stack(current, &stack); unsigned long *stack;
}
stack = (unsigned long *)&stack;
stack++;
__show_stack(current, stack);
}
EXPORT_SYMBOL(dump_stack); EXPORT_SYMBOL(dump_stack);
void show_stack(struct task_struct *task, unsigned long *stack)
{
if (!stack && !task)
dump_stack();
else
__show_stack(task, stack);
}
#ifdef CONFIG_M68KFPU_EMU #ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpemu_signal(int signal, int code, void *addr) asmlinkage void fpemu_signal(int signal, int code, void *addr)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment