Source-Changes-HG archive

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

[src/trunk]: src/sys/sys The current MIPS DDB stacktrace code doesn't work if...



details:   https://anonhg.NetBSD.org/src/rev/c67f154eea82
branches:  trunk
changeset: 955197:c67f154eea82
user:      simonb <simonb%NetBSD.org@localhost>
date:      Wed Sep 23 09:52:02 2020 +0000

description:
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.

diffstat:

 sys/arch/mips/mips/mips_stacktrace.c |  114 ++++++++++++++++++----------------
 sys/kern/kern_ksyms.c                |   14 +++-
 sys/sys/ksyms.h                      |    3 +-
 3 files changed, 74 insertions(+), 57 deletions(-)

diffs (189 lines):

diff -r 28f0d5104726 -r c67f154eea82 sys/arch/mips/mips/mips_stacktrace.c
--- a/sys/arch/mips/mips/mips_stacktrace.c      Wed Sep 23 08:11:28 2020 +0000
+++ b/sys/arch/mips/mips/mips_stacktrace.c      Wed Sep 23 09:52:02 2020 +0000
@@ -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 @@
        }
 
 #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;
                }
-       }
-       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);
+               }
+#ifdef DDB
        }
-       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);
-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);
-       }
-#endif
+#endif /* DDB */
        subr = va;
 
        /* scan forwards to find stack size and any saved registers */
diff -r 28f0d5104726 -r c67f154eea82 sys/kern/kern_ksyms.c
--- a/sys/kern/kern_ksyms.c     Wed Sep 23 08:11:28 2020 +0000
+++ b/sys/kern/kern_ksyms.c     Wed Sep 23 09:52:02 2020 +0000
@@ -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 @@
 }
 
 /*
+ * 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
diff -r 28f0d5104726 -r c67f154eea82 sys/sys/ksyms.h
--- a/sys/sys/ksyms.h   Wed Sep 23 08:11:28 2020 +0000
+++ b/sys/sys/ksyms.h   Wed Sep 23 09:52:02 2020 +0000
@@ -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 (ragge%ludd.luth.se@localhost).
@@ -144,6 +144,7 @@
 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 *);



Home | Main Index | Thread Index | Old Index