[Crash-utility] [PATCH v2 4/5] arm64: Add gdb multi-stack unwind support

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

 



Co-developed-by: Alexey Makhalov <alexey.makhalov@xxxxxxxxxxxx>
Co-developed-by: Tao Liu <ltao@xxxxxxxxxx>
Signed-off-by: Tao Liu <ltao@xxxxxxxxxx>
---
 arm64.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 75 insertions(+), 4 deletions(-)

diff --git a/arm64.c b/arm64.c
index 8291301..53cbf48 100644
--- a/arm64.c
+++ b/arm64.c
@@ -226,6 +226,12 @@ arm64_get_current_task_reg(int regno, const char *name,
 	tc = CURRENT_CONTEXT();
 	if (!tc)
 		return FALSE;
+
+	if (sid && sid <= extra_stacks_idx) {
+		ur_bitmap = extra_stacks_regs[extra_stacks_idx - 1];
+		goto get_sub;
+	}
+
 	BZERO(&bt_setup, sizeof(struct bt_info));
 	clone_bt_info(&bt_setup, &bt_info, tc);
 	fill_stackbuf(&bt_info);
@@ -241,25 +247,29 @@ arm64_get_current_task_reg(int regno, const char *name,
 		goto get_all;
 	}
 
+get_sub:
 	switch (regno) {
 	case X0_REGNUM ... X30_REGNUM:
 		if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
 		    REG_SEQ(arm64_pt_regs, regs[0]) + regno - X0_REGNUM)) {
-			FREEBUF(ur_bitmap);
+			if (!sid)
+				FREEBUF(ur_bitmap);
 			return FALSE;
 		}
 		break;
 	case SP_REGNUM:
 		if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
 		    REG_SEQ(arm64_pt_regs, sp))) {
-			FREEBUF(ur_bitmap);
+			if (!sid)
+				FREEBUF(ur_bitmap);
 			return FALSE;
 		}
 		break;
 	case PC_REGNUM:
 		if (!NUM_IN_BITMAP(ur_bitmap->bitmap,
 		    REG_SEQ(arm64_pt_regs, pc))) {
-			FREEBUF(ur_bitmap);
+			if (!sid)
+				FREEBUF(ur_bitmap);
 			return FALSE;
 		}
 		break;
@@ -287,7 +297,7 @@ get_all:
 		break;
 	}
 
-	if (bt_info.need_free) {
+	if (!sid && bt_info.need_free) {
 		FREEBUF(ur_bitmap);
 		bt_info.need_free = FALSE;
 	}
@@ -3680,6 +3690,7 @@ arm64_back_trace_cmd(struct bt_info *bt)
 	int level;
 	ulong exception_frame;
 	FILE *ofp;
+	extra_stacks_idx = 0;
 
 	if (bt->flags & BT_OPT_BACK_TRACE) {
 		if (machdep->flags & UNW_4_14) {
@@ -3733,6 +3744,29 @@ arm64_back_trace_cmd(struct bt_info *bt)
 		stackframe.fp = bt->frameptr;
 	}
 
+	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));
+		if (bt->task != tt->panic_task && stackframe.sp) {
+			readmem(stackframe.sp - 8, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.pc,
+				sizeof(ulong), "extra_stacks_regs.pc", RETURN_ON_ERROR);
+			readmem(stackframe.sp - 16, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.sp,
+				sizeof(ulong), "extra_stacks_regs.sp", RETURN_ON_ERROR);
+		} else {
+			extra_stacks_regs[extra_stacks_idx]->ur.pc = stackframe.pc;
+			extra_stacks_regs[extra_stacks_idx]->ur.sp = stackframe.sp;
+		}
+		SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+			REG_SEQ(arm64_pt_regs, pc));
+		SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+			REG_SEQ(arm64_pt_regs, sp));
+		gdb_add_substack (extra_stacks_idx++);
+	}
+
 	if (bt->flags & BT_TEXT_SYMBOLS) {
 		arm64_print_text_symbols(bt, &stackframe, ofp);
                 if (BT_REFERENCE_FOUND(bt)) {
@@ -3854,6 +3888,29 @@ arm64_back_trace_cmd_v2(struct bt_info *bt)
 		stackframe.fp = bt->frameptr;
 	}
 
+	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));
+		if (bt->task != tt->panic_task && stackframe.sp) {
+			readmem(stackframe.sp - 8, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.pc,
+				sizeof(ulong), "extra_stacks_regs.pc", RETURN_ON_ERROR);
+			readmem(stackframe.sp - 16, KVADDR, &extra_stacks_regs[extra_stacks_idx]->ur.sp,
+				sizeof(ulong), "extra_stacks_regs.sp", RETURN_ON_ERROR);
+		} else {
+			extra_stacks_regs[extra_stacks_idx]->ur.pc = stackframe.pc;
+			extra_stacks_regs[extra_stacks_idx]->ur.sp = stackframe.sp;
+		}
+		SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+			REG_SEQ(arm64_pt_regs, pc));
+		SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap,
+			REG_SEQ(arm64_pt_regs, sp));
+		gdb_add_substack (extra_stacks_idx++);
+	}
+
 	if (bt->flags & BT_TEXT_SYMBOLS) {
 		arm64_print_text_symbols(bt, &stackframe, ofp);
                 if (BT_REFERENCE_FOUND(bt)) {
@@ -4468,6 +4525,20 @@ arm64_print_exception_frame(struct bt_info *bt, ulong pt_regs, int mode, FILE *o
 			fprintf(ofp, "ORIG_X0: %016lx  SYSCALLNO: %lx",
 				(ulong)regs->orig_x0, (ulong)regs->syscallno);
 			fprintf(ofp, "  PSTATE: %08lx\n", (ulong)regs->pstate);
+		} else if (!bt->machdep ||
+			   regs->pc != ((struct user_regs_bitmap_struct *)bt->machdep)->ur.pc) {
+			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 arm64_pt_regs));
+			for (int i = 0; i < sizeof(struct arm64_pt_regs)/sizeof(long); i++)
+				SET_BIT(extra_stacks_regs[extra_stacks_idx]->bitmap, i);
+			gdb_add_substack (extra_stacks_idx++);
 		}
 	}
 
-- 
2.47.0
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




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

 

Powered by Linux