Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Crash Utility (http://www.linux-archive.org/crash-utility/)
-   -   ARM: dump also userspace registers when backtracing (http://www.linux-archive.org/crash-utility/459975-arm-dump-also-userspace-registers-when-backtracing.html)

Dave Anderson 12-01-2010 03:27 PM

ARM: dump also userspace registers when backtracing
 
----- "Mika Westerberg" <ext-mika.1.westerberg@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@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.

Thanks,
Dave


> arm.c | 31 ++++++++++++++++++++++++++++++-
> 1 files changed, 30 insertions(+), 1 deletions(-)
>
> diff --git a/arm.c b/arm.c
> index 985f78e..a8a34b9 100644
> --- a/arm.c
> +++ b/arm.c
> @@ -31,6 +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 void arm_back_trace(struct bt_info *);
> static void arm_back_trace_cmd(struct bt_info *);
> static ulong arm_processor_speed(void);
> @@ -668,6 +669,16 @@ arm_in_exception_text(ulong pc)
> }
>
> /*
> + * Returns TRUE if given pc points to a return from syscall
> entrypoint.
> + */
> +static int
> +arm_in_ret_from_syscall(ulong pc)
> +{
> + return (pc == symbol_value("ret_fast_syscall") ||
> + pc == symbol_value("ret_slow_syscall"));
> +}
> +
> +/*
> * Unroll the kernel stack using a minimal amount of gdb services.
> */
> static void
> @@ -1188,8 +1199,26 @@ arm_dump_backtrace_entry(struct bt_info *bt,
> int level, ulong from, ulong sp)
> fprintf(fp, " %s
", buf);
> }
>
> - if (arm_in_exception_text(bt->instptr))
> + 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));
> + }
>
> if (bt->flags & BT_FULL) {
> if (kt->flags & DWARF_UNWIND) {
> --
> 1.7.3.2
>
> --
> Crash-utility mailing list
> Crash-utility@redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility

Dave Anderson 12-10-2010 12:20 PM

ARM: dump also userspace registers when backtracing
 
----- "Mika Westerberg" <ext-mika.1.westerberg@nokia.com> wrote:

> On Wed, Dec 01, 2010 at 11:27:32AM -0500, ext Dave Anderson wrote:
> >
> > ----- "Mika Westerberg" <ext-mika.1.westerberg@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@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) {

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility


All times are GMT. The time now is 03:30 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.