180 lines
5.7 KiB
Diff
180 lines
5.7 KiB
Diff
From 0c14080b7d7bacadba3611568bd87b347677fa12 Mon Sep 17 00:00:00 2001
|
|
From: Tao Liu <ltao@redhat.com>
|
|
Date: Wed, 25 Jun 2025 16:02:03 +1200
|
|
Subject: [PATCH 7/9] ppc64: Add gdb multi-stack unwind support
|
|
|
|
Please note, there is a known issue which some ppc cannot stack unwind
|
|
successfully as:
|
|
|
|
crash> bt
|
|
PID: 2 TASK: c000000004797f80 CPU: 0 COMMAND: "kthreadd"
|
|
#0 [c00000000484fbc0] _end at c00000000484fd70 (unreliable)
|
|
#1 [c00000000484fd70] __switch_to at c00000000001fabc
|
|
#2 [c00000000484fdd0] __schedule at c0000000011ca9dc
|
|
#3 [c00000000484feb0] schedule at c0000000011caeb0
|
|
#4 [c00000000484ff20] kthreadd at c0000000001af6c4
|
|
#5 [c00000000484ffe0] start_kernel_thread at c00000000000ded8
|
|
crash> gdb bt
|
|
#0 0xc00000000484fd70 in ?? ()
|
|
gdb: gdb request failed: bt
|
|
|
|
This has nothing to do with bt/gdb bt, see root cause in [1][2].
|
|
|
|
[1]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01124.html
|
|
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01139.html
|
|
|
|
Co-developed-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
|
|
Co-developed-by: Tao Liu <ltao@redhat.com>
|
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
|
---
|
|
ppc64.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 64 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/ppc64.c b/ppc64.c
|
|
index 532eb3f..d1a5067 100644
|
|
--- a/ppc64.c
|
|
+++ b/ppc64.c
|
|
@@ -2053,6 +2053,7 @@ ppc64_back_trace_cmd(struct bt_info *bt)
|
|
char buf[BUFSIZE];
|
|
struct gnu_request *req;
|
|
extern void print_stack_text_syms(struct bt_info *, ulong, ulong);
|
|
+ extra_stacks_idx = 0;
|
|
|
|
bt->flags |= BT_EXCEPTION_FRAME;
|
|
|
|
@@ -2071,6 +2072,29 @@ ppc64_back_trace_cmd(struct bt_info *bt)
|
|
req->pc = bt->instptr;
|
|
req->sp = bt->stkptr;
|
|
|
|
+ if (is_task_active(bt->task)) {
|
|
+ if (!extra_stacks_regs[extra_stacks_idx]) {
|
|
+ extra_stacks_regs[extra_stacks_idx] =
|
|
+ (struct user_regs_bitmap_struct *)
|
|
+ malloc(sizeof(struct user_regs_bitmap_struct));
|
|
+ }
|
|
+ memset(extra_stacks_regs[extra_stacks_idx], 0,
|
|
+ sizeof(struct user_regs_bitmap_struct));
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.nip = req->pc;
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.gpr[1] = req->sp;
|
|
+ SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
|
|
+ REG_SEQ(ppc64_pt_regs, nip));
|
|
+ SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
|
|
+ REG_SEQ(ppc64_pt_regs, gpr[0]) + 1);
|
|
+ if (!bt->machdep ||
|
|
+ (extra_stacks_regs[extra_stacks_idx]->ur.gpr[1] !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.gpr[1] &&
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.nip !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.nip)) {
|
|
+ gdb_add_substack (extra_stacks_idx++);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (bt->flags &
|
|
(BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)) {
|
|
if (!INSTACK(req->sp, bt))
|
|
@@ -2512,6 +2536,28 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
|
|
fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
|
|
ppc64_print_regs(regs);
|
|
ppc64_print_nip_lr(regs, 1);
|
|
+
|
|
+ if (!((regs->msr >> MSR_PR_LG) & 0x1) &&
|
|
+ !(bt->flags & BT_EFRAME_SEARCH)) {
|
|
+ if (!extra_stacks_regs[extra_stacks_idx]) {
|
|
+ extra_stacks_regs[extra_stacks_idx] =
|
|
+ (struct user_regs_bitmap_struct *)
|
|
+ malloc(sizeof(struct user_regs_bitmap_struct));
|
|
+ }
|
|
+ memset(extra_stacks_regs[extra_stacks_idx], 0,
|
|
+ sizeof(struct user_regs_bitmap_struct));
|
|
+ memcpy(&extra_stacks_regs[extra_stacks_idx]->ur, regs,
|
|
+ sizeof(struct ppc64_pt_regs));
|
|
+ for (int i = 0; i < sizeof(struct ppc64_pt_regs)/sizeof(ulong); i++)
|
|
+ SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, i);
|
|
+ if (!bt->machdep ||
|
|
+ (extra_stacks_regs[extra_stacks_idx]->ur.gpr[1] !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.gpr[1] &&
|
|
+ extra_stacks_regs[extra_stacks_idx]->ur.nip !=
|
|
+ ((struct user_regs_bitmap_struct *)(bt->machdep))->ur.nip)) {
|
|
+ gdb_add_substack (extra_stacks_idx++);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
static int
|
|
@@ -2552,6 +2598,12 @@ ppc64_get_current_task_reg(int regno, const char *name, int size,
|
|
tc = CURRENT_CONTEXT();
|
|
if (!tc)
|
|
return FALSE;
|
|
+
|
|
+ if (sid && sid <= extra_stacks_idx) {
|
|
+ ur_bitmap = extra_stacks_regs[sid - 1];
|
|
+ goto get_sub;
|
|
+ }
|
|
+
|
|
BZERO(&bt_setup, sizeof(struct bt_info));
|
|
clone_bt_info(&bt_setup, &bt_info, tc);
|
|
fill_stackbuf(&bt_info);
|
|
@@ -2570,39 +2622,45 @@ ppc64_get_current_task_reg(int regno, const char *name, int size,
|
|
goto get_all;
|
|
}
|
|
|
|
+get_sub:
|
|
switch (regno) {
|
|
case PPC64_R0_REGNUM ... PPC64_R31_REGNUM:
|
|
if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
|
|
REG_SEQ(ppc64_pt_regs, gpr[0]) + regno - PPC64_R0_REGNUM)) {
|
|
- FREEBUF(ur_bitmap);
|
|
+ if (!sid)
|
|
+ FREEBUF(ur_bitmap);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case PPC64_PC_REGNUM:
|
|
if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
|
|
REG_SEQ(ppc64_pt_regs, nip))) {
|
|
- FREEBUF(ur_bitmap);
|
|
+ if (!sid)
|
|
+ FREEBUF(ur_bitmap);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case PPC64_MSR_REGNUM:
|
|
if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
|
|
REG_SEQ(ppc64_pt_regs, msr))) {
|
|
- FREEBUF(ur_bitmap);
|
|
+ if (!sid)
|
|
+ FREEBUF(ur_bitmap);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case PPC64_LR_REGNUM:
|
|
if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
|
|
REG_SEQ(ppc64_pt_regs, link))) {
|
|
- FREEBUF(ur_bitmap);
|
|
+ if (!sid)
|
|
+ FREEBUF(ur_bitmap);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case PPC64_CTR_REGNUM:
|
|
if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
|
|
REG_SEQ(ppc64_pt_regs, ctr))) {
|
|
- FREEBUF(ur_bitmap);
|
|
+ if (!sid)
|
|
+ FREEBUF(ur_bitmap);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
@@ -2645,7 +2703,7 @@ get_all:
|
|
ret = TRUE;
|
|
break;
|
|
}
|
|
- if (bt_info.need_free) {
|
|
+ if (!sid && bt_info.need_free) {
|
|
FREEBUF(ur_bitmap);
|
|
bt_info.need_free = FALSE;
|
|
}
|
|
--
|
|
2.47.0
|
|
|