[PATCH] s390: Print pt_regs for interrupt stack frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave,

With this patch instead of just printing the string " - Interrupt -",
we print the pt_regs for interrupts. The pt_regs contain all the current
registers and PSW of the interrupted CPU. This is very useful information
for debugging.

Old output:
-----------
 #4 [00017ea0] do_restart at 111c18
 #5 [00017eb8] psw_restart_int_handler at 5c1194
 - Interrupt -
 #6 [00017f58] vtime_stop_cpu at 5c043e
 #0 [00907eb0] cpu_idle at 106026
 #1 [00907ef8] start_kernel at 9799e8

New output:
-----------
 #4 [00017ea0] do_restart at 111c18
 #5 [00017eb8] psw_restart_int_handler at 5c1194
 PSW:  0706000180000000 00000000005c043e (vtime_stop_cpu+134)
 GPRS: 0000000000000000 00000000005c043e 00000000011e5228 00000000011e5248 
       0000000000907f08 00000000011e5b40 0000000000979324 0000000000000000 
       00000000009c0000 00000000009c0010 00000000009ab024 00000000011e5200 
       00000000011e5238 00000000005c6a00 0000000000106026 0000000000907e68 
 #0 [00907eb0] cpu_idle at 106026
 #1 [00907ef8] start_kernel at 9799e

Signed-off-by: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx>
---
 s390x.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 11 deletions(-)

