Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/aarch64 fix to do backtrace properly for running LW...
details: https://anonhg.NetBSD.org/src/rev/6c50d1a7d490
branches: trunk
changeset: 933221:6c50d1a7d490
user: ryo <ryo%NetBSD.org@localhost>
date: Fri May 22 19:29:26 2020 +0000
description:
fix to do backtrace properly for running LWPs and cpu_lwp_fork().
when dump of pcb_tf, only the switchframe part is now displayed instead of the whole trapframe.
diffstat:
sys/arch/aarch64/aarch64/cpuswitch.S | 14 ++++++++-
sys/arch/aarch64/aarch64/db_machdep.c | 40 +++++++++++++++++++++++-----
sys/arch/aarch64/aarch64/db_trace.c | 47 +++++++++++++++++++++++++++++-----
sys/arch/aarch64/aarch64/vm_machdep.c | 11 ++++++-
sys/arch/aarch64/include/db_machdep.h | 3 +-
5 files changed, 94 insertions(+), 21 deletions(-)
diffs (278 lines):
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/cpuswitch.S
--- a/sys/arch/aarch64/aarch64/cpuswitch.S Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/cpuswitch.S Fri May 22 19:29:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.19 2020/05/15 09:08:10 ryo Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.20 2020/05/22 19:29:26 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include "opt_ddb.h"
#include "opt_kasan.h"
-RCSID("$NetBSD: cpuswitch.S,v 1.19 2020/05/15 09:08:10 ryo Exp $")
+RCSID("$NetBSD: cpuswitch.S,v 1.20 2020/05/22 19:29:26 ryo Exp $")
ARMV8_DEFINE_OPTIONS
@@ -60,6 +60,10 @@
stp x25, x26, [sp, #TF_X25]
stp x27, x28, [sp, #TF_X27]
stp x29, x30, [sp, #TF_X29]
+#ifdef DDB
+ str lr, [sp, #TF_PC] /* for backtrace */
+ str xzr, [sp, #TF_SP] /* mark as switchframe */
+#endif
/*
* Save the current stack pointer and the CPACR and save them in
@@ -76,6 +80,9 @@
DISABLE_INTERRUPT
ldr x6, [x1, #L_PCB] /* x6 = lwp_getpcb(newlwp) */
ldr x4, [x6, #PCB_TF] /* get trapframe ptr (aka SP) */
+#ifdef DDB
+ str xzr, [x6, #PCB_TF] /* clear l->l_addr->pcb_tf */
+#endif
ldr x5, [x1, #L_MD_CPACR] /* get cpacr_el1 */
mov sp, x4 /* restore stack pointer */
msr cpacr_el1, x5 /* restore cpacr_el1 */
@@ -190,6 +197,9 @@
str x19, [x3, #CI_CURLWP] /* curcpu()->ci_curlwp := x19 */
ldr x6, [x19, #L_PCB] /* x6 = lwp_getpcb(curlwp) */
ldr x4, [x6, #PCB_TF] /* x4 := pinned_lwp->l_addr->pcb_tf */
+#ifdef DDB
+ str xzr, [x6, #PCB_TF] /* clear l->l_addr->pcb_tf */
+#endif
ldr x5, [x19, #L_MD_CPACR] /* x5 := pinned_lwp->l_md_cpacr */
mov sp, x4 /* restore pinned_lwp sp */
msr cpacr_el1, x5 /* restore pinned_lwp cpacr */
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/db_machdep.c
--- a/sys/arch/aarch64/aarch64/db_machdep.c Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/db_machdep.c Fri May 22 19:29:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.c,v 1.23 2020/05/22 04:46:26 ryo Exp $ */
+/* $NetBSD: db_machdep.c,v 1.24 2020/05/22 19:29:26 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.23 2020/05/22 04:46:26 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.24 2020/05/22 19:29:26 ryo Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd32.h"
@@ -264,6 +264,29 @@
tf->tf_reg[30], tf->tf_sp);
}
+void
+dump_switchframe(struct trapframe *tf, void (*pr)(const char *, ...))
+{
+ struct trapframe tf_buf;
+
+ db_read_bytes((db_addr_t)tf, sizeof(tf_buf), (char *)&tf_buf);
+ tf = &tf_buf;
+
+ (*pr)(" x19=%016"PRIxREGISTER", x20=%016"PRIxREGISTER"\n",
+ tf->tf_reg[19], tf->tf_reg[20]);
+ (*pr)(" x21=%016"PRIxREGISTER", x22=%016"PRIxREGISTER"\n",
+ tf->tf_reg[21], tf->tf_reg[22]);
+ (*pr)(" x23=%016"PRIxREGISTER", x24=%016"PRIxREGISTER"\n",
+ tf->tf_reg[23], tf->tf_reg[24]);
+ (*pr)(" x25=%016"PRIxREGISTER", x26=%016"PRIxREGISTER"\n",
+ tf->tf_reg[25], tf->tf_reg[26]);
+ (*pr)(" x27=%016"PRIxREGISTER", x28=%016"PRIxREGISTER"\n",
+ tf->tf_reg[27], tf->tf_reg[28]);
+ (*pr)("fp=x29=%016"PRIxREGISTER", lr=x30=%016"PRIxREGISTER"\n",
+ tf->tf_reg[29], tf->tf_reg[30]);
+}
+
+
#if defined(_KERNEL)
static void
show_cpuinfo(struct cpu_info *ci)
@@ -373,7 +396,7 @@
db_printf("\tl->l_addr.pcb_tf =%p\n", pcb->pcb_tf);
if (pcb->pcb_tf != l->l_md.md_utf)
- dump_trapframe(pcb->pcb_tf, db_printf);
+ dump_switchframe(pcb->pcb_tf, db_printf);
db_printf("\tl->l_md.md_cpacr =%016" PRIx64 "\n", l->l_md.md_cpacr);
db_printf("\tl->l_md.md_flags =%08x\n", l->l_md.md_flags);
@@ -881,7 +904,7 @@
volatile struct cpu_info *db_trigger;
volatile struct cpu_info *db_onproc;
volatile struct cpu_info *db_newcpu;
-volatile int db_readytoswitch[MAXCPUS];
+volatile struct trapframe *db_readytoswitch[MAXCPUS];
#ifdef _KERNEL
void
@@ -896,8 +919,9 @@
if (!have_addr) {
for (i = 0; i < ncpu; i++) {
- if (db_readytoswitch[i] != 0)
- db_printf("cpu%d: ready\n", i);
+ if (db_readytoswitch[i] != NULL)
+ db_printf("cpu%d: ready. tf=%p\n", i,
+ db_readytoswitch[i]);
else
db_printf("cpu%d: not responding\n", i);
}
@@ -969,7 +993,7 @@
db_trigger = ci;
membar_producer();
}
- db_readytoswitch[ci->ci_index] = 1;
+ db_readytoswitch[ci->ci_index] = tf;
membar_producer();
#endif
@@ -1024,7 +1048,7 @@
__asm __volatile ("sev; sev; sev");
}
db_trigger = NULL;
- db_readytoswitch[ci->ci_index] = 0;
+ db_readytoswitch[ci->ci_index] = NULL;
membar_producer();
#endif
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/db_trace.c
--- a/sys/arch/aarch64/aarch64/db_trace.c Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/db_trace.c Fri May 22 19:29:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.10 2020/05/13 06:08:51 ryo Exp $ */
+/* $NetBSD: db_trace.c,v 1.11 2020/05/22 19:29:26 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.10 2020/05/13 06:08:51 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.11 2020/05/22 19:29:26 ryo Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -208,12 +208,37 @@
} else
#endif
{
+ struct pcb pcb_buf;
struct pcb *pcb = lwp_getpcb(&l);
- tf = pcb->pcb_tf;
- db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
- (*pr)("trace: pid %d lid %d at tf %p\n",
- p.p_pid, l.l_lid, tf);
+ db_read_bytes((db_addr_t)pcb, sizeof(pcb_buf),
+ (char *)&pcb_buf);
+ tf = pcb_buf.pcb_tf;
+ if (tf != 0) {
+ db_read_bytes((db_addr_t)&tf->tf_reg[29],
+ sizeof(fp), (char *)&fp);
+ (*pr)("trace: pid %d lid %d at tf %p (in pcb)\n",
+ p.p_pid, l.l_lid, tf);
+ }
+#if defined(MULTIPROCESSOR) && defined(_KERNEL)
+ else if (l.l_stat == LSONPROC ||
+ (l.l_pflag & LP_RUNNING) != 0) {
+
+ /* running lwp on other cpus */
+ extern struct trapframe *db_readytoswitch[];
+ struct cpu_info cpuinfobuf;
+
+ db_read_bytes((db_addr_t)l.l_cpu,
+ sizeof(cpuinfobuf), (char *)&cpuinfobuf);
+ tf = db_readytoswitch[cpuinfobuf.ci_index];
+
+ (*pr)("trace: pid %d lid %d at tf %p (in kdb_trap)\n",
+ p.p_pid, l.l_lid, tf);
+ }
+#endif
+ else {
+ (*pr)("trace: no trapframe found for lwp: %p\n", (void *)addr);
+ }
}
} else if (tf == NULL) {
fp = addr;
@@ -227,14 +252,20 @@
if (tf != NULL) {
#if defined(_KERNEL)
- (*pr)("---- trapframe %p (%zu bytes) ----\n",
+ bool is_switchframe = (tf->tf_sp == 0);
+ (*pr)("---- %s %p (%zu bytes) ----\n",
+ is_switchframe ? "switchframe" : "trapframe",
tf, sizeof(*tf));
- dump_trapframe(tf, pr);
+ if (is_switchframe)
+ dump_switchframe(tf, pr);
+ else
+ dump_trapframe(tf, pr);
(*pr)("------------------------"
"------------------------\n");
#endif
lastfp = lastlr = lr = fp = 0;
+
db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
db_read_bytes((db_addr_t)&tf->tf_reg[29], sizeof(fp), (char *)&fp);
lr = aarch64_strip_pac(lr);
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/aarch64/vm_machdep.c
--- a/sys/arch/aarch64/aarch64/vm_machdep.c Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/aarch64/vm_machdep.c Fri May 22 19:29:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.6 2020/04/12 07:49:58 maxv Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.7 2020/05/22 19:29:26 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_ddb.h"
+
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.6 2020/04/12 07:49:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.7 2020/05/22 19:29:26 ryo Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -140,6 +142,11 @@
ktf->tf_reg[29] = 0;
KASSERT(reg_daif_read() == 0);
ktf->tf_lr = (uintptr_t)lwp_trampoline;
+#ifdef DDB
+ ktf->tf_pc = (uint64_t)&&backtrace_here;
+ ktf->tf_sp = 0; /* mark as switchframe */
+ backtrace_here:
+#endif
pcb2->pcb_tf = ktf;
}
diff -r ad94ee612503 -r 6c50d1a7d490 sys/arch/aarch64/include/db_machdep.h
--- a/sys/arch/aarch64/include/db_machdep.h Fri May 22 19:02:59 2020 +0000
+++ b/sys/arch/aarch64/include/db_machdep.h Fri May 22 19:29:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.h,v 1.8 2018/10/12 01:28:58 ryo Exp $ */
+/* $NetBSD: db_machdep.h,v 1.9 2020/05/22 19:29:26 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -202,6 +202,7 @@
#define DB_MACHINE_COMMANDS
void dump_trapframe(struct trapframe *, void (*)(const char *, ...));
+void dump_switchframe(struct trapframe *, void (*)(const char *, ...));
const char *strdisasm(vaddr_t);
const char *strdisasm_aarch32(vaddr_t);
void db_machdep_init(void);
Home |
Main Index |
Thread Index |
Old Index