[Crash-utility] [PATCH v2 3/3] [ppc] Enable stack trace display for KDUMP cores

Suzuki K. Poulose suzuki at in.ibm.com
Thu Dec 29 10:30:25 UTC 2011


Crash doesn't support displaying backtrace for ppc on KDUMP.

Before the patch :

 crash> bt
 PID: 482    TASK: c7af5380  CPU: 0   COMMAND: "bash"
 bt: cannot resolve "crash_save_current_state"

This patch enables backtrace for PPC.

After the patch :

 crash> bt
 PID: 482    TASK: c7af5380  CPU: 0   COMMAND: "bash"

 R0:  00000001   R1:  c7acfea0   R2:  c7af5380   R3:  00000063
 R4:  00001c61   R5:  ffffffff   R6:  c01e5234   R7:  c05943f8
 R8:  c05948a8   R9:  00000000   R10: 00003fff   R11: 00001c61
 R12: 24242482   R13: 100ed8f4   R14: 00000000   R15: 100e0000
 R16: 100e5db8   R17: 100cccf0   R18: 100e5f60   R19: 100e5ed0
 R20: 100f8c08   R21: 100e5ce4   R22: 00000001   R23: 100e0000
 R24: 100e0000   R25: 00000007   R26: c0560000   R27: 00029000
 R28: 00000000   R29: 00000063   R30: c01e03a8   R31: c05800ac
 NIP: c01e03bc   MSR: 00021000   OR3: 00000000   CTR: c01e03a8
 LR:  c01e06a8   XER: 20000000   CCR: 24242484   MQ:  c05948a8
 DAR: 00000000 DSISR: 00800000        Syscall Result: 48026000

  NIP [00000000c01e03bc] sysrq_handle_crash
  LR  [00000000c01e06a8] __handle_sysrq

  #0 [c7acfea0] sysrq_handle_crash at c01e03bc
  #1 [c7acfed0] write_sysrq_trigger at c01e0810
  #2 [c7acfee0] proc_reg_write at c0139f48
  #3 [c7acfef0] vfs_write at c00e4a10
  #4 [c7acff10] sys_write at c00e4c3c
  #5 [c7acff40] ret_from_syscall at c000d8c8
 crash> bt 1
 PID: 1      TASK: c782c000  CPU: 0   COMMAND: "init"
  #0 [c782b9f0] __schedule at c0311774
  #1 [c782ba30] schedule_hrtimeout_range_clock at c0312a18
  #2 [c782bab0] poll_schedule_timeout at c00f7e38
  #3 [c782bac0] do_select at c00f8f80
  #4 [c782bdc0] core_sys_select at c00f931c
  #5 [c782bf10] sys_select at c00f9758
  #6 [c782bf40] ret_from_syscall at c000d8c8

Signed-off-by: Suzuki K. Poulose <suzuki at in.ibm.com>
---

 ppc.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 88 insertions(+), 13 deletions(-)

diff --git a/ppc.c b/ppc.c
index a6e67fd..a001abe 100755
--- a/ppc.c
+++ b/ppc.c
@@ -1127,16 +1127,92 @@ ppc_print_eframe(char *efrm_str, struct ppc_pt_regs *regs, struct bt_info *bt)
 	fprintf(fp, "\n");
 }
 
+static void
+ppc_kdump_stack_frame(struct bt_info *bt, ulong *nip, ulong *ksp)
+{
+	struct ppc_pt_regs *pt_regs;
+	unsigned long ip, sp;
+
+	ip = sp = 0;
+
+	pt_regs = (struct ppc_pt_regs*)bt->machdep;
+
+	if (!pt_regs || !(pt_regs->gpr[1])) {
+		fprintf(fp, "0lx: GPR1 register value(SP) was not saved\n",
+			bt->task);
+		return;
+	}
+
+	sp = pt_regs->gpr[1];
+
+	if (!IS_KVADDR(sp)) {
+		if (IN_TASK_VMA(bt->task, *ksp))
+			fprintf(fp, "%0lx: Task is running in user space\n",
+				bt->task);
+		else 
+			fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+				bt->task, *ksp);
+	}
+
+	ip = pt_regs->nip;
+
+	if(nip)
+		*nip = ip;
+	if (ksp)
+		*ksp = sp;
+
+	if (bt->flags && 
+		((BT_TEXT_SYMBOLS | BT_TEXT_SYMBOLS_PRINT |
+			BT_TEXT_SYMBOLS_NOPRINT))) 
+		return TRUE;
+	/*
+	 * Print the collected regs for the active task
+	 */
+	ppc_print_regs(pt_regs);
+
+	if (!IS_KVADDR(sp)) 
+		return;
+	
+	fprintf(fp, " NIP [%016lx] %s\n", pt_regs->nip,
+		closest_symbol(pt_regs->nip));
+	fprintf(fp, " LR  [%016lx] %s\n", pt_regs->link,
+			closest_symbol(pt_regs->link));
+
+	fprintf(fp, "\n");
+
+	return;
+}	
+	
+static void
+ppc_dumpfile_stack_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)
+{
+	struct syment *sp;
+
+	/* For KDUMP get the SP, PC from pt_regs stored in the core */
+	if (pc->flags & KDUMP) {
+		ppc_kdump_stack_frame(bt, getpc, getsp);
+		return;
+	}
+
+	if (getpc) {
+		if (!(sp = next_symbol("crash_save_current_state", NULL)))
+			*getpc = (symbol_value("crash_save_current_state")+16);
+        	else
+			*getpc = (sp->value - 4);
+	}
+}
+
 /*
  *  Get a stack frame combination of pc and ra from the most relevent spot.
  */
 static void
 ppc_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
 {
-	if (pcp)
-		*pcp = ppc_get_pc(bt);
-	if (spp)
-		*spp = ppc_get_sp(bt);
+	if (DUMPFILE() && is_task_active(bt->task))
+		ppc_dumpfile_stack_frame(bt, pcp, spp);
+	else
+		get_ppc_frame(bt, pcp, spp);
+
 }
 
 
@@ -1148,7 +1224,10 @@ ppc_get_sp(struct bt_info *bt)
 {
         ulong sp;
 
-        get_ppc_frame(bt, NULL, &sp);
+	if (DUMPFILE() && is_task_active(bt->task))
+		ppc_dumpfile_stack_frame(bt, NULL, &sp);
+	else
+	        get_ppc_frame(bt, NULL, &sp);
 
         return sp;
 }
@@ -1159,16 +1238,12 @@ ppc_get_sp(struct bt_info *bt)
 static ulong
 ppc_get_pc(struct bt_info *bt)
 {
-	struct syment *sp;
 	ulong ip;
 
-	if (DUMPFILE() && is_task_active(bt->task)) {
-		if (!(sp = next_symbol("crash_save_current_state", NULL)))
-			return (symbol_value("crash_save_current_state")+16);
-		else
-			return (sp->value - 4);
-	}
-	get_ppc_frame(bt, &ip, NULL);
+	if (DUMPFILE() && is_task_active(bt->task))
+		ppc_dumpfile_stack_frame(bt, &ip, NULL);
+	else
+		get_ppc_frame(bt, &ip, NULL);
 
 	return ip;
 }




More information about the Crash-utility mailing list