⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    if (p->status != STOPPED) {	if (p->exitval == 0) {	    error("program exited\n");	} else {	    error("program exited with code %d\n", p->exitval);	}    }}/* * Return from execution when the given signal is pending. */public psigtrace(p, sig, sw)Process p;int sig;Boolean sw;{    if (sw) {	p->sigset |= setrep(sig);    } else {	p->sigset &= ~setrep(sig);    }}/* * Don't catch any signals. * Particularly useful when letting a process finish uninhibited. */public unsetsigtraces(p)Process p;{    p->sigset = 0;}/* * Turn off attention to signals not being caught. */private sig_t sigfunc[NSIG];private sigs_off(){    register int i;    for (i = FIRSTSIG; i < LASTSIG; i++) {	if (i != SIGKILL) {	    sigfunc[i] = signal(i, SIG_IGN);	}    }}/* * Turn back on attention to signals. */private sigs_on(){    register int i;    for (i = FIRSTSIG; i < LASTSIG; i++) {	if (i != SIGKILL) {	    signal(i, sigfunc[i]);	}    }}/* * Get process information from user area. */private getinfo (p, status)register Process p;register int status;{    register int i;    Address addr;    p->signo = (status&0177);    p->exitval = ((status >> 8)&0377);    if (p->signo != STOPPED) {	p->status = FINISHED;	p->pid = 0;	p->reg[PROGCTR] = 0;    } else {	p->status = p->signo;	p->signo = p->exitval;	p->exitval = 0;#       ifdef IRIS	    p->mask = readreg(p, RPS);#       else	    p->sigcode = ptrace(UREAD, p->pid, &((struct user *)0)->u_code, 0);	    p->mask = readreg(p, PS);#       endif	for (i = 0; i < NREG; i++) {	    p->reg[i] = readreg(p, rloc[i]);	    p->oreg[i] = p->reg[i];	}#       ifdef mc68000	    if (p->status == STOPPED and p->signo == SIGTRAP and		p->reg[PROGCTR] > CODESTART	    ) {		p->reg[PROGCTR] -= 2;	    }#       endif	savetty(stdout, &(p->ttyinfo));	addr = (Address) &(((struct user *) 0)->u_signal[p->signo]);	p->sigstatus = (Address) ptrace(UREAD, p->pid, addr, 0);    }}/* * Set process's user area information from given process structure. */private setinfo (p, signo)register Process p;int signo;{    register int i;    register int r;    if (signo == DEFSIG) {	if (istraced(p) and (p->sigstatus == 0 or p->sigstatus == 1)) {	    p->signo = 0;	}    } else {	p->signo = signo;    }    for (i = 0; i < NREG; i++) {	if ((r = p->reg[i]) != p->oreg[i]) {	    writereg(p, rloc[i], r);	}    }    restoretty(stdout, &(p->ttyinfo));}/* * Return the address associated with the current signal. * (Plus two since the address points to the beginning of a procedure). */public Address usignal (p)Process p;{    Address r;    r = p->sigstatus;    if (r != 0 and r != 1) {	r += FUNCOFFSET;    }    return r;}/* * Structure for reading and writing by words, but dealing with bytes. */typedef union {    Word pword;    Byte pbyte[sizeof(Word)];} Pword;/* * Read (write) from (to) the process' address space. * We must deal with ptrace's inability to look anywhere other * than at a word boundary. */private Word fetch();private store();private pio(p, op, seg, buff, addr, nbytes)Process p;PioOp op;PioSeg seg;char *buff;Address addr;int nbytes;{    register int i;    register Address newaddr;    register char *cp;    char *bufend;    Pword w;    Address wordaddr;    int byteoff;    if (p->status != STOPPED) {	error("program is not active");    }    cp = buff;    newaddr = addr;    wordaddr = (newaddr&WMASK);    if (wordaddr != newaddr) {	w.pword = fetch(p, seg, wordaddr);	for (i = newaddr - wordaddr; i < sizeof(Word) and nbytes > 0; i++) {	    if (op == PREAD) {		*cp++ = w.pbyte[i];	    } else {		w.pbyte[i] = *cp++;	    }	    nbytes--;	}	if (op == PWRITE) {	    store(p, seg, wordaddr, w.pword);	}	newaddr = wordaddr + sizeof(Word);    }    byteoff = (nbytes&(~WMASK));    nbytes -= byteoff;    bufend = cp + nbytes;#ifdef tahoe    if (((int)cp)&WMASK) {	/*	 * Must copy a byte at a time, buffer not word addressable.	 */	while (cp < bufend) {	    if (op == PREAD) {		w.pword = fetch(p, seg, newaddr);		for (i = 0; i < sizeof(Word); i++)		    *cp++ = w.pbyte[i];	    } else {		for (i = 0; i < sizeof(Word); i++)		    w.pbyte[i] = *cp++;		store(p, seg, newaddr, w.pword);	    }	    newaddr += sizeof(Word);	}    } else {    /*     * Buffer, word aligned, act normally...     */#endif    while (cp < bufend) {	if (op == PREAD) {	    *((Word *) cp) = fetch(p, seg, newaddr);	} else {	    store(p, seg, newaddr, *((Word *) cp));	}	cp += sizeof(Word);	newaddr += sizeof(Word);    }#ifdef tahoe    }#endif    if (byteoff > 0) {	w.pword = fetch(p, seg, newaddr);	for (i = 0; i < byteoff; i++) {	    if (op == PREAD) {		*cp++ = w.pbyte[i];	    } else {		w.pbyte[i] = *cp++;	    }	}	if (op == PWRITE) {	    store(p, seg, newaddr, w.pword);	}    }}/* * Get a word from a process at the given address. * The address is assumed to be on a word boundary. * * A simple cache scheme is used to avoid redundant ptrace calls * to the instruction space since it is assumed to be pure. * * It is necessary to use a write-through scheme so that * breakpoints right next to each other don't interfere. */private Integer nfetchs, nreads, nwrites;private Word fetch(p, seg, addr)Process p;PioSeg seg;register int addr;{    register CacheWord *wp;    register Word w;    switch (seg) {	case TEXTSEG:	    ++nfetchs;	    wp = &p->word[cachehash(addr)];	    if (addr == 0 or wp->addr != addr) {		++nreads;		w = ptrace(IREAD, p->pid, addr, 0);		wp->addr = addr;		wp->val = w;	    } else {		w = wp->val;	    }	    break;	case DATASEG:	    w = ptrace(DREAD, p->pid, addr, 0);	    break;	default:	    panic("fetch: bad seg %d", seg);	    /* NOTREACHED */    }    return w;}/* * Put a word into the process' address space at the given address. * The address is assumed to be on a word boundary. */private store(p, seg, addr, data)Process p;PioSeg seg;int addr;Word data;{    register CacheWord *wp;    switch (seg) {	case TEXTSEG:	    ++nwrites;	    wp = &p->word[cachehash(addr)];	    wp->addr = addr;	    wp->val = data;	    ptrace(IWRITE, p->pid, addr, data);	    break;	case DATASEG:	    ptrace(DWRITE, p->pid, addr, data);	    break;	default:	    panic("store: bad seg %d", seg);	    /* NOTREACHED */    }}/* * Flush the instruction cache associated with a process. */private cacheflush (p)Process p;{    bzero(p->word, sizeof(p->word));}public printptraceinfo(){    printf("%d fetchs, %d reads, %d writes\n", nfetchs, nreads, nwrites);}/* * Redirect input. * Assuming this is called from a child, we should be careful to avoid * (possibly) shared standard I/O buffers. */private infrom (filename)String filename;{    Fileid in;    in = open(filename, 0);    if (in == -1) {	write(2, "can't read ", 11);	write(2, filename, strlen(filename));	write(2, "\n", 1);	_exit(1);    }    fswap(0, in);}/* * Redirect standard output. * Same assumptions as for "infrom" above. */private outto (filename)String filename;{    Fileid out;    out = creat(filename, 0666);    if (out == -1) {	write(2, "can't write ", 12);	write(2, filename, strlen(filename));	write(2, "\n", 1);	_exit(1);    }    fswap(1, out);}/* * Swap file numbers, useful for redirecting standard input or output. */private fswap(oldfd, newfd)Fileid oldfd;Fileid newfd;{    if (oldfd != newfd) {	close(oldfd);	dup(newfd);	close(newfd);    }}/* * Signal name manipulation. */private String signames[NSIG] = {    0,    "HUP", "INT", "QUIT", "ILL", "TRAP",    "IOT", "EMT", "FPE", "KILL", "BUS",    "SEGV", "SYS", "PIPE", "ALRM", "TERM",    0, "STOP", "TSTP", "CONT", "CHLD",    "TTIN", "TTOU", "TINT", "XCPU", "XFSZ",    "VTALRM", "PROF", "WINCH", "USR1", "USR2"};/* * Get the signal number associated with a given name. * The name is first translated to upper case if necessary. */public integer siglookup (s)String s;{    register char *p, *q;    char buf[100];    integer i;    p = s;    q = buf;    while (*p != '\0') {	if (*p >= 'a' and *p <= 'z') {	    *q = (*p - 'a') + 'A';	} else {	    *q = *p;	}	++p;	++q;    }    *q = '\0';    p = buf;    if (buf[0] == 'S' and buf[1] == 'I' and buf[2] == 'G') {	p += 3;    }    i = 1;    for (;;) {	if (i >= sizeof(signames) div sizeof(signames[0])) {	    error("signal \"%s\" unknown", s);	    i = 0;	    break;	}	if (signames[i] != nil and streq(signames[i], p)) {	    break;	}	++i;    }    return i;}/* * Print all signals being ignored by the debugger. * These signals are auotmatically * passed on to the debugged process. */public printsigsignored (p)Process p;{    printsigs(~p->sigset);}/* * Print all signals being intercepted by * the debugger for the specified process. */public printsigscaught(p)Process p;{    printsigs(p->sigset);}private printsigs (set)integer set;{    integer s;    char separator[2];    separator[0] = '\0';    for (s = 1; s < sizeof(signames) div sizeof(signames[0]); s++) {	if (set & setrep(s)) {	    if (signames[s] != nil) {		printf("%s%s", separator, signames[s]);		separator[0] = ' ';		separator[1] = '\0';	    }	}    }    if (separator[0] == ' ') {	putchar('\n');    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -