[Crash-utility] [PATCH] ARM: dump also userspace registers when backtracing

Mika Westerberg ext-mika.1.westerberg at nokia.com
Wed Dec 1 15:55:23 UTC 2010


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.

 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\n", 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




More information about the Crash-utility mailing list