[Crash-utility] [PATCH] ppc64: rework bt command
Dave Anderson
anderson at redhat.com
Mon Sep 17 14:24:53 UTC 2018
Hi Hari,
Can you check the original bugzilla w/respect to a task running
in user space when the crash occurs?
Thanks,
Dave
----- Original Message -----
>
>
> ----- Original Message -----
> > Commit 3db3d3992d78 was aimed at making 'bt' work for dumpfiles saved
> > with fadump but it introduced a bit of unwarranted complexity in 'bt'
> > command processing. Rework 'bt' command processing for PPC64 arch to
> > make it a little less compilated and also, print symbols for NIP and
> > LR registers on exception frames.
> >
> > Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
>
> Thanks, Hari. As we discussed in the related bugzilla, this looks good.
> Queued for crash-7.2.4:
>
> https://github.com/crash-utility/crash/commit/5fe78861ea1589084f6a2956a6ff63677c9269e1
>
> Dave
>
>
>
> > ---
> > ppc64.c | 140
> > +++++++++++++++++++++++++++++++++++++++++++++------------------
> > 1 file changed, 99 insertions(+), 41 deletions(-)
> >
> > diff --git a/ppc64.c b/ppc64.c
> > index f5d0dac..03fecd3 100644
> > --- a/ppc64.c
> > +++ b/ppc64.c
> > @@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame,
> > lr);
> > return;
> > }
> > - if (req->pc != lr) {
> > - fprintf(fp, "\n%s[Link Register] ",
> > - frame < 10 ? " " : "");
> > - fprintf(fp, "[%lx] %s at %lx",
> > - req->sp, lrname, lr);
> > - }
> > req->ra = lr;
> > }
> > - if (!req->name || STREQ(req->name,lrname))
> > + if (!req->name || STREQ(req->name, lrname) ||
> > + !is_kernel_text(req->pc))
> > fprintf(fp, " (unreliable)");
> >
> > fprintf(fp, "\n");
> > @@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs)
> > fprintf(fp, " Syscall Result: %016lx\n", regs->result);
> > }
> >
> > +static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr)
> > +{
> > + char buf[BUFSIZE];
> > + char *sym_buf;
> > +
> > + sym_buf = value_to_symstr(regs->nip, buf, 0);
> > + if (sym_buf[0] != NULLCHAR)
> > + fprintf(fp, " [NIP : %s]\n", sym_buf);
> > +
> > + if (print_lr) {
> > + sym_buf = value_to_symstr(regs->link, buf, 0);
> > + if (sym_buf[0] != NULLCHAR)
> > + fprintf(fp, " [LR : %s]\n", sym_buf);
> > + }
> > +}
> > +
> > /*
> > * Print the exception frame information
> > */
> > @@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct
> > ppc64_pt_regs *regs,
> >
> > fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
> > ppc64_print_regs(regs);
> > + ppc64_print_nip_lr(regs, 1);
> > +}
> > +
> > +/*
> > + * For vmcore typically saved with KDump or FADump, get SP and IP values
> > + * from the saved ptregs.
> > + */
> > +static int
> > +ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
> > +{
> > + struct ppc64_pt_regs *pt_regs;
> > + unsigned long unip;
> > +
> > + pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
> > + if (!pt_regs || !pt_regs->gpr[1]) {
> > + /*
> > + * Not collected regs. May be the corresponding CPU not
> > + * responded to an IPI in case of KDump OR f/w has not
> > + * not provided the register info in case of FADump.
> > + */
> > + fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
> > + bt_in->task);
> > + return FALSE;
> > + }
> > + *ksp = pt_regs->gpr[1];
> > + if (IS_KVADDR(*ksp)) {
> > + readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
> > + FAULT_ON_ERROR);
> > + *nip = unip;
> > + } else {
> > + if (IN_TASK_VMA(bt_in->task, *ksp))
> > + fprintf(fp, "%0lx: Task is running in user space\n",
> > + bt_in->task);
> > + else
> > + fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
> > + bt_in->task, *ksp);
> > + *nip = pt_regs->nip;
> > + }
> > +
> > + if (bt_in->flags &&
> > + ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
> > + return TRUE;
> > +
> > + /*
> > + * Print the collected regs for the active task
> > + */
> > + ppc64_print_regs(pt_regs);
> > + if (!IS_KVADDR(*ksp))
> > + return FALSE;
> > +
> > + ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0);
> > +
> > + return TRUE;
> > }
> >
> > /*
> > @@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct
> > ppc64_pt_regs
> > *regs,
> > static int
> > ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong
> > *ksp)
> > {
> > - int i;
> > + int i, ret, panic_task;
> > char *sym;
> > ulong *up;
> > struct bt_info bt_local, *bt;
> > @@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info
> > *bt_in,
> > ulong *nip, ulong *ksp)
> > struct ppc64_pt_regs *pt_regs;
> > struct syment *sp;
> >
> > - bt = &bt_local;
> > - BCOPY(bt_in, bt, sizeof(struct bt_info));
> > - ms = machdep->machspec;
> > + bt = &bt_local;
> > + BCOPY(bt_in, bt, sizeof(struct bt_info));
> > + ms = machdep->machspec;
> > + ur_nip = ur_ksp = 0;
> > +
> > + panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
> >
> > check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE;
> > + if (panic_task && bt->machdep) {
> > + pt_regs = (struct ppc64_pt_regs *)bt->machdep;
> > + ur_nip = pt_regs->nip;
> > + ur_ksp = pt_regs->gpr[1];
> > + } else if ((pc->flags & KDUMP) ||
> > + ((pc->flags & DISKDUMP) &&
> > + (*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
> > + /*
> > + * For the KDump or FADump vmcore, use SP and IP values
> > + * that are saved in ptregs.
> > + */
> > + ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp);
> > + if (ret)
> > + return TRUE;
> > + }
> >
> > if (bt->task != tt->panic_task) {
> > char cpu_frozen = FALSE;
> > @@ -2385,38 +2467,14 @@ retry:
> > check_intrstack = FALSE;
> > goto retry;
> > }
> > -
> > /*
> > - * We didn't find what we were looking for, so try to use
> > - * the SP and IP values saved in ptregs.
> > + * We didn't find what we were looking for, so just use what was
> > + * passed in the ELF header.
> > */
> > - pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
> > - if (!pt_regs || !pt_regs->gpr[1]) {
> > - /*
> > - * Not collected regs. May be the corresponding CPU did not
> > - * respond to an IPI.
> > - */
> > - if (CRASHDEBUG(1))
> > - fprintf(fp, "%0lx: GPR1(SP) register value not saved\n",
> > - bt_in->task);
> > - } else {
> > - *ksp = pt_regs->gpr[1];
> > - if (IS_KVADDR(*ksp)) {
> > - readmem(*ksp+16, KVADDR, nip, sizeof(ulong),
> > - "Regs NIP value", FAULT_ON_ERROR);
> > - ppc64_print_regs(pt_regs);
> > - return TRUE;
> > - } else {
> > - if (IN_TASK_VMA(bt_in->task, *ksp))
> > - fprintf(fp, "%0lx: Task is running in user space\n",
> > - bt_in->task);
> > - else
> > - fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
> > - bt_in->task, *ksp);
> > - *nip = pt_regs->nip;
> > - ppc64_print_regs(pt_regs);
> > - return FALSE;
> > - }
> > + if (ur_nip && ur_ksp) {
> > + *nip = ur_nip;
> > + *ksp = ur_ksp;
> > + return TRUE;
> > }
> >
> > console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic
> > task\n");
> >
> >
>
More information about the Crash-utility
mailing list