[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