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 (ra...@ludd.luth.se).
@@ -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 *);

Reply via email to