summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/traps.c121
1 files changed, 73 insertions, 48 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 40c8ba492..f3f6be7a1 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.15 1998/08/25 09:14:43 ralf Exp $
+/* $Id: traps.c,v 1.16 1998/10/14 23:40:44 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -6,6 +6,7 @@
*
* Copyright 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
* Modified for R3000 by Paul M. Antoine, 1995, 1996
+ * Complete output from die() by Ulf Carlsson, 1998
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -80,50 +81,61 @@ int kstack_depth_to_print = 24;
* This routine abuses get_user()/put_user() to reference pointers
* with at least a bit of error checking ...
*/
-void show_registers(char * str, struct pt_regs * regs, long err)
+void show_stack(unsigned int *sp)
{
- int i;
- int *stack;
- u32 *sp, *pc, addr, module_start, module_end;
- extern char start_kernel, _etext;
+ int i;
+ unsigned int *stack;
- sp = (u32 *)regs->regs[29];
- pc = (u32 *)regs->cp0_epc;
+ stack = sp;
+ i = 0;
- show_regs(regs);
+ printk("Stack:");
+ while ((unsigned long) stack & (PAGE_SIZE - 1)) {
+ unsigned long stackdata;
- /*
- * Dump the stack
- */
- printk("Process %s (pid: %ld, stackpage=%08lx)\nStack: ",
- current->comm, current->pid, (unsigned long)current);
- for(i=0;i<5;i++)
- printk("%08x ", *sp++);
- stack = (int *) sp;
+ if (__get_user(stackdata, stack++)) {
+ printk(" (Bad stack address)");
+ break;
+ }
- for(i=0; i < kstack_depth_to_print; i++) {
- unsigned int stackdata;
+ printk(" %08lx", stackdata);
- if (((u32) stack & (PAGE_SIZE -1)) == 0)
- break;
- if (i && ((i % 8) == 0))
- printk("\n ");
- if (get_user(stackdata, stack++) < 0) {
- printk("(Bad stack address)");
+ if (++i > 40) {
+ printk(" ...");
break;
}
- printk("%08x ", stackdata);
+
+ if (i % 8 == 0)
+ printk("\n ");
}
- printk("\nCall Trace: ");
- stack = (int *)sp;
- i = 1;
+}
+
+void show_trace(unsigned int *sp)
+{
+ int i;
+ unsigned int *stack;
+ unsigned long kernel_start, kernel_end;
+ unsigned long module_start, module_end;
+ extern char _stext, _etext;
+
+ stack = sp;
+ i = 0;
+
+ kernel_start = (unsigned long) &_stext;
+ kernel_end = (unsigned long) &_etext;
module_start = VMALLOC_START;
module_end = module_start + MODULE_RANGE;
- while (((unsigned long)stack & (PAGE_SIZE -1)) != 0) {
- if (get_user(addr, stack++) < 0) {
- printk("(Bad address)\n");
+
+ printk("\nCall Trace:");
+
+ while ((unsigned long) stack & (PAGE_SIZE -1)) {
+ unsigned long addr;
+
+ if (__get_user(addr, stack++)) {
+ printk(" (Bad stack address)\n");
break;
}
+
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
@@ -132,26 +144,33 @@ void show_registers(char * str, struct pt_regs * regs, long err)
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
- if (((addr >= (u32) &start_kernel) &&
- (addr <= (u32) &_etext)) ||
- ((addr >= module_start) && (addr <= module_end))) {
- if (i && ((i % 8) == 0))
- printk("\n ");
- printk("%08x ", addr);
- i++;
+
+ if ((addr >= kernel_start && addr < kernel_end) ||
+ (addr >= module_start && addr < module_end)) {
+
+ printk(" [<%08lx>]", addr);
+ if (++i > 40) {
+ printk(" ...");
+ break;
+ }
}
}
+}
+
+void show_code(unsigned int *pc)
+{
+ long i;
- printk("\nCode : ");
- if ((KSEGX(pc) == KSEG0 || KSEGX(pc) == KSEG1) &&
- (((unsigned long) pc & 3) == 0))
- {
- for(i=0;i<5;i++)
- printk("%08x ", *pc++);
- printk("\n");
+ printk("\nCode:");
+
+ for(i = -3 ; i < 6 ; i++) {
+ unsigned long insn;
+ if (__get_user(insn, pc + i)) {
+ printk(" (Bad address in epc)\n");
+ break;
+ }
+ printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
}
- else
- printk("(Bad address in epc)\n");
}
void die(const char * str, struct pt_regs * regs, unsigned long err)
@@ -162,6 +181,12 @@ void die(const char * str, struct pt_regs * regs, unsigned long err)
console_verbose();
printk("%s: %04lx\n", str, err & 0xffff);
show_regs(regs);
+ printk("Process %s (pid: %ld, stackpage=%08lx)\n",
+ current->comm, current->pid, (unsigned long) current);
+ show_stack((unsigned int *) regs->regs[29]);
+ show_trace((unsigned int *) regs->regs[29]);
+ show_code((unsigned int *) regs->cp0_epc);
+ printk("\n");
do_exit(SIGSEGV);
}