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

📄 process.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	pwait(p->pid, &status);	sigs_on();	getinfo(p, status);	if (p->status == STOPPED and traceexec and not istraced(p)) {	    printf("!! ignored signal %d at 0x%x\n",		p->signo, p->reg[PROGCTR]);	    fflush(stdout);	}	s = p->signo;    } while (p->status == STOPPED and not istraced(p));    if (traceexec) {	printf("!! pcont to 0x%x on signal %d\n", p->reg[PROGCTR], p->signo);	fflush(stdout);    }}/* * Single step as best ptrace can. */public pstep(p, signo)Process p;integer signo;{    int s, status;    s = signo;    do {	setinfo(p, s);	if (traceexec) {	    printf("!! pstep from 0x%x with signal %d (%d)\n",		p->reg[PROGCTR], s, p->signo);	    fflush(stdout);	}	sigs_off();	if (ptrace(SSTEP, p->pid, p->reg[PROGCTR], p->signo) < 0) {	    panic("error %d trying to step process", errno);	}	pwait(p->pid, &status);	sigs_on();	getinfo(p, status);	if (p->status == STOPPED and traceexec and not istraced(p)) {	    printf("!! pstep ignored signal %d at 0x%x\n",		p->signo, p->reg[PROGCTR]);	    fflush(stdout);	}	s = p->signo;    } while (p->status == STOPPED and not istraced(p));    if (traceexec) {	printf("!! pstep to 0x%x on signal %d\n",	    p->reg[PROGCTR], p->signo);	fflush(stdout);    }    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 Intfunc *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 int rloc[] ={    R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC};private getinfo(p, status)register Process p;register int status;{    register int i, j;    Address addr;	int value;    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->sigcode = ptrace(UREAD, p->pid, &((struct user *) 0)->u_code, 0);	p->exitval = 0;	p->mask = ptrace(UREAD, p->pid, regloc(PS), 0);	for (i = 0; i < NREG; i++) {	    p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0);	    p->oreg[i] = p->reg[i];	}	if (vectorcapable && vector_context()) {		if(((single_stepping or inst_tracing) and found_a_vec_inst) or									(!single_stepping and !inst_tracing)) {	    	for (i = 0; i < NREG; i++) {	    		for (j = 0; j < NVREG; j++) {					value = ptrace(VREAD, p->pid, vregloc(A_VREGLO, i, j), 0);					p->ovreg[i]->reg[j].val[0] =									p->vreg[i]->reg[j].val[0] = value;					value = ptrace(VREAD, p->pid, vregloc(A_VREGHI, i, j), 0);					p->ovreg[i]->reg[j].val[1] =									p->vreg[i]->reg[j].val[1] = value;	    		}	    	}	    	p->ovcr = p->vcr = ptrace(VREAD, p->pid, vregloc(A_VCR, 0, 0), 0);	    	p->ovlr = p->vlr = ptrace(VREAD, p->pid, vregloc(A_VLR, 0, 0), 0);	    	p->ovaer = p->vaer =					ptrace(VREAD, p->pid, vregloc(A_VAER, 0, 0), 0);	    	p->ovmr.val[0] = p->vmr.val[0] =					ptrace(VREAD, p->pid, vregloc(A_VMRLO, 0, 0), 0);	    	p->ovmr.val[1] = p->vmr.val[1] =	    			ptrace(VREAD, p->pid, vregloc(A_VMRHI, 0, 0), 0);		}	}	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, j;    register int r, s;    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]) {	    	ptrace(UWRITE, p->pid, regloc(rloc[i]), r);			p->oreg[i] = r;		}    }	if (vectorcapable && vector_context()) {		if(((single_stepping or inst_tracing) and found_a_vec_inst) or									(!single_stepping and !inst_tracing)) {	    	for (i = 0; i < NREG; i++) {	    		for (j = 0; j < NVREG; j++) {	    			r = p->vreg[i]->reg[j].val[0];	    			s = p->vreg[i]->reg[j].val[1];	    			if (r != p->ovreg[i]->reg[j].val[0]) {						ptrace(VWRITE, p->pid, vregloc(A_VREGLO, i, j), r);						p->ovreg[i]->reg[j].val[0] = r;					}	    			if (s != p->ovreg[i]->reg[j].val[1]) {						ptrace(VWRITE, p->pid, vregloc(A_VREGHI, i, j), s);						p->ovreg[i]->reg[j].val[1] = s;					}	    		} 			}			if(p->ovcr != p->vcr) {	    		ptrace(VWRITE, p->pid, vregloc(A_VCR, 0, 0), p->vcr);				p->ovcr = p->vcr;			}			if(p->ovaer != p->vaer) {	    		ptrace(VWRITE, p->pid, vregloc(A_VAER, 0, 0), p->vaer);				p->ovaer = p->vaer;			}			if(p->ovlr != p->vlr) {	    		ptrace(VWRITE, p->pid, vregloc(A_VLR, 0, 0), p->vlr);				p->ovlr = p->vlr;			}			if(p->ovmr.val[0] != p->vmr.val[0]) {	    		ptrace(VWRITE, p->pid, vregloc(A_VMRLO, 0, 0), p->vmr.val[0]);				p->ovmr.val[0] = p->vmr.val[0];			}			if(p->ovmr.val[1] != p->vmr.val[1]) {	    		ptrace(VWRITE, p->pid, vregloc(A_VMRHI, 0, 0), p->vmr.val[1]);				p->ovmr.val[1] = p->vmr.val[1];			}    	}	}    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 += 2;    }    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;    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);    }    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);    }}/* * The signal is SIGTRAP, caught by the debugger, so reset the * sigstatus field to 0. */public resetsig(p)Process p;{    p->sigstatus = 0;}/* * Signal name manipulation. */private String signames[NSIG] = {    0,    "HUP", "INT", "QUIT", "ILL", "TRAP",    "IOT", "EMT", "FPE", "KILL", "BUS",    "SEGV", "SYS", "PIPE", "ALRM", "TERM",    "URG", "STOP", "TSTP", "CONT", "CHLD",    "TTIN", "TTOU", "IO", "XCPU", "XFSZ",    "VTALRM", "PROF", "WINCH", "LOST", "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');    }}/* get the vector registers from the coredump file and put them into * the process structure. */put_vregs(f)File f;{	int i, j;	Word value;	for (i = 0; i < NREG; i++) {	    for (j = 0; j < NVREG; j++) {			value = readvregfromfile(corefile, vregloc(A_VREGLO, i, j));			process->ovreg[i]->reg[j].val[0] =						process->vreg[i]->reg[j].val[0] = value;			value = readvregfromfile(corefile, vregloc(A_VREGHI, i, j));			process->ovreg[i]->reg[j].val[1] =						process->vreg[i]->reg[j].val[1] = value;			if(!coredump)				return;	    }	}	process->ovcr = process->vcr =				readvregfromfile(corefile, vregloc(A_VCR, 0, 0));	process->ovaer = process->vaer =				readvregfromfile(corefile, vregloc(A_VAER, 0, 0));	process->ovlr = process->vlr =				readvregfromfile(corefile, vregloc(A_VLR, 0, 0));	process->ovmr.val[0] = process->vmr.val[0] =				readvregfromfile(corefile, vregloc(A_VMRLO, 0, 0));	process->ovmr.val[1] = process->vmr.val[1] =	    		readvregfromfile(corefile, vregloc(A_VMRHI, 0, 0));}

⌨️ 快捷键说明

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