[parisc-linux-cvs] linux tausq
Randolph Chung
Randolph Chung <randolph@tausq.org>
Fri, 15 Nov 2002 22:49:45 -0800
> -pa4
> updated the stack dumping code. this is a bit similar, but more primitive, than what we have in 2.5 now
not too pretty, but it works. this does not (yet) have the KALLSYMS
support that is in 2.5.
randolph
Index: arch/parisc/vmlinux.lds
===================================================================
RCS file: /var/cvs/linux/arch/parisc/vmlinux.lds,v
retrieving revision 1.9
diff -u -p -r1.9 vmlinux.lds
--- arch/parisc/vmlinux.lds 6 Sep 2001 09:44:11 -0000 1.9
+++ arch/parisc/vmlinux.lds 16 Nov 2002 06:14:42 -0000
@@ -14,12 +14,12 @@ SECTIONS
*(.gnu.warning)
} = 0
+ _etext = .; /* End of text section */
+
. = ALIGN(16);
.rodata : { *(.rodata) *(.rodata.*) }
.kstrtab : { *(.kstrtab) }
- _etext = .; /* End of text section */
-
.data BLOCK(8192) : { /* Data without special */
data_start = .;
*(.data)
Index: arch/parisc/vmlinux64.lds
===================================================================
RCS file: /var/cvs/linux/arch/parisc/vmlinux64.lds,v
retrieving revision 1.2
diff -u -p -r1.2 vmlinux64.lds
--- arch/parisc/vmlinux64.lds 6 Sep 2001 09:44:11 -0000 1.2
+++ arch/parisc/vmlinux64.lds 16 Nov 2002 06:14:42 -0000
@@ -15,12 +15,12 @@ SECTIONS
*(.gnu.warning)
} = 0
+ _etext = .; /* End of text section */
+
. = ALIGN(16);
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
- _etext = .; /* End of text section */
-
.data BLOCK(8192) : { /* Data without special */
data_start = .;
*(.data)
Index: arch/parisc/kernel/traps.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/traps.c,v
retrieving revision 1.68
diff -u -p -r1.68 traps.c
--- arch/parisc/kernel/traps.c 13 Nov 2002 20:03:41 -0000 1.68
+++ arch/parisc/kernel/traps.c 16 Nov 2002 06:14:42 -0000
@@ -18,6 +18,7 @@
#include <linux/ptrace.h>
#include <linux/timer.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
@@ -38,14 +39,6 @@
#include "../math-emu/math-emu.h" /* for handle_fpe() */
-#ifdef CONFIG_KWDB
-#include <kdb/break.h> /* for BI2_KGDB_GDB */
-#include <kdb/kgdb_types.h> /* for __() */
-#include <kdb/save_state.h> /* for struct save_state */
-#include <kdb/kgdb_machine.h> /* for pt_regs_to_ssp and ssp_to_pt_regs */
-#include <kdb/trap.h> /* for I_BRK_INST */
-#endif /* CONFIG_KWDB */
-
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
/* dumped to the console via printk) */
@@ -67,6 +60,99 @@ static int printbinary(char *buf, unsign
#define RFMT "%08lx"
#endif
+static int kstack_depth_to_print = 24;
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(unsigned long addr)
+{
+#ifdef CONFIG_MODULES
+ int retval = 0;
+ struct module *mod;
+#endif
+ extern char _stext, _etext;
+
+ if (addr >= (unsigned long) &_stext &&
+ addr <= (unsigned long) &_etext)
+ return 1;
+
+#ifdef CONFIG_MODULES
+ for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+ /* mod_bound tests for addr being inside the vmalloc'ed
+ * module area. Of course it'd be better to test only
+ * for the .text subset... */
+ if (mod_bound(addr, 0, mod)) {
+ retval = 1;
+ break;
+ }
+ }
+ return retval;
+#endif
+}
+
+
+void show_trace(unsigned long * stack)
+{
+ unsigned long *startstack;
+ unsigned long addr;
+ int i;
+
+ startstack = (unsigned long *)((unsigned long)stack & ~(THREAD_SIZE - 1));
+ i = 1;
+ printk("Kernel addresses on the stack:\n");
+ while (stack >= startstack) {
+ addr = *stack--;
+ if (kernel_text_address(addr)) {
+ printk(" [<" RFMT ">] ", addr);
+ if ((i & 0x03) == 0)
+ printk("\n");
+ i++;
+ }
+ }
+ printk("\n");
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+ show_trace((unsigned long *)tsk->thread.regs.ksp);
+}
+
+void show_stack(unsigned long * sp)
+{
+ unsigned long *stack;
+ int i;
+
+ /*
+ * debugging aid: "show_stack(NULL);" prints the
+ * back trace for this cpu.
+ */
+ if (sp==NULL)
+ sp = (unsigned long*)&sp;
+
+ stack = sp;
+ printk("\n" KERN_CRIT "Stack Dump:\n");
+ printk(KERN_CRIT " " RFMT ": ", (unsigned long) stack);
+ for (i=0; i < kstack_depth_to_print; i++) {
+ if (((long) stack & (THREAD_SIZE-1)) == 0)
+ break;
+ if (i && ((i & 0x03) == 0))
+ printk("\n" KERN_CRIT " " RFMT ": ",
+ (unsigned long) stack);
+ printk(RFMT " ", *stack--);
+ }
+ printk("\n" KERN_CRIT "\n");
+ show_trace(sp);
+}
+
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+ show_stack(0);
+}
+
+
void show_regs(struct pt_regs *regs)
{
int i;
@@ -122,84 +208,6 @@ void show_regs(struct pt_regs *regs)
}
-static void parisc_dump_stack(unsigned long from, unsigned long to, int istackflag)
-{
- unsigned int *fromptr;
- unsigned int *toptr;
-
- fromptr = (unsigned int *)from;
- toptr = (unsigned int *)to;
-
- printk("\n");
- printk(KERN_CRIT "Dumping %sStack from 0x%p to 0x%p:\n",
- istackflag ? "Interrupt " : "",
- fromptr, toptr);
-
- while (fromptr < toptr) {
- printk(KERN_CRIT "%04lx %08x %08x %08x %08x %08x %08x %08x %08x\n",
- ((unsigned long)fromptr) & 0xffff,
- fromptr[0], fromptr[1], fromptr[2], fromptr[3],
- fromptr[4], fromptr[5], fromptr[6], fromptr[7]);
- fromptr += 8;
- }
-}
-
-
-void show_stack(struct pt_regs *regs)
-{
-#if 1
- /* If regs->sr[7] == 0, we are on a kernel stack */
- if (regs->sr[7] == 0) {
-
- unsigned long sp = regs->gr[30];
- unsigned long cr30;
- unsigned long cr31;
- unsigned long stack_start;
- struct pt_regs *int_regs;
-
- cr30 = mfctl(30);
- cr31 = mfctl(31);
- stack_start = sp & ~(ISTACK_SIZE - 1);
- if (stack_start == cr31) {
- /*
- * We are on the interrupt stack, get the stack
- * pointer from the first pt_regs structure on
- * the interrupt stack, so we can dump the task
- * stack first.
- */
-
- int_regs = (struct pt_regs *)cr31;
- sp = int_regs->gr[30];
- stack_start = sp & ~(INIT_TASK_SIZE - 1);
- if (stack_start != cr30) {
- printk(KERN_CRIT "WARNING! Interrupt-Stack pointer and cr30 do not correspond!\n");
- printk(KERN_CRIT "Dumping virtual address stack instead\n");
- parisc_dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0);
- } else {
- parisc_dump_stack(stack_start, sp, 0);
- };
-
- printk("\n\n" KERN_DEBUG "Registers at Interrupt:\n");
- show_regs(int_regs);
-
- /* Now dump the interrupt stack */
-
- sp = regs->gr[30];
- stack_start = sp & ~(ISTACK_SIZE - 1);
- parisc_dump_stack(stack_start,sp,1);
- }
- else
- {
- /* Stack Dump! */
- printk(KERN_CRIT "WARNING! Stack pointer and cr30 do not correspond!\n");
- printk(KERN_CRIT "Dumping virtual address stack instead\n");
- parisc_dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0);
- }
- }
-#endif
-}
-
-
void die_if_kernel(char *str, struct pt_regs *regs, long err)
{
if (user_mode(regs)) {
@@ -261,9 +269,6 @@ void handle_gdb_break(struct pt_regs *re
void handle_break(unsigned iir, struct pt_regs *regs)
{
struct siginfo si;
-#ifdef CONFIG_KWDB
- struct save_state ssp;
-#endif /* CONFIG_KWDB */
switch(iir) {
case 0x00:
@@ -286,26 +291,6 @@ void handle_break(unsigned iir, struct p
handle_gdb_break(regs, TRAP_BRKPT);
break;
-#ifdef CONFIG_KWDB
- case KGDB_BREAK_INSN:
- mtctl(0, 15);
- pt_regs_to_ssp(regs, &ssp);
- kgdb_trap(I_BRK_INST, &ssp, 1);
- ssp_to_pt_regs(&ssp, regs);
- break;
-
- case KGDB_INIT_BREAK_INSN:
- mtctl(0, 15);
- pt_regs_to_ssp(regs, &ssp);
- kgdb_trap(I_BRK_INST, &ssp, 1);
- ssp_to_pt_regs(&ssp, regs);
-
- /* Advance pcoq to skip break */
- regs->iaoq[0] = regs->iaoq[1];
- regs->iaoq[1] += 4;
- break;
-#endif /* CONFIG_KWDB */
-
default:
#ifdef PRINT_USER_FAULTS
printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",
@@ -336,19 +321,6 @@ static void default_trap(int code, struc
void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap;
-#ifdef CONFIG_KWDB
-int debug_call (void)
-{
- printk (KERN_DEBUG "Debug call.\n");
- return 0;
-}
-
-int debug_call_leaf (void)
-{
- return 0;
-}
-#endif /* CONFIG_KWDB */
-
void transfer_pim_to_trap_frame(struct pt_regs *regs)
{
@@ -458,7 +430,7 @@ void parisc_terminate(char *msg, struct
break;
}
- show_stack(regs);
+ show_stack((unsigned long *)regs->gr[30]);
printk("\n");
printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n",
@@ -482,9 +454,6 @@ void handle_interruption(int code, struc
unsigned long fault_address = 0;
unsigned long fault_space = 0;
struct siginfo si;
-#ifdef CONFIG_KWDB
- struct save_state ssp;
-#endif /* CONFIG_KWDB */
if (code == 1)
pdc_console_restart(); /* switch back to pdc if HPMC */
@@ -648,7 +617,6 @@ void handle_interruption(int code, struc
case 25:
/* Taken branch trap */
-#ifndef CONFIG_KWDB
regs->gr[0] &= ~PSW_T;
if (regs->iasq[0])
handle_gdb_break(regs, TRAP_BRANCH);
@@ -656,19 +624,6 @@ void handle_interruption(int code, struc
* run.
*/
return;
-#else
- /* Kernel debugger: */
- mtctl(0, 15);
- pt_regs_to_ssp(regs, &ssp);
- kgdb_trap(I_TAKEN_BR, &ssp, 1);
- ssp_to_pt_regs(&ssp, regs);
-
- /* FIXME: Should this break without setting fault_address
- and fault_space? They are required for the dump later on.
- (Carlos) */
-
- break;
-#endif /* CONFIG_KWDB */
case 7:
/* Instruction access rights */
@@ -773,17 +728,7 @@ void handle_interruption(int code, struc
}
}
-#ifdef CONFIG_KWDB
- debug_call_leaf ();
-#endif /* CONFIG_KWDB */
-
do_page_fault(regs, code, fault_address);
-}
-
-
-void show_trace_task(struct task_struct *tsk)
-{
- BUG();
}
Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.363
diff -u -p -r1.363 Makefile
--- Makefile 16 Nov 2002 06:10:45 -0000 1.363
+++ Makefile 16 Nov 2002 06:14:42 -0000
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 20
-EXTRAVERSION = -rc1-pa3
+EXTRAVERSION = -rc1-pa4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)