The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/db_trace.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $FreeBSD: releng/5.1/sys/powerpc/powerpc/db_trace.c 104435 2002-10-04 01:19:18Z grehan $ */
    2 /*      $NetBSD: db_trace.c,v 1.20 2002/05/13 20:30:09 matt Exp $       */
    3 /*      $OpenBSD: db_trace.c,v 1.3 1997/03/21 02:10:48 niklas Exp $     */
    4 
    5 /* 
    6  * Mach Operating System
    7  * Copyright (c) 1992 Carnegie Mellon University
    8  * All Rights Reserved.
    9  * 
   10  * Permission to use, copy, modify and distribute this software and its
   11  * documentation is hereby granted, provided that both the copyright
   12  * notice and this permission notice appear in all copies of the
   13  * software, derivative works or modified versions, and any portions
   14  * thereof, and that both notices appear in supporting documentation.
   15  * 
   16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   18  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  * 
   20  * Carnegie Mellon requests users of this software to return to
   21  * 
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  * 
   27  * any improvements or extensions that they make and grant Carnegie Mellon 
   28  * the rights to redistribute these changes.
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/proc.h>
   34 #include <sys/user.h>
   35 
   36 #include <vm/vm.h>
   37 #include <vm/pmap.h>
   38 #include <vm/vm_extern.h>
   39 
   40 #include <machine/db_machdep.h>
   41 #include <machine/spr.h>
   42 #include <machine/trap.h>
   43 
   44 #include <ddb/ddb.h>
   45 #include <ddb/db_access.h>
   46 #include <ddb/db_sym.h>
   47 #include <ddb/db_variables.h>
   48 
   49 struct db_variable db_regs[] = {
   50         { "r0",  &ddb_regs.r[0],  FCN_NULL },
   51         { "r1",  &ddb_regs.r[1],  FCN_NULL },
   52         { "r2",  &ddb_regs.r[2],  FCN_NULL },
   53         { "r3",  &ddb_regs.r[3],  FCN_NULL },
   54         { "r4",  &ddb_regs.r[4],  FCN_NULL },
   55         { "r5",  &ddb_regs.r[5],  FCN_NULL },
   56         { "r6",  &ddb_regs.r[6],  FCN_NULL },
   57         { "r7",  &ddb_regs.r[7],  FCN_NULL },
   58         { "r8",  &ddb_regs.r[8],  FCN_NULL },
   59         { "r9",  &ddb_regs.r[9],  FCN_NULL },
   60         { "r10", &ddb_regs.r[10], FCN_NULL },
   61         { "r11", &ddb_regs.r[11], FCN_NULL },
   62         { "r12", &ddb_regs.r[12], FCN_NULL },
   63         { "r13", &ddb_regs.r[13], FCN_NULL },
   64         { "r14", &ddb_regs.r[14], FCN_NULL },
   65         { "r15", &ddb_regs.r[15], FCN_NULL },
   66         { "r16", &ddb_regs.r[16], FCN_NULL },
   67         { "r17", &ddb_regs.r[17], FCN_NULL },
   68         { "r18", &ddb_regs.r[18], FCN_NULL },
   69         { "r19", &ddb_regs.r[19], FCN_NULL },
   70         { "r20", &ddb_regs.r[20], FCN_NULL },
   71         { "r21", &ddb_regs.r[21], FCN_NULL },
   72         { "r22", &ddb_regs.r[22], FCN_NULL },
   73         { "r23", &ddb_regs.r[23], FCN_NULL },
   74         { "r24", &ddb_regs.r[24], FCN_NULL },
   75         { "r25", &ddb_regs.r[25], FCN_NULL },
   76         { "r26", &ddb_regs.r[26], FCN_NULL },
   77         { "r27", &ddb_regs.r[27], FCN_NULL },
   78         { "r28", &ddb_regs.r[28], FCN_NULL },
   79         { "r29", &ddb_regs.r[29], FCN_NULL },
   80         { "r30", &ddb_regs.r[30], FCN_NULL },
   81         { "r31", &ddb_regs.r[31], FCN_NULL },
   82         { "iar", &ddb_regs.iar,   FCN_NULL },
   83         { "msr", &ddb_regs.msr,   FCN_NULL },
   84         { "lr",  &ddb_regs.lr,    FCN_NULL },
   85         { "ctr", &ddb_regs.ctr,   FCN_NULL },
   86         { "cr",  &ddb_regs.cr,    FCN_NULL },
   87         { "xer", &ddb_regs.xer,   FCN_NULL },
   88 #ifdef PPC_IBM4XX
   89         { "dear", &ddb_regs.dear, FCN_NULL },
   90         { "esr", &ddb_regs.esr,   FCN_NULL },
   91         { "pid", &ddb_regs.pid,   FCN_NULL },
   92 #endif
   93 };
   94 struct db_variable *db_eregs = db_regs + sizeof (db_regs)/sizeof (db_regs[0]);
   95 
   96 extern int trapexit[];
   97 extern int end[];
   98 
   99 /*
  100  *      Frame tracing.
  101  */
  102 static void
  103 db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count, 
  104                      char *modif, void (*pr)(const char *, ...))
  105 {
  106         db_addr_t frame, lr, caller, *args;
  107         db_addr_t fakeframe[2];
  108         db_expr_t diff;
  109         c_db_sym_t sym;
  110         const char *symname;
  111         boolean_t kernel_only = TRUE;
  112         boolean_t trace_thread = FALSE;
  113         boolean_t full = FALSE;
  114 
  115         {
  116                 register char *cp = modif;
  117                 register char c;
  118 
  119                 while ((c = *cp++) != 0) {
  120                         if (c == 't')
  121                                 trace_thread = TRUE;
  122                         if (c == 'u')
  123                                 kernel_only = FALSE;
  124                         if (c == 'f')
  125                                 full = TRUE;
  126                 }
  127         }
  128 
  129         if (have_addr) {
  130 #if 0
  131                 if (trace_thread) {
  132                         struct proc *p;
  133                         struct user *u;
  134 
  135                         (*pr)("trace: pid %d ", (int)addr);
  136                         p = pfind(addr);
  137                         if (p == NULL) {
  138                                 (*pr)("not found\n");
  139                                 return;
  140                         }       
  141                         if (!(p->p_flag&P_INMEM)) {
  142                                 (*pr)("swapped out\n");
  143                                 return;
  144                         }
  145                         u = p->p_addr;
  146                         frame = (db_addr_t)u->u_pcb.pcb_sp;
  147                         (*pr)("at %p\n", frame);
  148                 } else
  149 #endif
  150                         frame = (db_addr_t)addr;
  151         } else {
  152                 frame = (db_addr_t)ddb_regs.r[1];
  153         }
  154         for (;;) {
  155                 if (frame < PAGE_SIZE)
  156                         break;
  157 #ifdef PPC_MPC6XX
  158                 if (kernel_only &&
  159                     ((frame > (db_addr_t) end &&
  160                       frame < VM_MIN_KERNEL_ADDRESS) ||
  161                      frame >= VM_MAX_KERNEL_ADDRESS))
  162                         break;
  163 #endif 
  164                 frame = *(db_addr_t *)frame;
  165             next_frame:
  166                 args = (db_addr_t *)(frame + 8);
  167                 if (frame < PAGE_SIZE)
  168                         break;
  169 #ifdef PPC_MPC6XX
  170                 if (kernel_only &&
  171                     ((frame > (db_addr_t) end &&
  172                       frame < VM_MIN_KERNEL_ADDRESS) ||
  173                      frame >= VM_MAX_KERNEL_ADDRESS))
  174                         break;
  175 #endif
  176                 if (count-- == 0)
  177                         break;
  178 
  179                 lr = *(db_addr_t *)(frame + 4) - 4;
  180                 if ((lr & 3) || (lr < 0x100)) {
  181                         (*pr)("saved LR(0x%x) is invalid.", lr);
  182                         break;
  183                 }
  184                 if ((caller = (db_addr_t)vtophys(lr)) == 0)
  185                         caller = lr;
  186 
  187                 if (frame != (db_addr_t) fakeframe) {
  188                         (*pr)("0x%08lx: ", frame);
  189                 } else {
  190                         (*pr)("     <?>  : ");
  191                 }
  192                 if (caller + 4 == (db_addr_t) &trapexit) {
  193                         const char *trapstr;
  194                         struct trapframe *tf = (struct trapframe *) (frame+8);
  195                         (*pr)("%s ", tf->srr1 & PSL_PR ? "user" : "kernel");
  196                         switch (tf->exc) {
  197                         case EXC_DSI:
  198 #ifdef PPC_MPC6XX
  199                                 (*pr)("DSI %s trap @ %#x by ",
  200                                     tf->dsisr & DSISR_STORE ? "write" : "read",
  201                                     tf->dar);
  202 #endif
  203 #ifdef PPC_IBM4XX
  204                                 (*pr)("DSI %s trap @ %#x by ",
  205                                     tf->esr & ESR_DST ? "write" : "read",
  206                                     tf->dear);
  207 #endif
  208                                 goto print_trap;
  209                         case EXC_ISI: trapstr = "ISI"; break;
  210                         case EXC_PGM: trapstr = "PGM"; break;
  211                         case EXC_SC: trapstr = "SC"; break;
  212                         case EXC_EXI: trapstr = "EXI"; break;
  213                         case EXC_MCHK: trapstr = "MCHK"; break;
  214                         case EXC_VEC: trapstr = "VEC"; break;
  215                         case EXC_FPU: trapstr = "FPU"; break;
  216                         case EXC_FPA: trapstr = "FPA"; break;
  217                         case EXC_DECR: trapstr = "DECR"; break;
  218                         case EXC_ALI: trapstr = "ALI"; break;
  219                         case EXC_BPT: trapstr = "BPT"; break;
  220                         case EXC_TRC: trapstr = "TRC"; break;
  221                         case EXC_RUNMODETRC: trapstr = "RUNMODETRC"; break;
  222                         case EXC_PERF: trapstr = "PERF"; break;
  223                         case EXC_SMI: trapstr = "SMI"; break;
  224                         case EXC_RST: trapstr = "RST"; break;
  225                         default: trapstr = NULL; break;
  226                         }
  227                         if (trapstr != NULL) {
  228                                 (*pr)("%s trap by ", trapstr);
  229                         } else {
  230                                 (*pr)("trap %#x by ", tf->exc);
  231                         }
  232                    print_trap:  
  233                         lr = (db_addr_t) tf->srr0;
  234                         if ((caller = (db_addr_t)vtophys(lr)) == 0)
  235                                 caller = lr;
  236                         diff = 0;
  237                         symname = NULL;
  238                         sym = db_search_symbol(caller, DB_STGY_ANY, &diff);
  239                         db_symbol_values(sym, &symname, 0);
  240                         if (symname == NULL || !strcmp(symname, "end")) {
  241                                 (*pr)("%p: srr1=%#x\n", caller, tf->srr1);
  242                         } else {
  243                                 (*pr)("%s+%x: srr1=%#x\n", symname, diff,
  244                                     tf->srr1);
  245                         }
  246                         (*pr)("%-10s  r1=%#x cr=%#x xer=%#x ctr=%#x",
  247                             "", tf->fixreg[1], tf->cr, tf->xer, tf->ctr);
  248 #ifdef PPC_MPC6XX
  249                         if (tf->exc == EXC_DSI)
  250                                 (*pr)(" dsisr=%#x", tf->dsisr);
  251 #endif
  252 #ifdef PPC_IBM4XX
  253                         if (tf->exc == EXC_DSI)
  254                                 (*pr)(" dear=%#x", tf->dear);
  255                         (*pr)(" esr=%#x pid=%#x", tf->esr, tf->pid);
  256 #endif
  257                         (*pr)("\n");
  258                         fakeframe[0] = (db_addr_t) tf->fixreg[1];
  259                         fakeframe[1] = (db_addr_t) tf->lr;
  260                         frame = (db_addr_t) fakeframe;
  261                         if (kernel_only && (tf->srr1 & PSL_PR))
  262                                 break;
  263                         goto next_frame;
  264                 }
  265 
  266                 diff = 0;
  267                 symname = NULL;
  268                 sym = db_search_symbol(caller, DB_STGY_ANY, &diff);
  269                 db_symbol_values(sym, &symname, 0);
  270                 if (symname == NULL || !strcmp(symname, "end"))
  271                         (*pr)("at %p", caller);
  272                 else
  273                         (*pr)("at %s+%#x", symname, diff);
  274                 if (full)
  275                         /* Print all the args stored in that stackframe. */
  276                         (*pr)("(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)",
  277                                 args[0], args[1], args[2], args[3],
  278                                 args[4], args[5], args[6], args[7]);
  279                 (*pr)("\n");
  280         }
  281 }
  282 
  283 void
  284 db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
  285     char *modif)
  286 {
  287 
  288         db_stack_trace_print(addr, have_addr, count, modif, db_printf);
  289 }
  290 
  291 void
  292 db_print_backtrace(void)
  293 {
  294 }

Cache object: bc310ff32c0ab7e1737eb106c492fefb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.