Module Name: src Committed By: ryo Date: Thu Jun 2 05:09:01 UTC 2022
Modified Files: src/sys/arch/aarch64/aarch64: db_trace.c Added Files: src/usr.sbin/crash/arch: aarch64.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/sys/arch/aarch64/aarch64/db_trace.c cvs rdiff -u -r0 -r1.1 src/usr.sbin/crash/arch/aarch64.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/aarch64/aarch64/db_trace.c diff -u src/sys/arch/aarch64/aarch64/db_trace.c:1.16 src/sys/arch/aarch64/aarch64/db_trace.c:1.17 --- src/sys/arch/aarch64/aarch64/db_trace.c:1.16 Sun May 29 23:43:49 2022 +++ src/sys/arch/aarch64/aarch64/db_trace.c Thu Jun 2 05:09:01 2022 @@ -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 <r...@nerv.org> @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v #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 @@ __CTASSERT(VM_MIN_ADDRESS == 0); #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 @@ is_lwp(void *p) 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 @@ db_stack_trace_print(db_expr_t addr, boo 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 @@ db_stack_trace_print(db_expr_t addr, boo 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 @@ db_stack_trace_print(db_expr_t addr, boo 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 @@ db_stack_trace_print(db_expr_t addr, boo pr_traceaddr("fp", fp, lr, flags, pr); - } else -#endif - { + } else { pr_traceaddr("fp", fp, lr - 4, flags, pr); } } Added files: Index: src/usr.sbin/crash/arch/aarch64.c diff -u /dev/null src/usr.sbin/crash/arch/aarch64.c:1.1 --- /dev/null Thu Jun 2 05:09:01 2022 +++ src/usr.sbin/crash/arch/aarch64.c Thu Jun 2 05:09:01 2022 @@ -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; +}