📄 debug.c
字号:
{ XPR_RPC|XPR_NFS, "nfsrpc" }, { XPR_SIGNAL, "signal" }, { XPR_SM, "shared memory" }, { XPR_TLB|XPR_SCHED|XPR_PROCESS |XPR_EXEC|XPR_SYSCALL|XPR_TRAP |XPR_NOFAULT|XPR_VM|XPR_SWAP |XPR_SWTCH|XPR_RMAP|XPR_TEXT |XPR_SIGNAL, "kernel" }, { 0, NULL }};struct xprbuf *xprbase, *xprptr, *xprend;int xprsize=0x10000, xprinitflag;unsigned xpr_flags = 0;int askme;char *index();unsigned clkticks;extern struct kernargs kernargs[];/* * xprinit: initialize xprintf buffer. The minimum buffer size is one * page. If debugging is not enabled, no buffers are allocated. The * first physical page beyond the xprintf buffers is returned. Xprbufs * are assumed to mapped virtual = physical. * Note that xpr buffers are uncached. */xprinit(fpage){ register int i, j; extern char xpr_addr; xprbase = (struct xprbuf *)PHYS_TO_K1((unsigned)ptob(fpage)); xprptr = xprbase; if (!xprsize) xprsize = 1*NBPG; /* Clear out the buffer */ fpage += btoc(xprsize); xprend = (struct xprbuf *)PHYS_TO_K1(ptob(fpage)) - 1;#ifndef SABLE bzero(xprbase, (char *)xprend - (char *)xprbase);#endif xprsize /= sizeof(struct xprbuf); xprinitflag = 1; return(fpage);}/* * Store a pointer (msg) and up to 3 arguments into the circular xpr buffer. * msg is assumed to be a pointer into the kernel text segment (which * does not change after boot time) and all arguments are assumed to be * non-pointers. The printf string processing is delayed until the buffer * is dumped. */xprintf(msg, arg1, arg2, arg3, arg4)char *msg;{ register struct xprbuf *xp; register int s; extern int cur_pid; extern int cur_tlbpid; if (xprinitflag == 0) return; s = splhigh(); xp = xprptr; xp->xp_msg = msg; xp->xp_arg1 = arg1; xp->xp_arg2 = arg2; xp->xp_arg3 = arg3; xp->xp_arg4 = arg4; xp->xp_timestamp = clkticks; xp->xp_pid = cur_pid; xp->xp_tlbpid = cur_tlbpid; if (++xprptr >= xprend) xprptr = xprbase; splx(s);}xprdump(){ xprtail(xprsize);}/* * Dump the current xprbuf. This is generally called after the system has * crashed (from the monitor). The string processing for xprintf calls * is done here via dprintf which doesn't call xprintf. */xprtail(lines)unsigned lines;{ register struct xprbuf *xp; register int i; if (!xprinitflag) dprintf("Buffer not initialized.\n"); else { if (lines > xprsize) lines = xprsize; xp = xprptr - lines; if (xp < xprbase) xp += xprsize; dprintf("pid / tlb @ ticks: message\n"); for(i = 0; i < lines; i++) { if (xp->xp_msg) { dprintf("%d / %x @ %d:\t", xp->xp_pid, xp->xp_tlbpid, xp->xp_timestamp); dprintf(xp->xp_msg, xp->xp_arg1, xp->xp_arg2, xp->xp_arg3, xp->xp_arg4); if (xp->xp_msg[strlen(xp->xp_msg)-1] != '\n') dprintf("\n"); } if (++xp >= xprend) xp = xprbase; } dprintf("Done\n"); }}#ifdef notdef#include "../h/msgbuf.h"/* * dump the contents of the msgbuf from the monitor */msgdump(){ register char *msgptr, *msgend; register int i, c; if (pmsgbuf->msg_magic != MSG_MAGIC) { dprintf("msgbuf not initialized\n"); return; } dprintf("msgbuf buffer: pmsgbuf=0x%x\n", pmsgbuf); msgptr = &(pmsgbuf->msg_bufc[pmsgbuf->msg_bufx]); msgend = &(pmsgbuf->msg_bufc[MSG_BSIZE]); for(i=0; i < MSG_BSIZE; i++) { if (msgptr >= msgend) msgptr = pmsgbuf->msg_bufc; if (c = *msgptr++) dprintf("%c", c); } dprintf("Done\n");}#endif notdefassfail(ass, file, line)char *ass, file;int line;{ printf("ASSERTION %s FAILED in file %s at line %d\n", ass, file, line); panic("ASSERTION");}/* * getargs(argc, argv) * * 1. loop through the arg list: * * 1a. if switch is "init="name, name is the file with the image of the * init process * * 1b. if switch is "-"x, copy the switch from the boot stack to kernel * space so it can be passed to init process * * 1c. if switch is sw"="n, set kernel flag sw to number n; if "="n is * omitted, set to 1 * */getargs(argc, argv, environ)char *argv[];char *environ[];{ register struct kernargs *kp; register int i; register char *cp; register char **argp;#ifdef ultrix argp = 0; /* environ is junk on ultrix */ if ((u_int)argv <= (u_int)K1BASE || (u_int)argv >= (u_int)(K1BASE + 0x20000)) { cprintf("getargs: bad argv from prom 0x%x\n",argv); return; }#else oldmips argp = environ;#endif ultrixloop: for (; argp && *argp; argp++) { if (strncmp("init=", *argp, 5) == 0) { extern char icode_file[]; dprintf("Using %s for /etc/init\n", &(*argp)[5]); strcpy(icode_file, &(*argp)[5]); continue; } if (**argp == '-') { extern char *icode_args[]; extern char *icode_argv[]; extern int icode_argc[];/* dprintf("/etc/init arg: %s\n", *argp); */ cp = *argp; /* * Relocate in line here */ icode_argv[icode_argc[0]++] = (char *)(icode_args[0] - (char *)icode + USRDATA); do { *icode_args[0]++ = *cp; } while (*cp++); icode_argv[icode_argc[0]] = 0; continue; } for(kp = kernargs; kp->name; kp++) { i = strlen(kp->name); if (strncmp(kp->name, *argp, i) == 0) { extern char *atob(); cp = &((*argp)[i]); if (*cp == 0) *kp->ptr = 1; else if (*cp == '=') { cp = atob(++cp, kp->ptr); if (*cp) dprintf("WARNING: Badly formed kernel argument %s\n", *argp); } else if (*cp == ':') { extern char *symval(); cp = symval(++cp, kp->ptr); if (*cp) dprintf("WARNING: Badly formed kernel argument %s\n", *argp); } else continue; dprintf("Kernel argument %s = 0x%x\n", kp->name, *kp->ptr); break; } } } if (argv) { argp = argv+1; /* skip boot device */ argv = 0; goto loop; }}/* * System call which allows a user to read/write kernel variables specified * in the above table by symbolic name. Only the super-user is allowed to * write non-readonly variables. */intmipskopt(argname, value, op) char *argname; int value; int op;{#define MAXKVARNAME 20 char nbuf[MAXKVARNAME]; register char *nbp; register struct kernargs *kp; int error = 0; nbp = nbuf; if ((error = copyinstr(argname, nbuf, MAXKVARNAME, 0)) != 0) { if (error == ENOENT) error = EINVAL; /* name too long */ return(error); } for (kp = kernargs; kp->name; kp++) if (strcmp(kp->name, nbuf) == 0) { error = do_opt(kp, value, op); return(error); } return(EINVAL);}do_opt(kp, val, op)struct kernargs *kp;{ u.u_r.r_val1 = *(kp->ptr); if (op != KOPT_GET && (!suser() || kp->readonly)) return(EACCES); switch (op) { case KOPT_GET: break; case KOPT_SET: *(kp->ptr) = val; break; case KOPT_BIS: *(kp->ptr) |= val; break; case KOPT_BIC: *(kp->ptr) &= ~val; break; default: return(EINVAL); } if (kp->func && op != KOPT_GET) return((*kp->func)(*(kp->ptr))); return(0);}/* * ????? * MOVE SOME OF THIS STUFF TO libc.c and libasm.s *//* * digit -- convert the ascii representation of a digit to its * binary representation */unsigneddigit(c)register char c;{ unsigned d; if (c >= '0' && c <= '9') d = c - '0'; else if (c >= 'a' && c <= 'f') d = c - 'a' + 10; else if (c >= 'A' && c <= 'F') d = c - 'A' + 10; else d = 999999; /* larger than any base to break callers loop */ return(d);}char *symval(cp, iptr)register char *cp;int *iptr;{ register struct reg_values *rv; register char *bp; char buf[32]; *iptr = 0; while (cp && *cp) { bp = buf; while (*cp && *cp != '|' && bp < &buf[sizeof(buf)-1]) *bp++ = *cp++; *bp = 0; for (rv = sym_values; rv->rv_name; rv++) if (strcmp(buf, rv->rv_name) == 0) { *iptr |= rv->rv_value; break; } if (rv->rv_name == NULL) printf("unknown symbol: %s\n", buf); while (*cp == '|') cp++; } return(cp);}/* * atob -- convert ascii to binary. Accepts all C numeric formats. */char *atob(cp, iptr)register char *cp;int *iptr;{ int minus = 0; register int value = 0; unsigned base = 10; unsigned d; *iptr = 0; while (*cp == ' ' || *cp == '\t') cp++; while (*cp == '-') { cp++; minus = !minus; } /* * Determine base by looking at first 2 characters */ if (*cp == '0') { switch (*++cp) { case 'X': case 'x': base = 16; cp++; break; case 'B': /* a frill: allow binary base */ case 'b': base = 2; cp++; break; default: base = 8; break; } } while ((d = digit(*cp)) < base) { value *= base; value += d; cp++; } if (minus) value = -value; *iptr = value; return(cp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -