[parisc-linux] [PATCH] [PARISC] Clean up syslog output of

Helge Deller deller at gmx.de
Fri Jul 20 15:40:39 MDT 2007


On Sunday 15 July 2007, Randolph Chung wrote:
> > I find the dumps useful.  While in most cases gdb is necessary
> > to fix bugs, it's not 100 % reliable when used to examine core
> > dumps (sorry Randolph).  The getdents bug that I tracked down
> > a few weeks ago was a case in point.
> 
> I agree the dumps are a useful tool in addition to gdb; [....]

Ok, here is an updated patch.
As requested by you I kept the register dump and in addition added full 
string table of the interrupts/traps.

New example:
a.out(1876): Data TLB miss fault/Data page fault (trap #15) for addr 0x0000aabb at ip=0x000105c4
<here comes the full register dump>

Please test.

Helge
______________________
Changes:
- some minor code path cleanups (const strings, drop unneeded return values)
- converted all traps to the form <application>(<pid>): <type_of_crash> (<crash_id>) ...
- use instruction_pointer() macro instead of "regs->iaoq[0] & ~3" 
- mark parisc_terminate() with __noreturn
- added interruption/trap description table

Signed-off-by: Helge Deller <deller at gmx.de>

diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index bbf029a..0f71d23 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -51,7 +51,7 @@
 DEFINE_SPINLOCK(pa_dbit_lock);
 #endif
 
-static int printbinary(char *buf, unsigned long x, int nbits)
+static void printbinary(char *buf, unsigned long x, int nbits)
 {
 	unsigned long mask = 1UL << (nbits - 1);
 	while (mask != 0) {
@@ -59,8 +59,6 @@ static int printbinary(char *buf, unsigned long x, int nbits)
 		mask >>= 1;
 	}
 	*buf = '\0';
-
-	return nbits;
 }
 
 #ifdef CONFIG_64BIT
@@ -75,7 +73,7 @@ static int printbinary(char *buf, unsigned long x, int nbits)
 		lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1],		\
 		(r)[(x)+2], (r)[(x)+3])
 
-static void print_gr(char *level, struct pt_regs *regs)
+static void print_gr(const char *level, struct pt_regs *regs)
 {
 	int i;
 	char buf[64];
@@ -89,7 +87,7 @@ static void print_gr(char *level, struct pt_regs *regs)
 		PRINTREGS(level, regs->gr, "r", RFMT, i);
 }
 
-static void print_fr(char *level, struct pt_regs *regs)
+static void print_fr(const char *level, struct pt_regs *regs)
 {
 	int i;
 	char buf[64];
@@ -119,7 +117,7 @@ static void print_fr(char *level, struct pt_regs *regs)
 void show_regs(struct pt_regs *regs)
 {
 	int i;
-	char *level;
+	const char *level;
 	unsigned long cr30, cr31;
 
 	level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
@@ -212,16 +210,16 @@ int is_valid_bugaddr(unsigned long iaoq)
 	return 1;
 }
 
-void die_if_kernel(char *str, struct pt_regs *regs, long err)
+void die_if_kernel(const char *str, struct pt_regs *regs, long err)
 {
 	if (user_mode(regs)) {
 		if (err == 0)
 			return; /* STFU */
 
-		printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
-			current->comm, current->pid, str, err, regs->iaoq[0]);
 #ifdef PRINT_USER_FAULTS
-		/* XXX for debugging only */
+		printk(KERN_CRIT "%s(%d): %s (code %ld) at " RFMT "\n",
+			current->comm, current->pid, str, err, 
+			instruction_pointer(regs));
 		show_regs(regs);
 #endif
 		return;
@@ -251,7 +249,7 @@ KERN_CRIT "                     ||     ||\n");
 		pdc_console_restart();
 	
 	if (err)
-		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
+		printk(KERN_CRIT "%s(%d): %s (code %ld)\n",
 			current->comm, current->pid, str, err);
 
 	/* Wot's wrong wif bein' racy? */
@@ -292,7 +290,7 @@ static void handle_gdb_break(struct pt_regs *regs, int wot)
 	si.si_signo = SIGTRAP;
 	si.si_errno = 0;
 	si.si_code = wot;
-	si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
+	si.si_addr = (void __user *) instruction_pointer(regs);
 	force_sig_info(SIGTRAP, &si, current);
 }
 
@@ -303,7 +301,7 @@ static void handle_break(struct pt_regs *regs)
 	if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) {
 		/* check if a BUG() or WARN() trapped here.  */
 		enum bug_trap_type tt;
-		tt = report_bug(regs->iaoq[0] & ~3, regs);
+		tt = report_bug(instruction_pointer(regs), regs);
 		if (tt == BUG_TRAP_TYPE_WARN) {
 			regs->iaoq[0] += 4;
 			regs->iaoq[1] += 4;
@@ -315,9 +313,9 @@ static void handle_break(struct pt_regs *regs)
 
 #ifdef PRINT_USER_FAULTS
 	if (unlikely(iir != GDB_BREAK_INSN)) {
-		printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
-			iir & 31, (iir>>13) & ((1<<13)-1),
-			current->pid, current->comm);
+		printk(KERN_DEBUG "%s(%d): break %d,%d\n",
+			current->comm, current->pid,
+			iir & 31, (iir>>13) & ((1<<13)-1));
 		show_regs(regs);
 	}
 #endif
@@ -415,9 +413,11 @@ void transfer_pim_to_trap_frame(struct pt_regs *regs)
  * has gone clearly wrong. We get called for faults in kernel space,
  * and HPMC's.
  */
-void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
+void __noreturn parisc_terminate(const char *msg, struct pt_regs *regs,
+				 unsigned long code, unsigned long offset)
 {
 	static DEFINE_SPINLOCK(terminate_lock);
+	struct unwind_frame_info info;
 
 	oops_in_progress = 1;
 
@@ -433,27 +433,15 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 		pdc_console_restart();
 
 	/* Not all paths will gutter the processor... */
-	switch(code){
-
-	case 1:
+	if (code == 1)
 		transfer_pim_to_trap_frame(regs);
-		break;
-
-	default:
-		/* Fall through */
-		break;
-
-	}
 	    
-	{
-		/* show_stack(NULL, (unsigned long *)regs->gr[30]); */
-		struct unwind_frame_info info;
-		unwind_frame_init(&info, current, regs);
-		do_show_stack(&info);
-	}
+	/* show_stack(NULL, (unsigned long *)regs->gr[30]); */
+	unwind_frame_init(&info, current, regs);
+	do_show_stack(&info);
 
 	printk("\n");
-	printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n",
+	printk(KERN_CRIT "%s: trap=%ld regs=%p (Addr=" RFMT ")\n",
 			msg, code, regs, offset);
 	show_regs(regs);
 
@@ -476,7 +464,46 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 	panic(msg);
 }
 
-void handle_interruption(int code, struct pt_regs *regs)
+static const char * const interruption_txt[] = {
+	[1] = "High-priority machine check (HPMC)",
+	[2] = "Power failure interrupt",
+	[3] = "Recovery counter trap",
+	[4] = "External interrupt trap",
+	[5] = "Low-priority machine check",
+	[6] = "Instruction TLB miss fault/Instruction page fault",
+	[7] = "Instruction memory protection trap",
+	[8] = "Illegal instruction trap",
+	[9] = "Break instruction trap",
+	[10] = "Privileged operation trap",
+	[11] = "Privileged register trap",
+	[12] = "Overflow trap",
+	[13] = "Conditional trap",
+	[14] = "Assist exception trap",
+	[15] = "Data TLB miss fault/Data page fault",
+	[16] = "Non-access instruction TLB miss fault",
+	[17] = "Non-access data TLB miss fault/Non-access data page fault",
+	[18] = "Unaligned access trap",
+	[19] = "Data memory break trap",
+	[21] = "Page reference trap",
+	[25] = "Taken branch trap",
+	[26] = "Data memory access rights trap",
+	[27] = "Data memory protection ID trap",
+	[28] = "Unaligned data reference trap",
+	[29] = "Performance monitor interrupt",
+	[30] = "Instruction debug trap",
+};
+
+const char * interruption_descr(unsigned long code)
+{
+	if (code >= ARRAY_SIZE(interruption_txt) ||
+		!interruption_txt[code] )
+		return "Unknown interruption trap"; 
+	else
+		return interruption_txt[code];
+}
+
+
+void handle_interruption(unsigned int code, struct pt_regs *regs)
 {
 	unsigned long fault_address = 0;
 	unsigned long fault_space = 0;
@@ -529,13 +556,13 @@ void handle_interruption(int code, struct pt_regs *regs)
 		/* set up a new led state on systems shipped with a LED State panel */
 		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
 		    
-	    	parisc_terminate("High Priority Machine Check (HPMC)",
-				regs, code, 0);
+	    	parisc_terminate(interruption_txt[1], regs, code, 0);
 		/* NOT REACHED */
 		
 	case  2:
 		/* Power failure interrupt */
-		printk(KERN_CRIT "Power failure interrupt !\n");
+		printk(KERN_CRIT "%s\n", interruption_txt[2]);
+		kill_cad_pid(SIGPWR, 1);
 		return;
 
 	case  3:
@@ -563,7 +590,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 
 	case  8:
 		/* Illegal instruction trap */
-		die_if_kernel("Illegal instruction", regs, code);
+		die_if_kernel(interruption_txt[8], regs, code);
 		si.si_code = ILL_ILLOPC;
 		goto give_sigill;
 
@@ -574,7 +601,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 	
 	case 10:
 		/* Privileged operation trap */
-		die_if_kernel("Privileged operation", regs, code);
+		die_if_kernel(interruption_txt[10], regs, code);
 		si.si_code = ILL_PRVOPC;
 		goto give_sigill;
 	
@@ -597,7 +624,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 			return;
 		}
 
-		die_if_kernel("Privileged register usage", regs, code);
+		die_if_kernel(interruption_txt[11], regs, code);
 		si.si_code = ILL_PRVREG;
 	give_sigill:
 		si.si_signo = SIGILL;
@@ -632,7 +659,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 		
 	case 14:
 		/* Assist Exception Trap, i.e. floating point exception. */
-		die_if_kernel("Floating point exception", regs, 0); /* quiet */
+		die_if_kernel(interruption_txt[14], regs, 0); /* quiet */
 		handle_fpe(regs);
 		return;
 		
@@ -727,7 +754,7 @@ void handle_interruption(int code, struct pt_regs *regs)
 		/* Fall Through */
 	case 27: 
 		/* Data memory protection ID trap */
-		die_if_kernel("Protection id trap", regs, code);
+		die_if_kernel(interruption_descr(code), regs, code);
 		si.si_code = SEGV_MAPERR;
 		si.si_signo = SIGSEGV;
 		si.si_errno = 0;
@@ -746,8 +773,8 @@ void handle_interruption(int code, struct pt_regs *regs)
 	default:
 		if (user_mode(regs)) {
 #ifdef PRINT_USER_FAULTS
-			printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
-			    current->pid, current->comm);
+			printk(KERN_DEBUG "%s(%d): unknown trap %d in handle_interruption().\n",
+			    current->comm, current->pid, code);
 			show_regs(regs);
 #endif
 			/* SIGBUS, for lack of a better one. */
@@ -767,12 +794,12 @@ void handle_interruption(int code, struct pt_regs *regs)
 	if (user_mode(regs)) {
 	    if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
 #ifdef PRINT_USER_FAULTS
+		printk(KERN_DEBUG "%s(%d): ", current->comm, current->pid);
 		if (fault_space == 0)
-			printk(KERN_DEBUG "User Fault on Kernel Space ");
+			printk("User Fault on Kernel Space\n");
 		else
-			printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
+			printk("User Fault (long pointer) (trap #%d)\n",
 			       code);
-		printk("pid=%d command='%s'\n", current->pid, current->comm);
 		show_regs(regs);
 #endif
 		si.si_signo = SIGSEGV;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index f6f6755..ef6394f 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -36,7 +36,7 @@
 DEFINE_PER_CPU(struct exception_data, exception_data);
 
 /*
- * parisc_acctyp(unsigned int inst) --
+ * parisc_acctyp(unsigned long code, unsigned int inst) --
  *    Given a PA-RISC memory access instruction, determine if the
  *    the instruction would perform a memory read or memory write
  *    operation.
@@ -208,13 +208,10 @@ bad_area:
 		struct siginfo si;
 
 #ifdef PRINT_USER_FAULTS
-		printk(KERN_DEBUG "\n");
-		printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
-		    tsk->pid, tsk->comm, code, address);
-		if (vma) {
-			printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
-					vma->vm_start, vma->vm_end);
-		}
+		printk(KERN_DEBUG "%s(%d): %s (trap #%ld) for "
+				  "addr 0x%08lx at ip=0x%08lx\n",
+			tsk->comm, tsk->pid, interruption_descr(code), 
+			code, address, instruction_pointer(regs));
 		show_regs(regs);
 #endif
 		/* FIXME: actually we need to get the signo and code correct */
diff --git a/include/asm-parisc/traps.h b/include/asm-parisc/traps.h
index 1945f99..ee92563 100644
--- a/include/asm-parisc/traps.h
+++ b/include/asm-parisc/traps.h
@@ -5,8 +5,9 @@
 struct pt_regs;
 
 /* traps.c */
-void parisc_terminate(char *msg, struct pt_regs *regs,
-		int code, unsigned long offset);
+const char * interruption_descr(unsigned long code);
+void __noreturn parisc_terminate(const char *msg, struct pt_regs *regs,
+		unsigned long code, unsigned long offset);
 
 /* mm/fault.c */
 void do_page_fault(struct pt_regs *regs, unsigned long code,



More information about the parisc-linux mailing list