Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/m68k/m68k Fix a problem I noticed a while back but ...



details:   https://anonhg.NetBSD.org/src/rev/dbe06102aaaf
branches:  trunk
changeset: 471542:dbe06102aaaf
user:      scw <scw%NetBSD.org@localhost>
date:      Sun Apr 04 11:33:02 1999 +0000

description:
Fix a problem I noticed a while back but had too many other things
in the air to deal with it.
Basically, following a kernel fault (eg. dereferencing a NULL pointer
in kernel mode) a DDB 'trace' did not show the function where the
fault occurred. For example:

        db> trace
        _Debugger()
        _panic()
        _trap()
        faultstkadj()
        _pool_drain()
        _uvm_pageout()
        _start_pagedaemon()
        _proc_trampoline()
        db>

The 'faultstkadj()' line here is bogus. It is shown because the return
address to 'trap()' happens to point there, and since faultstkadj() has
no stack frame, DDB assumes it was the faulting function. In this example,
the _real_ function was pool_reclaim(), but you would have to look at
the program counter at the time of the fault to figure that one out.

This fix makes the trace command do the dirty work for you by grubbing
around in 'trap()'s argument list to find the *real* PC value at the
time of the fault, replacing the 'faultstkadj()' line with the real
function's name.

diffstat:

 sys/arch/m68k/m68k/db_trace.c |  36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diffs (64 lines):

diff -r 485f10e18cb2 -r dbe06102aaaf sys/arch/m68k/m68k/db_trace.c
--- a/sys/arch/m68k/m68k/db_trace.c     Sun Apr 04 11:02:09 1999 +0000
+++ b/sys/arch/m68k/m68k/db_trace.c     Sun Apr 04 11:33:02 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_trace.c,v 1.23 1999/01/15 23:15:50 thorpej Exp $    */
+/*     $NetBSD: db_trace.c,v 1.24 1999/04/04 11:33:02 scw Exp $        */
 
 /* 
  * Mach Operating System
@@ -99,6 +99,8 @@
 #define        get(addr, space) \
                (db_get_value((db_addr_t)(addr), sizeof(int), FALSE))
 
+#define        offsetof(type, member)  ((size_t)(&((type *)0)->member))
+
 #define        NREGISTERS      16
 
 struct stackpos {
@@ -475,6 +477,7 @@
        char *          name;
        struct stackpos pos;
        boolean_t       kernel_only = TRUE;
+       int             fault_pc = 0;
 
        {
                char *cp = modif;
@@ -535,6 +538,37 @@
                                val = MAXINT;
                        }
                }
+
+               /*
+                * Since faultstkadj doesn't set up a valid stack frame,
+                * we would assume it was the source of the fault. To
+                * get around this we peek at the fourth argument of
+                * "trap()" (the stack frame at the time of the fault)
+                * to determine the _real_ value of PC when things wen
+                * wrong.
+                *
+                * NOTE: If the argument list for 'trap()' ever changes,
+                * we lose.
+                */
+               if ( strcmp("_trap", name) == 0 ) {
+                       /* Point to 'trap()'s argument list */
+                       regp  = pos.k_fp + FR_SAVFP + 4;
+                       /* Step over the arguments to the frame structure */
+                       regp += (4 * 4) + offsetof(struct frame, f_pc);
+                       /* Get the PC at the time of the fault */
+                       fault_pc = get(regp, DSP);
+               } else
+               if ( fault_pc ) {
+                       if ( strcmp("faultstkadj", name) == 0 ) {
+                               db_find_sym_and_offset(fault_pc, &name, &val);
+                               if (name == 0) {
+                                       name = "?";
+                                       val = MAXINT;
+                               }
+                       }
+                       fault_pc = 0;
+               }
+
                db_printf("%s", name);
                if (pos.k_entry != MAXINT && name) {
                        char *  entry_name;



Home | Main Index | Thread Index | Old Index