[PATCH v4 2/3] arm64: find a correct starting stackframe at bt

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

 



For example, crash_kexec() calls several sub functions.
So even if we find some address, as a saved lr,  which belongs to this
function, it may not be the *last* stackframe.
For our purpose of backtracing, it is not necessary to find the last
frame, but the saved frame pointer should be sane for later use.

This patch adds some check.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx>
---
 arm64.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/arm64.c b/arm64.c
index 4f85772..5327370 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1893,9 +1893,9 @@ arm64_back_trace_cmd(struct bt_info *bt)
 			arm64_set_irq_stack(bt);
 			bt->flags |= BT_IRQSTACK;
 		}
-		stackframe.fp = GET_STACK_ULONG(bt->bptr - 8);
-		stackframe.pc = GET_STACK_ULONG(bt->bptr);
-		stackframe.sp = bt->bptr + 8;
+		stackframe.fp = GET_STACK_ULONG(bt->bptr);
+		stackframe.pc = GET_STACK_ULONG(bt->bptr + 8);
+		stackframe.sp = bt->bptr + 16;
 		bt->frameptr = stackframe.fp;
 	} else {
 		stackframe.sp = bt->stkptr;
@@ -2051,14 +2051,20 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
 
 	ms = machdep->machspec;
 	for (ptr = start - 8; ptr >= base; ptr--) {
-		if ((*ptr >= ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
-			bt->bptr = ((ulong)ptr - (ulong)base) + bt->tc->thread_info;
+		if ((*ptr >= ms->crash_kexec_start) &&
+		    (*ptr < ms->crash_kexec_end) &&
+		    INSTACK(*(ptr - 1), bt)) {
+			bt->bptr = ((ulong)(ptr - 1) - (ulong)base)
+				   + bt->tc->thread_info;
 			if (CRASHDEBUG(1))
 				fprintf(fp, "%lx: %lx (crash_kexec)\n", bt->bptr, *ptr);
 			return TRUE;
 		}
-		if ((*ptr >= ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
-			bt->bptr = ((ulong)ptr - (ulong)base) + bt->tc->thread_info;
+		if ((*ptr >= ms->crash_save_cpu_start) &&
+		    (*ptr < ms->crash_save_cpu_end) &&
+		    INSTACK(*(ptr - 1), bt)) {
+			bt->bptr = ((ulong)(ptr - 1) - (ulong)base)
+				   + bt->tc->thread_info;
 			if (CRASHDEBUG(1))
 				fprintf(fp, "%lx: %lx (crash_save_cpu)\n", bt->bptr, *ptr);
 			return TRUE;
@@ -2096,16 +2102,20 @@ arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
 	start = (ulong *)(stackbuf + ms->irq_stack_size);
 
 	for (ptr = start - 8; ptr >= base; ptr--) {
-		if ((*ptr >= ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
-			bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
+		if ((*ptr >= ms->crash_kexec_start) &&
+		    (*ptr < ms->crash_kexec_end) &&
+		    INSTACK(*(ptr - 1), bt)) {
+			bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
 			if (CRASHDEBUG(1))
 				fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n", 
 					bt->bptr, *ptr);
 			FREEBUF(stackbuf);
 			return TRUE;
 		}
-		if ((*ptr >= ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
-			bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
+		if ((*ptr >= ms->crash_save_cpu_start) &&
+		    (*ptr < ms->crash_save_cpu_end) &&
+		    INSTACK(*(ptr - 1), bt)) {
+			bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
 			if (CRASHDEBUG(1))
 				fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n", 
 					bt->bptr, *ptr);
-- 
2.9.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