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