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

Suzuki K. Poulose suzuki at in.ibm.com
Mon Jan 9 13:02:49 UTC 2012


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 |  108 +++++++++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/ppc.c b/ppc.c
index a6e67fd..509a41b 100755
--- a/ppc.c
+++ b/ppc.c
@@ -59,8 +59,6 @@ static void ppc_print_eframe(char *, struct ppc_pt_regs *, struct bt_info *);
 static void ppc_print_regs(struct ppc_pt_regs *);
 static void ppc_display_full_frame(struct bt_info *, ulong, FILE *);
 static void ppc_dump_irq(int);
-static ulong ppc_get_pc(struct bt_info *);
-static ulong ppc_get_sp(struct bt_info *);
 static void ppc_get_stack_frame(struct bt_info *, ulong *, ulong *);
 static int ppc_dis_filter(ulong, char *, unsigned int);
 static void ppc_cmd_mach(void);
@@ -1127,54 +1125,96 @@ ppc_print_eframe(char *efrm_str, struct ppc_pt_regs *regs, struct bt_info *bt)
 	fprintf(fp, "\n");
 }
 
-/*
- *  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)
+ppc_kdump_stack_frame(struct bt_info *bt, ulong *nip, ulong *ksp)
 {
-	if (pcp)
-		*pcp = ppc_get_pc(bt);
-	if (spp)
-		*spp = ppc_get_sp(bt);
-}
+	struct ppc_pt_regs *pt_regs;
+	unsigned long ip, sp;
 
+	ip = sp = 0;
 
-/*
- *  Get the saved ESP from a user-space copy of the kernel stack.
- */
-static ulong
-ppc_get_sp(struct bt_info *bt)
-{
-        ulong sp;
+	pt_regs = (struct ppc_pt_regs*)bt->machdep;
+
+	if (!pt_regs || !(pt_regs->gpr[1])) {
+		fprintf(fp, "0%lx: GPR1 register value(SP) was not saved\n",
+			bt->task);
+		return;
+	}
 
-        get_ppc_frame(bt, NULL, &sp);
+	sp = pt_regs->gpr[1];
 
-        return sp;
-}
+	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);
+	}
 
-/*
- *  Get the saved PC from a user-space copy of the kernel stack.
- */
-static ulong
-ppc_get_pc(struct bt_info *bt)
+	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;
+	/*
+	 * 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;
-	ulong ip;
 
-	if (DUMPFILE() && is_task_active(bt->task)) {
+	/* 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)))
-			return (symbol_value("crash_save_current_state")+16);
-		else
-			return (sp->value - 4);
+			*getpc = (symbol_value("crash_save_current_state")+16);
+        	else
+			*getpc = (sp->value - 4);
 	}
-	get_ppc_frame(bt, &ip, NULL);
+}
+
+/*
+ *  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 (DUMPFILE() && is_task_active(bt->task))
+		ppc_dumpfile_stack_frame(bt, pcp, spp);
+	else
+		get_ppc_frame(bt, pcp, spp);
 
-	return ip;
 }
 
 /*
- *  Do the work for ppc_get_sp() and ppc_get_pc().
+ *  Do the work for ppc_get_stack_frame() for non-active tasks
  */
 static void
 get_ppc_frame(struct bt_info *bt, ulong *getpc, ulong *getsp)




More information about the Crash-utility mailing list