Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/crash/arch tidy up backtrace from crash(9) on aarch64



details:   https://anonhg.NetBSD.org/src/rev/75fc6109bf69
branches:  trunk
changeset: 366613:75fc6109bf69
user:      ryo <ryo%NetBSD.org@localhost>
date:      Thu Jun 02 05:09:01 2022 +0000

description:
tidy up backtrace from crash(9) on aarch64

- fix to dump trapframe when backtracing from crash(8).
- use db_read_bytes() when reading kernel memory.

diffstat:

 sys/arch/aarch64/aarch64/db_trace.c |  103 +++++++++++++++++++++++------------
 usr.sbin/crash/arch/aarch64.c       |   61 +++++++++++++++++++++
 2 files changed, 129 insertions(+), 35 deletions(-)

diffs (240 lines):

diff -r 7ed4ed374fd2 -r 75fc6109bf69 sys/arch/aarch64/aarch64/db_trace.c
--- a/sys/arch/aarch64/aarch64/db_trace.c       Thu Jun 02 01:57:27 2022 +0000
+++ b/sys/arch/aarch64/aarch64/db_trace.c       Thu Jun 02 05:09:01 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.16 2022/05/29 23:43:49 ryo Exp $ */
+/* $NetBSD: db_trace.c,v 1.17 2022/06/02 05:09:01 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.16 2022/05/29 23:43:49 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.17 2022/06/02 05:09:01 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -52,6 +52,15 @@
 #include <ddb/db_extern.h>
 #include <ddb/db_interface.h>
 
+#ifdef _KERNEL
+extern char el0_trap[];
+extern char el1_trap[];
+#else
+/* see also usr.sbin/crash/arch/aarch64.c */
+extern vaddr_t el0_trap;
+extern vaddr_t el1_trap;
+#endif
+
 #define MAXBACKTRACE   128     /* against infinite loop */
 
 
@@ -61,6 +70,31 @@
 #define IN_KERNEL_VM_ADDRESS(addr)     \
        ((VM_MIN_KERNEL_ADDRESS <= (addr)) && ((addr) < VM_MAX_KERNEL_ADDRESS))
 
+static void
+pr_frame(struct trapframe *tf, void (*pr)(const char *, ...) __printflike(1, 2))
+{
+       struct trapframe tf_buf;
+
+       db_read_bytes((db_addr_t)tf, sizeof(tf_buf), (char *)&tf_buf);
+
+       if (tf_buf.tf_sp == 0) {
+               (*pr)("---- switchframe %p (%zu bytes) ----\n",
+                   tf, sizeof(*tf));
+               dump_switchframe(tf, pr);
+       } else {
+#ifdef _KERNEL
+               (*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
+                   (tf_buf.tf_esr == (uint64_t)-1) ? "Interrupt" :
+                   eclass_trapname(__SHIFTOUT(tf_buf.tf_esr, ESR_EC)),
+                   tf, sizeof(*tf));
+#else
+               (*pr)("---- trapframe %p (%zu bytes) ----\n", tf, sizeof(*tf));
+#endif
+               dump_trapframe(tf, pr);
+       }
+       (*pr)("------------------------"
+             "------------------------\n");
+}
 
 static bool __unused
 is_lwp(void *p)
@@ -74,19 +108,44 @@
        return false;
 }
 
+static vaddr_t
+db_lwp_getuarea(lwp_t *l)
+{
+       void *laddr;
+       db_read_bytes((db_addr_t)&l->l_addr, sizeof(laddr), (char *)&laddr);
+       if (laddr == 0)
+               return 0;
+       return (vaddr_t)((char *)laddr - UAREA_PCB_OFFSET);
+}
+
 static const char *
 getlwpnamebysp(uint64_t sp)
 {
-#if defined(_KERNEL)
+       static char c_name[MAXCOMLEN];
        lwp_t *lwp;
+       struct proc *pp;
+       char *lname;
 
        for (lwp = db_lwp_first(); lwp != NULL; lwp = db_lwp_next(lwp)) {
-               uint64_t uarea = uvm_lwp_getuarea(lwp);
+               uint64_t uarea = db_lwp_getuarea(lwp);
                if ((uarea <= sp) && (sp < (uarea + USPACE))) {
-                       return lwp->l_name;
+                       db_read_bytes((db_addr_t)&lwp->l_name, sizeof(lname),
+                           (char *)&lname);
+                       if (lname != NULL) {
+                               db_read_bytes((db_addr_t)lname, sizeof(c_name),
+                           c_name);
+                               return c_name;
+                       }
+                       db_read_bytes((db_addr_t)&lwp->l_proc, sizeof(pp),
+                           (char *)&pp);
+                       if (pp != NULL) {
+                               db_read_bytes((db_addr_t)&pp->p_comm,
+                                   sizeof(c_name), c_name);
+                               return c_name;
+                       }
+                       break;
                }
        }
-#endif
        return "unknown";
 }
 
@@ -253,22 +312,7 @@
                count = MAXBACKTRACE;
 
        if (tf != NULL) {
-#if defined(_KERNEL)
-               if (tf->tf_sp == 0) {
-                       (*pr)("---- switchframe %p (%zu bytes) ----\n",
-                           tf, sizeof(*tf));
-                       dump_switchframe(tf, pr);
-               } else {
-                       (*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
-                           (tf->tf_esr == -1) ? "Interrupt" :
-                           eclass_trapname(__SHIFTOUT(tf->tf_esr, ESR_EC)),
-                           tf, sizeof(*tf));
-                       dump_trapframe(tf, pr);
-               }
-               (*pr)("------------------------"
-                     "------------------------\n");
-
-#endif
+               pr_frame(tf, pr);
                lastfp = lastlr = lr = fp = 0;
 
                db_read_bytes((db_addr_t)&tf->tf_pc, sizeof(lr), (char *)&lr);
@@ -294,9 +338,6 @@
                if (lr == 0 || (!trace_user && IN_USER_VM_ADDRESS(lr)))
                        break;
 
-#if defined(_KERNEL)
-               extern char el1_trap[]; /* XXX */
-               extern char el0_trap[]; /* XXX */
                if (((char *)(lr - 4) == (char *)el0_trap) ||
                    ((char *)(lr - 4) == (char *)el1_trap)) {
 
@@ -327,13 +368,7 @@
                        if (lr == 0)
                                break;
 
-                       (*pr)("---- %s: trapframe %p (%zu bytes) ----\n",
-                           (tf->tf_esr == -1) ? "Interrupt" :
-                           eclass_trapname(__SHIFTOUT(tf->tf_esr, ESR_EC)),
-                           tf, sizeof(*tf));
-                       dump_trapframe(tf, pr);
-                       (*pr)("------------------------"
-                             "------------------------\n");
+                       pr_frame(tf, pr);
                        tf = NULL;
 
                        if (!trace_user && IN_USER_VM_ADDRESS(lr))
@@ -341,9 +376,7 @@
 
                        pr_traceaddr("fp", fp, lr, flags, pr);
 
-               } else
-#endif
-               {
+               } else {
                        pr_traceaddr("fp", fp, lr - 4, flags, pr);
                }
        }
diff -r 7ed4ed374fd2 -r 75fc6109bf69 usr.sbin/crash/arch/aarch64.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/crash/arch/aarch64.c     Thu Jun 02 05:09:01 2022 +0000
@@ -0,0 +1,61 @@
+/*     $NetBSD: aarch64.c,v 1.1 2022/06/02 05:09:01 ryo Exp $  */
+
+/*-
+ * Copyright (c) 2022 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ryo Shimizu.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: aarch64.c,v 1.1 2022/06/02 05:09:01 ryo Exp $");
+#endif /* not lint */
+
+#include <kvm.h>
+#include <nlist.h>
+#include <err.h>
+#include <stdlib.h>
+
+#include "extern.h"
+
+vaddr_t el0_trap;
+vaddr_t el1_trap;
+
+static struct nlist nl[] = {
+       { .n_name = "el0_trap" },       /* 0 */
+       { .n_name = "el1_trap" },       /* 1 */
+       { .n_name = NULL },
+};
+
+void
+db_mach_init(kvm_t *kd)
+{
+       if (kvm_nlist(kd, nl) == -1)
+               errx(EXIT_FAILURE, "kvm_nlist: %s", kvm_geterr(kd));
+
+       el0_trap = nl[0].n_value;
+       el1_trap = nl[1].n_value;
+}



Home | Main Index | Thread Index | Old Index