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@xxxxxxxxxx> --- ppc.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 91 insertions(+), 13 deletions(-) diff --git a/ppc.c b/ppc.c index 869b066..d74e52d 100755 --- a/ppc.c +++ b/ppc.c @@ -980,16 +980,95 @@ ppc_exception_frame(ulong addr, struct bt_info *bt, struct gnu_request *req) } +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)) + readmem(sp, KVADDR, &ip, sizeof(ulong), "Regs NIP Value", + FAULT_ON_ERROR); + else { + if (IN_TASK_VMA(bt->task, sp)) + fprintf(fp, "%0lx: Task is running in userspace\n", + bt->task); + else + fprintf(fp, "%0lx: Invalid Stack Pointer : 0%lx\n", + bt->task, sp); + 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); + } @@ -1001,7 +1080,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; } @@ -1012,16 +1094,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; } -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility