----- 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(a)redhat.com
>
https://www.redhat.com/mailman/listinfo/crash-utility
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility