[Crash-utility] arm64: "bt -f" output
Dave Anderson
anderson at redhat.com
Wed Jun 8 20:30:49 UTC 2016
----- Original Message -----
> Dave,
>
> When I looked at the output from "bt -f" command, I found that stack dump
> starts from frame.sp in arm64_print_stackframe_entry().
> Usage of stack frames on arm64 is a bit different from that on x86, and
> using frame.fp is, I believe, much useful (and accurate) for crash users.
> See my patch attached below.
>
> Details:
> A layout of a stack frame in a function looks like:
>
> stack grows to lower addresses.
> /|\
> |
> | |
> new sp +------+ <---
> |dyn | |
> | vars | |
> new fp +- - - + |
> |old fp| | a function's stack frame
> |old lr| |
> |static| |
> | vars| |
> old sp +------+ <---
> |dyn |
> | vars |
> old fp +------+
> | |
>
> * On function entry, sp is decremented down to new fp.
> * and old fp and sp are saved into this stack frame.
> "Static" local variables are allocated at the same time.
> * Later on, "dynamic" local variables may be allocated on a stack.
> But those dynamic variables are rarely used in the kernel image,
> and, as a matter of fact, sp is equal to fp in almost all functions.
> (not 100% though.)
>
> * Currently, sp is determined in arm64_unwind_frame() by
> sp = a callee's fp + 0x10
> where 0x10 stands for a saved area for fp and sp
> * As you can see, however, this calculated sp still points to the top of
> callee's static local variables and doesn't match with a *real* sp.
> * So, generally, dumping a stack from this calculated sp to the next frame's
> sp shows "callee's static local variables", old fp and sp.
>
> Confused?
OK, it's sinking in...
But how do you want to handle the top of all user space backtraces, i.e.,
the frame just before the user-space exception frame gets dumped? You
don't show it below, but it's kind of confusing to show a stack address
of 0.
Also, the stack dump shown before the #0 frame of active tasks is kind
of confusing. I'm not even sure it's worth showning? Or would be more
of a hack to prevent it from being displayed?
You commmented out the call to arm64_display_full_frame() in
arm64_print_exception_frame() -- is it because your patch has already
dumped it prior to the actual translated exception frame dump?
Dave
> Probably you will be able to understand more easily by seeing an example
> from my vmlinux/vmcore cases:
>
> === crash with my patch ===
> crash> bt -f 1324
> PID: 1324 TASK: ffff80002018be80 CPU: 2 COMMAND: "dhry"
> ffff800022f6ae08: ffff00000812ae44 (crash_save_cpu on IRQ stack)
> ffff800022f6ae10: ffff800022f74e00 ffff800020107ed0
> ffff800022f6ae20: 0000000000000000 ffff800020107ed0
> ffff800022f6ae30: ffff000008a26800 0000000000000003
> ffff800022f6ae40: 0000018800000005 0000000000000001
> #0 [ffff800022f6ae50] crash_save_cpu at ffff00000812ae44
> ffff800022f6ae50: ffff800022f6b010 ffff00000808e718
> #1's fp #1's lr (=handle_IPI)
> ffff800022f6ae60: ffff000008bce000 0000000000000002 -----
> ffff800022f6ae70: ffff800022f6ae90 0000000000000000 |
> ffff800022f6ae80: ffff800000000000 0000000000000000 |
> ffff800022f6ae90: 0000000000000000 0000000000000000 |local variables
> ... | including a big
> ffff800022f6afd0: 0000000000000000 0000000000000000 |"struct
> elf_prsatus"
> ffff800022f6afe0: ffff800022f6aff0 ffff00000808a820 |
> ffff800022f6aff0: ffff800022f6b010 ffff00000808e758 |
> ffff800022f6b000: ffff000008bce000 0000000000000000 -----
> #1 [ffff800022f6b010] handle_IPI at ffff00000808e718
> ffff800022f6b010: ffff800022f6b040 ffff0000080815f8
> ffff800022f6b020: 0000000000000003 0000000000001fff
> ffff800022f6b030: ffff800020107ed0 ffff000008e60c54
> #2 [ffff800022f6b040] gic_handle_irq at ffff0000080815f8
> ffff800022f6b040: ffff800022f6b080 ffff000008084c4c
> == crash(master branch) ===
> crash.dave> bt -f 1324
> PID: 1324 TASK: ffff80002018be80 CPU: 2 COMMAND: "dhry"
> ffff800022f6ae08: ffff00000812ae44 (crash_save_cpu on IRQ stack)
> #0 [ffff800022f6ae10] crash_save_cpu at ffff00000812ae44
> ffff800022f6ae10: ffff800022f74e00 ffff800020107ed0 -----
> ffff800022f6ae20: 0000000000000000 ffff800020107ed0 |local variables
> ffff800022f6ae30: ffff000008a26800 0000000000000003 | of callee(*)
> ffff800022f6ae40: 0000018800000005 0000000000000001 -----
> ffff800022f6ae50: ffff800022f6b010 ffff00000808e718 <= *real* stack frame
> #1 [ffff800022f6ae60] handle_IPI at ffff00000808e718 of
> crash_save_cpu()
> ffff800022f6ae60: ffff000008bce000 0000000000000002 starts here.
> ffff800022f6ae70: ffff800022f6ae90 0000000000000000
> ffff800022f6ae80: ffff800000000000 0000000000000000
> ffff800022f6ae90: 0000000000000000 0000000000000000
> ffff800022f6aea0: 0000000000000000 000000000000052c
> ffff800022f6aeb0: 0000000000000000 0000000000000000
> ...
> ffff800022f6afa0: ffff800022f6afc0 0000000000000000
> ffff800022f6afb0: ffff800022f6afe0 ffff000008675850
> ffff800022f6afc0: 0000000000402138 0000000000000000
> ffff800022f6afd0: 0000000000000000 0000000000000000
> ffff800022f6afe0: ffff800022f6aff0 ffff00000808a820
> ffff800022f6aff0: ffff800022f6b010 ffff00000808e758
> ffff800022f6b000: ffff000008bce000 0000000000000000
> ffff800022f6b010: ffff800022f6b040 ffff0000080815f8
> #2 [ffff800022f6b020] gic_handle_irq at ffff0000080815f8
> ffff800022f6b020: 0000000000000003 0000000000001fff
> ffff800022f6b030: ffff800020107ed0 ffff000008e60c54
> ffff800022f6b040: ffff800022f6b080 ffff000008084c4c
> === END ===
> (*) append_elf_note()
>
> Thanks,
> -Takahiro AKASHI
>
> ======8<======
> >From b3ca69ace916a5c233ce937954da887ba5487e50 Mon Sep 17 00:00:00 2001
> From: AKASHI Takahiro <takahiro.akashi at linaro.org>
> Date: Wed, 8 Jun 2016 11:14:22 +0900
> Subject: [PATCH] arm64: dump a stack frame based on fp
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
> arm64.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index bdea79c..22f93a2 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -1508,12 +1508,12 @@ arm64_print_stackframe_entry(struct bt_info *bt, int
> level, struct arm64_stackfr
> }
>
> if (bt->flags & BT_FULL) {
> - arm64_display_full_frame(bt, frame->sp);
> - bt->frameptr = frame->sp;
> + arm64_display_full_frame(bt, frame->fp);
> + bt->frameptr = frame->fp;
> }
>
> fprintf(ofp, "%s#%d [%8lx] %s at %lx", level < 10 ? " " : "", level,
> - frame->sp, name_plus_offset ? name_plus_offset : name,
> frame->pc);
> + frame->fp, name_plus_offset ? name_plus_offset : name,
> frame->pc);
>
> if (BT_REFERENCE_CHECK(bt))
> arm64_do_bt_reference_check(bt, frame->pc, name);
> @@ -1571,12 +1571,10 @@ arm64_unwind_frame(struct bt_info *bt, struct
> arm64_stackframe *frame)
> {
> unsigned long high, low, fp;
> unsigned long stack_mask;
> - unsigned long irq_stack_ptr, orig_sp, sp_in;
> + unsigned long irq_stack_ptr, orig_sp;
> struct arm64_pt_regs *ptregs;
> struct machine_specific *ms;
>
> - sp_in = frame->sp;
> -
> stack_mask = (unsigned long)(ARM64_STACK_SIZE) - 1;
> fp = frame->fp;
>
> @@ -1613,7 +1611,7 @@ arm64_unwind_frame(struct bt_info *bt, struct
> arm64_stackframe *frame)
> ptregs = (struct arm64_pt_regs
> *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(orig_sp))];
> frame->sp = orig_sp;
> frame->pc = ptregs->pc;
> - bt->bptr = sp_in;
> + bt->bptr = fp;
> if (CRASHDEBUG(1))
> error(INFO,
> "arm64_unwind_frame: switch stacks: fp: %lx sp: %lx pc: %lx\n",
> @@ -2004,8 +2002,11 @@ arm64_print_exception_frame(struct bt_info *bt, ulong
> pt_regs, int mode, FILE *o
> ulong LR, SP, offset;
> char buf[BUFSIZE];
>
> +#if 0 /* FIXME? */
> if (bt->flags & BT_FULL)
> arm64_display_full_frame(bt, pt_regs);
> +}
> +#endif
>
> if (CRASHDEBUG(1))
> fprintf(ofp, "pt_regs: %lx\n", pt_regs);
> --
> 2.8.1
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
>
More information about the Crash-utility
mailing list