[Crash-utility] arm64: "bt -f" output

Dave Anderson anderson at redhat.com
Mon Jun 13 15:30:24 UTC 2016



----- Original Message -----
> Dave,
> 
> On Fri, Jun 10, 2016 at 04:37:42PM -0400, Dave Anderson wrote:
> > Hi Takahiro,
> > 
> > To address my concerns about your patch, I added a few additional changes and attached
> > it to this email.  The changes are:
> > 
> > (1) Prevent the stack dump "below" the #0 level.  Yes, the stack data region is contained within
> >     the incoming frame parameters, but it's ugly and we really don't care to see what's before
> >     the #0 crash_kexec and crash_save_cpu #0 frames.
> > (2) Fill in the missing stack dump at the top of the process stack, up to, but not including
> >     the user-space exception frame.
> > (3) Instead of showing the fp of 0 in the top-most frame's stack address, fill it in with the
> >     address of the user-space exception frame.
> > 
> > Note that there is no dump of the stack containing the user-space exception frame, but the
> > register dump itself should suffice.
> 
> Well, the essential problem with my patch is that the output from "bt -f"
> looks like:
>      #XX ['fp'] 'function' at 'pc'  --- (1)
>      <function's stack dump>        --- (2)
> but that (1) and (2) are not printed as a single stack frame in the same
> iteration of while loop in arm64_back_trace_cmd().
> (I hope you understand what I mean :)

Actually I prefer your first approach.  I find this new one confusing, not
to mention unlike any of the other architectures in that the "frame level"
#X address value is not contiguous with the stack addresses that get filled
in by -f. 

Taking your picture into account:

         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   +------+
         |      |

Your first patch seemed natural to me because for any "#X" line containing a function
name, that function's dynamic variables, the "old fp/old lr" pair, and the function's
static variables were dumped below it (i.e., at higher stack addresses).   


> To be consistent with the out format of x86, the output should be
>      <function's stack dump>
>      #XX ['fp'] 'function' at 'pc'
> 
> Unfortunately, this requires that arm64_back_trace_cmd() and other functions should be overhauled.
> Please take a look at my next patch though it is uncompleted and still has room for improvement.

I don't know what you mean by "consistent with the out format of x86"?  With x86_64, 
each #<level> line is simply the stack address where the function pushed its return
address as a result of its making a "callq" to the next function.  Any local variables of 
the calling function would be at the next higher stack addresses:

  ...
  #X [stack address] function2 at 'return address'
  <function2's local variables>
  #Y [stack address] function1 at 'return address'
  <functions1's local variables> 
  ...

So for digging out local stack variables associated with a function, it's a simple
matter of looking "below" it in the "bt -f" output.

Dave


> Thanks,
> -Takahiro AKASHI
> 
> 
> > If you can live with the display, I'll clean up the patch, and maybe add
> > the stack-layout diagram
> > from your last post into a comment.  It was quite helpful, especially in
> > comparison to the
> > x86_64 model, which is what I was mistakenly using as a guide.
> > 
> > Thanks,
> >   Dave
> > 
> > 
> > 
> 
> > diff --git a/arm64.c b/arm64.c
> > index 86ec348..3b29ef4 100644
> > --- a/arm64.c
> > +++ b/arm64.c
> > @@ -1407,13 +1407,14 @@ arm64_print_stackframe_entry(struct bt_info *bt,
> > int level, struct arm64_stackfr
> >                                  value_to_symstr(frame->pc, buf,
> >                                  bt->radix);
> >          }
> >  
> > -	if (bt->flags & BT_FULL) {
> > -		arm64_display_full_frame(bt, frame->sp);
> > -		bt->frameptr = frame->sp;
> > +	if ((bt->flags & BT_FULL) && level) {
> > +		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);
> > +                frame->fp ? frame->fp : bt->stacktop - USER_EFRAME_OFFSET,
> > name_plus_offset ? name_plus_offset : name, frame->pc);
> >  
> >  	if (BT_REFERENCE_CHECK(bt))
> >  		arm64_do_bt_reference_check(bt, frame->pc, name);
> > @@ -1447,8 +1448,12 @@ arm64_display_full_frame(struct bt_info *bt, ulong
> > sp)
> >  	if (bt->frameptr == sp)
> >  		return;
> >  
> > -	if (!INSTACK(sp, bt) || !INSTACK(bt->frameptr, bt))
> > -		return;
> > +	if (!INSTACK(sp, bt) || !INSTACK(bt->frameptr, bt)) {
> > +		if (sp == 0)
> > +			sp = bt->stacktop - USER_EFRAME_OFFSET;
> > +		else
> > +			return;
> > +	}
> >  
> >  	words = (sp - bt->frameptr) / sizeof(ulong);
> >  
> > @@ -1471,12 +1476,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;
> >  
> > @@ -1513,7 +1516,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",
> > @@ -1904,8 +1907,10 @@ 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);
> 
> > --
> > Crash-utility mailing list
> > Crash-utility at redhat.com
> > https://www.redhat.com/mailman/listinfo/crash-utility
> 
> --
> 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