[Crash-utility] crash doesn't decode regs with 7.1.5

Rabin Vincent rabin at rab.in
Wed Oct 19 22:36:11 UTC 2016


On Tue, Oct 18, 2016 at 04:10:51PM -0700, Sagar Borikar wrote:
> I tried these patches but still don't get correct bt output.

I think I see the problem now.  Your EPC is 0 so we hit the if
(!IS_KVADDR(current.pc)) condition on the first iteration of the
backtrace loop and exit without trying futher.

Could you please try the following patch?  Please include a log with
debugging enabled ("set debug 8") if it still doesn't work.  Thanks.

8<------------------
>From 4ae6ab8d181deea53ece847007d27d228166370d Mon Sep 17 00:00:00 2001
From: Rabin Vincent <rabinv at axis.com>
Date: Thu, 20 Oct 2016 00:19:33 +0200
Subject: [PATCH] mips: allow one invalid PC at start or after exception

Before:

PID: 2810   TASK: 835e41a8  CPU: 1   COMMAND: "sh"
 #0 [8315bb00] crash_kexec at 800b26a4
 #1 [8315bbe0] panic at 800dc0fc
 #2 [8315bc20] die at 8001fa74
 #3 [8315bc50] __do_page_fault at 8002de74
 #4 [8315bd28] ret_from_irq at 80019624
    $ 0   : 00000000 00000001 80690000 00000000
    $ 4   : 00000063 812972dc 81297db8 000000c2
    $ 8   : 00004b38 00000001 80680000 80620000
    $12   : 00000104 00000002 00000000 00000000
    $16   : 80622530 80620000 00000063 80620000
    $20   : 80622470 00000001 00000000 00b9f322
    $24   : 00000003 00000000 00440000 800dca80
    $28   : 8315a000 8315bde0 00000000 80313b30
    Hi    : 00000046
    Lo    : 0f5c2a0e
    epc   : 00000000
    ra    : 80313b30 __handle_sysrq+0x144
    Status: 1100fc03
    Cause : 10800008
    BadVA : 00000000

After:

 crash> bt
 PID: 2810   TASK: 835e41a8  CPU: 1   COMMAND: "sh"
  #0 [8315bb00] crash_kexec at 800b26a4
  #1 [8315bbe0] panic at 800dc0fc
  #2 [8315bc20] die at 8001fa74
  #3 [8315bc50] __do_page_fault at 8002de74
  #4 [8315bd28] ret_from_irq at 80019624
     $ 0   : 00000000 00000001 80690000 00000000
     $ 4   : 00000063 812972dc 81297db8 000000c2
     $ 8   : 00004b38 00000001 80680000 80620000
     $12   : 00000104 00000002 00000000 00000000
     $16   : 80622530 80620000 00000063 80620000
     $20   : 80622470 00000001 00000000 00b9f322
     $24   : 00000003 00000000 00440000 800dca80
     $28   : 8315a000 8315bde0 00000000 80313b30
     Hi    : 00000046
     Lo    : 0f5c2a0e
     epc   : 00000000
     ra    : 80313b30 __handle_sysrq+0x144
     Status: 1100fc03
     Cause : 10800008
     BadVA : 00000000
  #5 [8315bde0] (invalid) at 0
  #6 [8315bde0] __handle_sysrq at 80313b30
  #7 [8315be18] write_sysrq_trigger at 80313c24
  #8 [8315be38] proc_reg_write at 80178074
  #9 [8315be58] __vfs_write at 8011ea78
 #10 [8315bec0] vfs_write at 8011fe7c
 #11 [8315bef0] sys_write at 801201e8
 #12 [8315bf28] syscall_common at 800275c8
---
 mips.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/mips.c b/mips.c
index 6cd8d1f..1bb4d27 100644
--- a/mips.c
+++ b/mips.c
@@ -413,7 +413,7 @@ mips_dump_backtrace_entry(struct bt_info *bt, struct syment *sym,
 			  struct mips_unwind_frame *current,
 			  struct mips_unwind_frame *previous, int level)
 {
-	const char *name = sym->name;
+	const char *name = sym ? sym->name : "(invalid)";
 	struct load_module *lm;
 	char *name_plus_offset;
 	char buf[BUFSIZE];
@@ -447,7 +447,7 @@ mips_dump_backtrace_entry(struct bt_info *bt, struct syment *sym,
 			fprintf(fp, "    %s\n", buf);
 	}
 
-	if (mips_is_exception_entry(sym)) {
+	if (sym && mips_is_exception_entry(sym)) {
 		char pt_regs[SIZE(pt_regs)];
 
 		GET_STACK_DATA(current->sp, &pt_regs, SIZE(pt_regs));
@@ -533,6 +533,7 @@ mips_back_trace_cmd(struct bt_info *bt)
 {
 	struct mips_unwind_frame current, previous;
 	int level = 0;
+	int invalid_ok = 1;
 
 	if (bt->flags & BT_REGS_NOT_FOUND)
 		return;
@@ -549,22 +550,24 @@ mips_back_trace_cmd(struct bt_info *bt)
 	}
 
 	while (INSTACK(current.sp, bt)) {
-		struct syment *symbol;
+		struct syment *symbol = NULL;
 		ulong offset;
 
 		if (CRASHDEBUG(8))
 			fprintf(fp, "level %d pc %#lx ra %#lx sp %lx\n",
 				level, current.pc, current.ra, current.sp);
 
-		if (!IS_KVADDR(current.pc))
+		if (!IS_KVADDR(current.pc) && !invalid_ok)
 			return;
 
 		symbol = value_search(current.pc, &offset);
-		if (!symbol) {
+		if (!symbol && !invalid_ok) {
 			error(FATAL, "PC is unknown symbol (%lx)", current.pc);
 			return;
 		}
 
+		invalid_ok = 0;
+
 		/*
 		 * If we get an address which points to the start of a
 		 * function, then it could one of the following:
@@ -586,7 +589,7 @@ mips_back_trace_cmd(struct bt_info *bt)
 		 *    * ret_from_fork
 		 *    * ret_from_kernel_thread
 		 */
-		if (!current.ra && !offset && !STRNEQ(symbol->name, "ret_from")) {
+		if (!current.ra && !offset && symbol && !STRNEQ(symbol->name, "ret_from")) {
 			if (CRASHDEBUG(8))
 				fprintf(fp, "zero offset at %s, try previous symbol\n",
 					symbol->name);
@@ -598,7 +601,7 @@ mips_back_trace_cmd(struct bt_info *bt)
 			}
 		}
 
-		if (mips_is_exception_entry(symbol)) {
+		if (symbol && mips_is_exception_entry(symbol)) {
 			struct mips_pt_regs_main *mains;
 			struct mips_pt_regs_cp0 *cp0;
 			char pt_regs[SIZE(pt_regs)];
@@ -617,18 +620,30 @@ mips_back_trace_cmd(struct bt_info *bt)
 			if (CRASHDEBUG(8))
 				fprintf(fp, "exception pc %#lx ra %#lx sp %lx\n",
 					previous.pc, previous.ra, previous.sp);
-		} else {
+
+			/* The PC causing the exception may have been invalid */
+			invalid_ok = 1;
+		} else if (symbol) {
 			mips_analyze_function(symbol->value, offset, &current, &previous);
+		} else {
+			/*
+			 * The current PC is invalid.  Assume that the code
+			 * jumped through a invalid pointer and that the SP has
+			 * not been adjusted.
+			 */
+			previous.sp = current.sp;
 		}
 
 		mips_dump_backtrace_entry(bt, symbol, &current, &previous, level++);
-		if (!current.ra)
-			break;
 
 		current.pc = current.ra;
 		current.sp = previous.sp;
 		current.ra = previous.ra;
 
+		if (CRASHDEBUG(8))
+			fprintf(fp, "next %d pc %#lx ra %#lx sp %lx\n",
+				level, current.pc, current.ra, current.sp);
+
 		previous.sp = previous.pc = previous.ra = 0;
 	}
 }
-- 
2.1.4




More information about the Crash-utility mailing list