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

📄 process.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* * Continue execution up to the next source line. * * There are two ways to define the next source line depending on what * is desired when a procedure or function call is encountered.  Step * stops at the beginning of the procedure or call; next skips over it. *//* * Stepc  or stepv is what is called when the step command is given. * It has to play with the "isstopped" information. */public stepv(){    Address newfrp, oldpc;    	if (not isstopped) {		error("can't continue execution");    }    isstopped = false;	oldpc = pc;    do {	    if(dostep(false, true)) {	    	if((newfrp = reg(FRP)) != 0) {				if(oldpc == pc) {					dostep(false, false);					continue;				}				break;			}		}		else {    		newfrp = reg(FRP);		}    } while (newfrp != 0);    isstopped = true;}public stepc(){    if (not isstopped) {	error("can't continue execution");    }    isstopped = false;    dostep(false, false);    isstopped = true;}public nextv(){    Address oldfrp, newfrp, oldpc;    if (not isstopped) {		error("can't continue execution");    }    isstopped = false;    oldfrp = reg(FRP);	oldpc = pc;    do {	    if(dostep(true, true)) {	    	if((newfrp = reg(FRP)) == oldfrp) {				if(oldpc == pc) {					dostep(false, false);					continue;				}				break;			}		}		else {    		newfrp = reg(FRP);		}    } while (newfrp != 0);    isstopped = true;}public next(){    Address oldfrp, newfrp;    if (not isstopped) {	error("can't continue execution");    }    isstopped = false;    if (inst_tracing) {        dostep(true, false);    } else {        oldfrp = reg(FRP);        do {	    dostep(true, false);	    newfrp = reg(FRP);        } while (newfrp < oldfrp and newfrp != 0);    }    isstopped = true;}/* * Continue execution until the current function returns, or, * if the given argument is non-nil, until execution returns to * somewhere within the given function. */public rtnfunc (f)Symbol f;{    Address addr;    Symbol t;    if (not isstopped) {	error("can't continue execution");    } else if (f != nil and not isactive(f)) {	error("%s is not active", symname(f));    } else {	addr = return_addr();	if (addr == nil) {	    error("no place to return to");	} else {	    isstopped = false;	    contto(addr);	    if (f != nil) {		for (;;) {		    t = whatblock(pc);		    addr = return_addr();		if (t == f or addr == nil) break;		    contto(addr);		}	    }	    if (not bpact()) {		isstopped = true;		printstatus();	    }	}    }}/* * Single-step over the current machine instruction. * * If we're single-stepping by source line we want to step to the * next source line.  Otherwise we're going to continue so there's * no reason to do all the work necessary to single-step to the next * source line. */public stepover(){    Boolean b;    if (traceexec) {	printf("!! stepping over 0x%x\n", process->reg[PROGCTR]);    }    if (single_stepping) {	dostep(false, false);    } else {	b = inst_tracing;	inst_tracing = true;	dostep(false, false);	inst_tracing = b;    }    if (traceexec) {	printf("!! stepped over to 0x%x\n", process->reg[PROGCTR]);    }}/* * Resume execution up to the given address.  We can either ignore * breakpoints (stepto) or catch them (contto). */public stepto(addr)Address addr;{    xto(addr, false);}private contto (addr)Address addr;{    xto(addr, true);}private xto (addr, catchbps)Address addr;boolean catchbps;{    Address curpc;    if (catchbps) {	stepover();    }    curpc = process->reg[PROGCTR];    if (addr != curpc) {	if (traceexec) {	    printf("!! stepping from 0x%x to 0x%x\n", curpc, addr);	}	if (catchbps) {	    setallbps();	}	setbp(addr);	resume(DEFSIG);	unsetbp(addr);	if (catchbps) {	    unsetallbps();	}	if (not isbperr()) {	    printstatus();	}    }}/* * Print the status of the process. * This routine does not return. */public printstatus(){    int status;    if (process->status == FINISHED) {	exit(0);    } else {	setcurfunc(whatblock(pc));	getsrcpos();	if (process->signo == SIGINT) {	    isstopped = true;	    printerror();	} else if (isbperr() and isstopped) {	    printf("stopped ");	    printloc();	    putchar('\n');	    if (curline > 0) {		printlines(curline, curline);	    } else {		printinst(pc, pc);	    }	    erecover();	} else {	    fixintr();	    isstopped = true;	    printerror();	}    }}/* * Print out the current location in the debuggee. */public printloc(){    Symbol f;    printf("in ");    f = curfunc;    while (isinline(f)) {        f = container(f);    }    printname(stdout, f);    putchar(' ');    if (curline > 0 and not useInstLoc) {	printsrcpos();    } else {	useInstLoc = false;	curline = 0;	printf("at 0x%x", pc);    }}/* * Some functions for testing the state of the process. */public Boolean notstarted(p)Process p;{    return (Boolean) (p->status == NOTSTARTED);}public Boolean isfinished(p)Process p;{    return (Boolean) (p->status == FINISHED);}/* * Predicate to test if the reason the process stopped was because * of a breakpoint.  If so, as a side effect clear the local copy of * signal handler associated with process.  We must do this so as to * not confuse future stepping or continuing by possibly concluding * the process should continue with a SIGTRAP handler. */public boolean isbperr(){    Process p;    boolean b;    p = process;    if (p->status == STOPPED and p->signo == SIGTRAP) {	b = true;	p->sigstatus = 0;    } else {	b = false;    }    return b;}/* * Return the signal number that stopped the process. */public integer errnum (p)Process p;{    return p->signo;}/* * Return the signal code associated with the signal. */public integer errcode (p)Process p;{    return p->sigcode;}/* * Return the termination code of the process. */public integer exitcode (p)Process p;{    return p->exitval;}/* * These routines are used to access the debuggee process from * outside this module. * * They invoke "pio" which eventually leads to a call to "ptrace". * The system generates an I/O error when a ptrace fails.  During reads * these are ignored, during writes they are reported as an error, and * for anything else they cause a fatal error. */extern Intfunc *onsyserr();private badaddr;private read_err(), write_err();/* * Read from the process' instruction area. */public iread(buff, addr, nbytes)char *buff;Address addr;int nbytes;{    Intfunc *f;    f = onsyserr(EIO, read_err);    badaddr = addr;    if (coredump) {	coredump_readtext(buff, addr, nbytes);    } else {	pio(process, PREAD, TEXTSEG, buff, addr, nbytes);    }    onsyserr(EIO, f);}/*  * Write to the process' instruction area, usually in order to set * or unset a breakpoint. */public iwrite(buff, addr, nbytes)char *buff;Address addr;int nbytes;{    Intfunc *f;    if (coredump) {	error("no process to write to");    }    f = onsyserr(EIO, write_err);    badaddr = addr;    pio(process, PWRITE, TEXTSEG, buff, addr, nbytes);    onsyserr(EIO, f);}/* * Read for the process' data area. */public dread(buff, addr, nbytes)char *buff;Address addr;int nbytes;{    Intfunc *f;    badaddr = addr;    if (coredump) {	f = onsyserr(EFAULT, read_err);	coredump_readdata(buff, addr, nbytes);	onsyserr(EFAULT, f);    } else {	f = onsyserr(EIO, read_err);	pio(process, PREAD, DATASEG, buff, addr, nbytes);	onsyserr(EIO, f);    }}/* * Write to the process' data area. */public dwrite(buff, addr, nbytes)char *buff;Address addr;int nbytes;{    Intfunc *f;    if (coredump) {	error("no process to write to");    }    f = onsyserr(EIO, write_err);    badaddr = addr;    pio(process, PWRITE, DATASEG, buff, addr, nbytes);    onsyserr(EIO, f);}/* * Trap for errors in reading or writing to a process. * The current approach is to "ignore" read errors and complain * bitterly about write errors. */private read_err(){    /*     * Ignore.     */}private write_err(){    error("can't write to process (address 0x%x)", badaddr);}/* * Ptrace interface. *//* * This magic macro enables us to look at the process' registers * in its user structure. */#define regloc(reg)     (ctob(UPAGES) + ( sizeof(int) * (reg) ))#define WMASK           (~(sizeof(Word) - 1))#define cachehash(addr) ((unsigned) ((addr >> 2) % CSIZE))#define FIRSTSIG        SIGINT#define LASTSIG         SIGQUIT#define ischild(pid)    ((pid) == 0)#define traceme()       ptrace(0, 0, 0, 0)#define setrep(n)       (1 << ((n)-1))#define istraced(p)     (p->sigset&setrep(p->signo))/* * Ptrace options (specified in first argument). */#define UREAD   3       /* read from process's user structure */#define UWRITE  6       /* write to process's user structure */#define IREAD   1       /* read from process's instruction space */#define IWRITE  4       /* write to process's instruction space */#define DREAD   2       /* read from process's data space */#define DWRITE  5       /* write to process's data space */#define CONT    7       /* continue stopped process */#define SSTEP   9       /* continue for approximately one instruction */#define PKILL   8       /* terminate the process */#define VREAD   10      /* read a vector register from process's user area */#define VWRITE  11      /* writes a vector register to process's user area *//* this routine is used to check if the process being debugged has a vector * context area. */boolean vector_context(){#ifndef NOVECTORS	int acflag = ~AVP;	acflag = ptrace(UREAD, process->pid, &((struct user *) 0)->u_acflag, 0);	if((acflag) & AVP)		return(true);	else#endif /* NOVECTORS */		return(false);}/* * Start up a new process by forking and exec-ing the * given argument list, returning when the process is loaded * and ready to execute.  The PROCESS information (pointed to * by the first argument) is appropriately filled. * * If the given PROCESS structure is associated with an already running * process, we terminate it. *//* VARARGS2 */private pstart(p, argv, infile, outfile)Process p;String argv[];String infile;String outfile;{    int status;    TTYWindow *tw;    struct sgttyb s;     struct ltchars l;    int localMode;    if (p->pid != 0) {	pterm(p);	cacheflush(p);    }    fflush(stdout);    psigtrace(p, SIGTRAP, true);    p->pid = vfork();    if (p->pid == -1) {	panic("can't fork");    }    if (ischild(p->pid)) {	nocatcherrs();	traceme();	if (xdb) {			/* 007 - xdb support */	    if (xdbwinflag == false) {		xdbwinflag = true;	    } else {		tw = CreateTTYWindow();		ioctl(tw->file,(int)TIOCGETP,(char *) &s);		s.sg_flags |= ANYP | CRMOD | ECHO;		s.sg_flags &= ~(RAW | CBREAK);		s.sg_erase = CERASE;		s.sg_kill = CKILL;		ioctl(tw->file,(int)TIOCSETP,(char *) &s);		ioctl(tw->file, (int) TIOCGLTC, (char *) &l);		l.t_rprntc = CRPRNT;		l.t_werasc = CWERASE;		ioctl(tw->file, (int) TIOCSLTC, (char *) &l);		localMode = LCRTBS | LCRTERA | LCRTKIL | LCTLECH;		ioctl(tw->file, (int) TIOCLBIS, (char *) &localMode);		dup2(tw->file,0);		dup2(tw->file,1);		dup2(tw->file,2); /* added by bjg */	    }	}	if (infile != nil) {	    infrom(infile);	}	if (outfile != nil) {	    outto(outfile);	}	execv(argv[0], argv);	_exit(1);    }                                           /* 010 - change format */    if (xdb) printf("%d iopid\n",p->pid);  /* 008 - xdb support */    pwait(p->pid, &status);    getinfo(p, status);    if (p->status != STOPPED) {	beginerrmsg();	fprintf(stderr, "warning: cannot execute %s\n", argv[0]);    } else {	ptraced(p->pid);    }}/* * Terminate a ptrace'd process. */public pterm (p)Process p;{    integer status;    if (p != nil and p->pid != 0) {	ptrace(PKILL, p->pid, 0, 0);	pwait(p->pid, &status);	unptraced(p->pid);    }}/* * Continue a stopped process.  The first argument points to a Process * structure.  Before the process is restarted it's user area is modified * according to the values in the structure.  When this routine finishes, * the structure has the new values from the process's user area. * * Pcont terminates when the process stops with a signal pending that * is being traced (via psigtrace), or when the process terminates. */private pcont(p, signo)Process p;int signo;{    int s, status;    if (p->pid == 0) {	error("program is not active");    }    s = signo;    do {	setinfo(p, s);	if (traceexec) {	    printf("!! pcont from 0x%x with signal %d (%d)\n",		p->reg[PROGCTR], s, p->signo);	    fflush(stdout);	}	sigs_off();	if (ptrace(CONT, p->pid, p->reg[PROGCTR], p->signo) < 0) {		p->pid = 0;    	p->status = FINISHED;	    error("error %d trying to continue process with %s", 											errno, sys_siglist[p->signo]);	}

⌨️ 快捷键说明

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