On Wed, Dec 01, 2010 at 11:27:32AM -0500, ext Dave Anderson wrote: > > ----- "Mika Westerberg" <ext-mika.1.westerberg@xxxxxxxxx> 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@xxxxxxxxx> > > --- > > 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. 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility