[Crash-utility] [PATCH] ARM: dump also userspace registers when backtracing
Dave Anderson
anderson at redhat.com
Fri Dec 10 13:20:43 UTC 2010
----- "Mika Westerberg" <ext-mika.1.westerberg at nokia.com> wrote:
> On Wed, Dec 01, 2010 at 11:27:32AM -0500, ext Dave Anderson wrote:
> >
> > ----- "Mika Westerberg" <ext-mika.1.westerberg at nokia.com> wrote:
> >
> > > Enhance backtracing code to print out userspace registers in case we
> > > are at syscall entry. Other architectures supported by crash are
> > > already doing this.
> > >
> > > Signed-off-by: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
> > > ---
> > > I tested this with both unwind tables and framepointers enabled on
> > > my test vmcores, and also on live system.
> >
> > Works well on my sample dumpfiles -- queued for the next release.
>
> Dave,
>
> I just noticed that there's a bug in this patch - it handles slow
> syscall return path wrong.
>
> Below is a patch which applies on top of this and fixes the slow
> path also. If you prefer, I can also send you a single patch which
> combines both of the patches.
>
> Sorry about the mess.
No problem -- the patch applies fine to 5.1.0, and it's queued for
the next release.
Thanks,
Dave
> Regards,
> MW
>
> diff --git a/arm.c b/arm.c
> index a8a34b9..751fe00 100644
> --- a/arm.c
> +++ b/arm.c
> @@ -31,7 +31,7 @@ static int arm_verify_symbol(const char *, ulong,
> char);
> static int arm_is_module_addr(ulong);
> static int arm_is_kvaddr(ulong);
> static int arm_in_exception_text(ulong);
> -static int arm_in_ret_from_syscall(ulong);
> +static int arm_in_ret_from_syscall(ulong, int *);
> static void arm_back_trace(struct bt_info *);
> static void arm_back_trace_cmd(struct bt_info *);
> static ulong arm_processor_speed(void);
> @@ -669,13 +669,44 @@ arm_in_exception_text(ulong pc)
> }
>
> /*
> - * Returns TRUE if given pc points to a return from syscall
> entrypoint.
> + * Returns TRUE if given pc points to a return from syscall
> + * entrypoint. In case the function returns TRUE and if offset is
> given,
> + * it is filled with the offset that should be added to the SP to
> get
> + * address of the exception frame where the user registers are.
> */
> static int
> -arm_in_ret_from_syscall(ulong pc)
> +arm_in_ret_from_syscall(ulong pc, int *offset)
> {
> - return (pc == symbol_value("ret_fast_syscall") ||
> - pc == symbol_value("ret_slow_syscall"));
> + /*
> + * On fast syscall return path, the stack looks like:
> + *
> + * SP + 0 {r4, r5}
> + * SP + 8 user pt_regs
> + *
> + * The asm syscall handler pushes fifth and sixth registers
> + * onto the stack before calling the actual syscall handler.
> + *
> + * So in order to print out the user registers at the time
> + * the syscall was made, we need to adjust SP for 8.
> + */
> + if (pc == symbol_value("ret_fast_syscall")) {
> + if (offset)
> + *offset = 8;
> + return TRUE;
> + }
> +
> + /*
> + * In case we are on the slow syscall path, the SP already
> + * points to the start of the user registers hence no
> + * adjustments needs to be done.
> + */
> + if (pc == symbol_value("ret_slow_syscall")) {
> + if (offset)
> + *offset = 0;
> + return TRUE;
> + }
> +
> + return FALSE;
> }
>
> /*
> @@ -1178,6 +1209,7 @@ arm_dump_backtrace_entry(struct bt_info *bt, int
> level, ulong from, ulong sp)
> {
> struct load_module *lm;
> const char *name;
> + int offset = 0;
>
> name = closest_symbol(bt->instptr);
>
> @@ -1201,23 +1233,10 @@ arm_dump_backtrace_entry(struct bt_info *bt,
> int level, ulong from, ulong sp)
>
> if (arm_in_exception_text(bt->instptr)) {
> arm_dump_exception_stack(sp, sp + sizeof(struct arm_pt_regs));
> - } else if (arm_in_ret_from_syscall(from)) {
> - /*
> - * When we are returning from the syscall, here is
> - * what the stack frame looks like:
> - *
> - * SP + 0 {r4, r5}
> - * SP + 8 user pt_regs
> - *
> - * The asm syscall handler pushes fifth and sixth
> - * registers onto the stack before calling the
> - * actual syscall handler.
> - *
> - * So in order to print out the user registers when
> - * the syscall was made, we need to adjust sp for 8.
> - */
> - arm_dump_exception_stack(sp + 8,
> - sp + 8 + sizeof(struct arm_pt_regs));
> + } else if (arm_in_ret_from_syscall(from, &offset)) {
> + ulong nsp = sp + offset;
> +
> + arm_dump_exception_stack(nsp, nsp + sizeof(struct arm_pt_regs));
> }
>
> if (bt->flags & BT_FULL) {
More information about the Crash-utility
mailing list