Module Name: src
Committed By: simonb
Date: Wed Sep 23 09:52:02 UTC 2020
Modified Files:
src/sys/arch/mips/mips: mips_stacktrace.c
src/sys/kern: kern_ksyms.c
src/sys/sys: ksyms.h
Log Message:
The current MIPS DDB stacktrace code doesn't work if no symbols are
available, so fall back to old-fashioned unwind code if no symbols.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/mips/mips/mips_stacktrace.c
cvs rdiff -u -r1.88 -r1.89 src/sys/kern/kern_ksyms.c
cvs rdiff -u -r1.37 -r1.38 src/sys/sys/ksyms.h
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/mips/mips/mips_stacktrace.c
diff -u src/sys/arch/mips/mips/mips_stacktrace.c:1.4 src/sys/arch/mips/mips/mips_stacktrace.c:1.5
--- src/sys/arch/mips/mips/mips_stacktrace.c:1.4 Mon Aug 17 21:50:14 2020
+++ src/sys/arch/mips/mips/mips_stacktrace.c Wed Sep 23 09:52:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_stacktrace.c,v 1.4 2020/08/17 21:50:14 mrg Exp $ */
+/* $NetBSD: mips_stacktrace.c,v 1.5 2020/09/23 09:52:02 simonb Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.4 2020/08/17 21:50:14 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_stacktrace.c,v 1.5 2020/09/23 09:52:02 simonb Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -322,60 +322,66 @@ loop:
}
#ifdef DDB
- /*
- * Check the kernel symbol table to see the beginning of
- * the current subroutine.
- */
- diff = 0;
- sym = db_search_symbol(pc, DB_STGY_ANY, &diff);
- if (sym != DB_SYM_NULL && diff == 0) {
- /* check func(foo) __attribute__((__noreturn__)) case */
- if (!kdbpeek(pc - 2 * sizeof(unsigned), &instr))
- return;
- i.word = instr;
- if (i.JType.op == OP_JAL) {
- sym = db_search_symbol(pc - sizeof(int),
- DB_STGY_ANY, &diff);
- if (sym != DB_SYM_NULL && diff != 0)
- diff += sizeof(int);
+ if (ksyms_available()) {
+ /*
+ * Check the kernel symbol table to see the beginning of
+ * the current subroutine.
+ */
+ diff = 0;
+ sym = db_search_symbol(pc, DB_STGY_ANY, &diff);
+ if (sym != DB_SYM_NULL && diff == 0) {
+ /* check func(foo) __attribute__((__noreturn__)) case */
+ if (!kdbpeek(pc - 2 * sizeof(unsigned), &instr))
+ return;
+ i.word = instr;
+ if (i.JType.op == OP_JAL) {
+ sym = db_search_symbol(pc - sizeof(int),
+ DB_STGY_ANY, &diff);
+ if (sym != DB_SYM_NULL && diff != 0)
+ diff += sizeof(int);
+ }
}
- }
- if (sym == DB_SYM_NULL) {
- ra = 0;
- goto done;
- }
- va = pc - diff;
-#else
- /*
- * Find the beginning of the current subroutine by scanning backwards
- * from the current PC for the end of the previous subroutine.
- *
- * XXX This won't work well because nowadays gcc is so aggressive
- * as to reorder instruction blocks for branch-predict.
- * (i.e. 'jr ra' wouldn't indicate the end of subroutine)
- */
- va = pc;
- do {
- va -= sizeof(int);
- if (va <= (vaddr_t)verylocore)
- goto finish;
- if (!kdbpeek(va, &instr))
- return;
- if (instr == MIPS_ERET)
- goto mips3_eret;
- } while (instr != MIPS_JR_RA && instr != MIPS_JR_K0);
- /* skip back over branch & delay slot */
- va += sizeof(int);
+ if (sym == DB_SYM_NULL) {
+ ra = 0;
+ goto done;
+ }
+ va = pc - diff;
+ } else {
+#endif /* DDB */
+ /*
+ * Find the beginning of the current subroutine by
+ * scanning backwards from the current PC for the end
+ * of the previous subroutine.
+ *
+ * XXX This won't work well because nowadays gcc is so
+ * aggressive as to reorder instruction blocks for
+ * branch-predict. (i.e. 'jr ra' wouldn't indicate
+ * the end of subroutine)
+ */
+ va = pc;
+ do {
+ va -= sizeof(int);
+ if (va <= (vaddr_t)verylocore)
+ goto finish;
+ if (!kdbpeek(va, &instr))
+ return;
+ if (instr == MIPS_ERET)
+ goto mips3_eret;
+ } while (instr != MIPS_JR_RA && instr != MIPS_JR_K0);
+ /* skip back over branch & delay slot */
+ va += sizeof(int);
mips3_eret:
- va += sizeof(int);
- /* skip over nulls which might separate .o files */
- instr = 0;
- while (instr == 0) {
- if (!kdbpeek(va, &instr))
- return;
va += sizeof(int);
+ /* skip over nulls which might separate .o files */
+ instr = 0;
+ while (instr == 0) {
+ if (!kdbpeek(va, &instr))
+ return;
+ va += sizeof(int);
+ }
+#ifdef DDB
}
-#endif
+#endif /* DDB */
subr = va;
/* scan forwards to find stack size and any saved registers */
Index: src/sys/kern/kern_ksyms.c
diff -u src/sys/kern/kern_ksyms.c:1.88 src/sys/kern/kern_ksyms.c:1.89
--- src/sys/kern/kern_ksyms.c:1.88 Sun Jan 5 21:12:34 2020
+++ src/sys/kern/kern_ksyms.c Wed Sep 23 09:52:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_ksyms.c,v 1.88 2020/01/05 21:12:34 pgoyette Exp $ */
+/* $NetBSD: kern_ksyms.c,v 1.89 2020/09/23 09:52:02 simonb Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.88 2020/01/05 21:12:34 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.89 2020/09/23 09:52:02 simonb Exp $");
#if defined(_KERNEL) && defined(_KERNEL_OPT)
#include "opt_copy_symtab.h"
@@ -247,6 +247,16 @@ ksyms_init(void)
}
/*
+ * Are any symbols available?
+ */
+bool
+ksyms_available(void)
+{
+
+ return ksyms_loaded;
+}
+
+/*
* Add a symbol table.
* This is intended for use when the symbol table and its corresponding
* string table are easily available. If they are embedded in an ELF
Index: src/sys/sys/ksyms.h
diff -u src/sys/sys/ksyms.h:1.37 src/sys/sys/ksyms.h:1.38
--- src/sys/sys/ksyms.h:1.37 Mon Nov 6 17:56:25 2017
+++ src/sys/sys/ksyms.h Wed Sep 23 09:52:02 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ksyms.h,v 1.37 2017/11/06 17:56:25 christos Exp $ */
+/* $NetBSD: ksyms.h,v 1.38 2020/09/23 09:52:02 simonb Exp $ */
/*
* Copyright (c) 2001, 2003 Anders Magnusson ([email protected]).
@@ -144,6 +144,7 @@ int ksyms_delsymtab(const char *);
void ksyms_init(void);
void ksyms_addsyms_elf(int, void *, void *);
void ksyms_addsyms_explicit(void *, void *, size_t, void *, size_t);
+bool ksyms_available(void);
int ksyms_sift(char *, char *, int);
void ksyms_modload(const char *, void *, vsize_t, char *, vsize_t);
void ksyms_modunload(const char *);