--- a/s390x.c
+++ b/s390x.c
@@ -878,6 +878,24 @@ static void print_frame_data(unsigned lo
 }
 
 /*
+ * Do reference check and set flags
+ */
+static int bt_reference_check(struct bt_info *bt, unsigned long addr)
+{
+	if (!BT_REFERENCE_CHECK(bt))
+		return 0;
+
+	if (bt->ref->cmdflags & BT_REF_HEXVAL) {
+		if (addr == bt->ref->hexval)
+			bt->ref->cmdflags |= BT_REF_FOUND;
+	} else {
+		if (STREQ(closest_symbol(addr), bt->ref->str))
+			bt->ref->cmdflags |= BT_REF_FOUND;
+	}
+	return 1;
+}
+
+/*
  * Print stack frame
  */
 static void print_frame(struct bt_info *bt, int cnt, unsigned long sp,
@@ -886,16 +904,8 @@ static void print_frame(struct bt_info *
 	struct load_module *lm;
 	char *sym;
 
-	if (BT_REFERENCE_CHECK(bt)) {
-		if (bt->ref->cmdflags & BT_REF_HEXVAL) {
-			if (r14 == bt->ref->hexval)
-				bt->ref->cmdflags |= BT_REF_FOUND;
-		} else {
-			if (STREQ(closest_symbol(r14), bt->ref->str))
-				bt->ref->cmdflags |= BT_REF_FOUND;
-		}
+	if (bt_reference_check(bt, r14))
 		return;
-	}
 	fprintf(fp, "%s#%d [%08lx] ", cnt < 10 ? " " : "", cnt, sp);
 	sym = closest_symbol(r14);
 	fprintf(fp, "%s at %lx", sym, r14);
@@ -907,6 +917,46 @@ static void print_frame(struct bt_info *
 }
 
 /*
+ * Print pt_regs structure
+ */
+static void print_ptregs(struct bt_info *bt, unsigned long sp)
+{
+	unsigned long addr, psw_flags, psw_addr, offs;
+	struct load_module *lm;
+	char *sym;
+	int i;
+
+	addr = sp + MEMBER_OFFSET("pt_regs", "psw");
+	psw_flags = readmem_ul(addr);
+	psw_addr = readmem_ul(addr + sizeof(long));
+	if (bt_reference_check(bt, psw_addr))
+		return;
+
+	fprintf(fp, " PSW:  %016lx %016lx ", psw_flags, psw_addr);
+	sym = closest_symbol(psw_addr);
+	offs = psw_addr - closest_symbol_value(psw_addr);
+	if (module_symbol(psw_addr, NULL, &lm, NULL, 0))
+		fprintf(fp, "(%s+%ld [%s])\n", sym, offs, lm->mod_name);
+	else
+		fprintf(fp, "(%s+%ld)\n", sym, offs);
+
+	addr = sp + MEMBER_OFFSET("pt_regs", "gprs");
+	for (i = 0; i < 16; i++) {
+		if (i != 0 && i % 4 == 0)
+			fprintf(fp, "\n");
+		if (i % 4 == 0) {
+			if (i == 0)
+				fprintf(fp, " GPRS: ");
+			else
+				fprintf(fp, "       ");
+		}
+		fprintf(fp, "%016lx ", readmem_ul(addr + i * sizeof(long)));
+	}
+	fprintf(fp, "\n");
+}
+
+
+/*
  * Print back trace for one stack
  */
 static unsigned long show_trace(struct bt_info *bt, int cnt, unsigned long sp,
@@ -955,8 +1005,7 @@ static unsigned long show_trace(struct b
 		/* Check for loop (kernel_thread_starter) of second zero bc */
 		if (low == reg || reg == 0)
 			return reg;
-		fprintf(fp, " - Interrupt -\n");
-		print_frame(bt, cnt++, sp, psw_addr);
+		print_ptregs(bt, sp);
 		low = sp;
 		sp = reg;
 		cnt = 0;

Subject: [PATCH] Print pt_regs for interrupt stack frames for s390x

From: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx>

With this patch instead of just printing the string " - Interrupt -",
we print the pt_regs for interrupts. The pt_regs contain all the current
registers and PSW of the interrupted CPU. This is very useful information
for debugging.

Old output:
-----------
 #4 [00017ea0] do_restart at 111c18
 #5 [00017eb8] psw_restart_int_handler at 5c1194
 - Interrupt -
 #6 [00017f58] vtime_stop_cpu at 5c043e
 #0 [00907eb0] cpu_idle at 106026
 #1 [00907ef8] start_kernel at 9799e8

New output:
-----------
 #4 [00017ea0] do_restart at 111c18
 #5 [00017eb8] psw_restart_int_handler at 5c1194
 PSW:  0706000180000000 00000000005c043e (vtime_stop_cpu+134)
 GPRS: 0000000000000000 00000000005c043e 00000000011e5228 00000000011e5248 
       0000000000907f08 00000000011e5b40 0000000000979324 0000000000000000 
       00000000009c0000 00000000009c0010 00000000009ab024 00000000011e5200 
       00000000011e5238 00000000005c6a00 0000000000106026 0000000000907e68 
 #0 [00907eb0] cpu_idle at 106026
 #1 [00907ef8] start_kernel at 9799e

Signed-off-by: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx>
---
 s390x.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 11 deletions(-)

--- a/s390x.c
+++ b/s390x.c
@@ -878,6 +878,24 @@ static void print_frame_data(unsigned lo
 }
 
 /*
+ * Do reference check and set flags
+ */
+static int bt_reference_check(struct bt_info *bt, unsigned long addr)
+{
+	if (!BT_REFERENCE_CHECK(bt))
+		return 0;
+
+	if (bt->ref->cmdflags & BT_REF_HEXVAL) {
+		if (addr == bt->ref->hexval)
+			bt->ref->cmdflags |= BT_REF_FOUND;
+	} else {
+		if (STREQ(closest_symbol(addr), bt->ref->str))
+			bt->ref->cmdflags |= BT_REF_FOUND;
+	}
+	return 1;
+}
+
+/*
  * Print stack frame
  */
 static void print_frame(struct bt_info *bt, int cnt, unsigned long sp,
@@ -886,16 +904,8 @@ static void print_frame(struct bt_info *
 	struct load_module *lm;
 	char *sym;
 
-	if (BT_REFERENCE_CHECK(bt)) {
-		if (bt->ref->cmdflags & BT_REF_HEXVAL) {
-			if (r14 == bt->ref->hexval)
-				bt->ref->cmdflags |= BT_REF_FOUND;
-		} else {
-			if (STREQ(closest_symbol(r14), bt->ref->str))
-				bt->ref->cmdflags |= BT_REF_FOUND;
-		}
+	if (bt_reference_check(bt, r14))
 		return;
-	}
 	fprintf(fp, "%s#%d [%08lx] ", cnt < 10 ? " " : "", cnt, sp);
 	sym = closest_symbol(r14);
 	fprintf(fp, "%s at %lx", sym, r14);
@@ -907,6 +917,46 @@ static void print_frame(struct bt_info *
 }
 
 /*
+ * Print pt_regs structure
+ */
+static void print_ptregs(struct bt_info *bt, unsigned long sp)
+{
+	unsigned long addr, psw_flags, psw_addr, offs;
+	struct load_module *lm;
+	char *sym;
+	int i;
+
+	addr = sp + MEMBER_OFFSET("pt_regs", "psw");
+	psw_flags = readmem_ul(addr);
+	psw_addr = readmem_ul(addr + sizeof(long));
+	if (bt_reference_check(bt, psw_addr))
+		return;
+
+	fprintf(fp, " PSW:  %016lx %016lx ", psw_flags, psw_addr);
+	sym = closest_symbol(psw_addr);
+	offs = psw_addr - closest_symbol_value(psw_addr);
+	if (module_symbol(psw_addr, NULL, &lm, NULL, 0))
+		fprintf(fp, "(%s+%ld [%s])\n", sym, offs, lm->mod_name);
+	else
+		fprintf(fp, "(%s+%ld)\n", sym, offs);
+
+	addr = sp + MEMBER_OFFSET("pt_regs", "gprs");
+	for (i = 0; i < 16; i++) {
+		if (i != 0 && i % 4 == 0)
+			fprintf(fp, "\n");
+		if (i % 4 == 0) {
+			if (i == 0)
+				fprintf(fp, " GPRS: ");
+			else
+				fprintf(fp, "       ");
+		}
+		fprintf(fp, "%016lx ", readmem_ul(addr + i * sizeof(long)));
+	}
+	fprintf(fp, "\n");
+}
+
+
+/*
  * Print back trace for one stack
  */
 static unsigned long show_trace(struct bt_info *bt, int cnt, unsigned long sp,
@@ -955,8 +1005,7 @@ static unsigned long show_trace(struct b
 		/* Check for loop (kernel_thread_starter) of second zero bc */
 		if (low == reg || reg == 0)
 			return reg;
-		fprintf(fp, " - Interrupt -\n");
-		print_frame(bt, cnt++, sp, psw_addr);
+		print_ptregs(bt, sp);
 		low = sp;
 		sp = reg;
 		cnt = 0;
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux