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

📄 process.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * 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);    } else {	b = inst_tracing;	inst_tracing = true;	dostep(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 {	if (runfirst) {	    fprintf(stderr, "\nEntering debugger ...\n");	    printheading();	    init();	}	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(){    printf("in ");    printname(stdout, curfunc);    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. */#define WMASK           (~(sizeof(Word) - 1))#define cachehash(addr) ((unsigned) ((addr >> 2) % CACHESIZE))#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 */#ifdef IRIS#   define readreg(p, r)	ptrace(10, p->pid, r, 0)#   define writereg(p, r, v)	ptrace(11, p->pid, r, v)#else#   define readreg(p, r)	ptrace(UREAD, p->pid, regloc(r), 0);#   define writereg(p, r, v)	ptrace(UWRITE, p->pid, regloc(r), v);#endif/* * 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;    if (p->pid != 0) {	pterm(p);	cacheflush(p);    }    fflush(stdout);    psigtrace(p, SIGTRAP, true);#   ifdef IRIS	p->pid = fork();#   else	p->pid = vfork();#   endif    if (p->pid == -1) {	panic("can't fork");    }    if (ischild(p->pid)) {	nocatcherrs();	traceme();	if (infile != nil) {	    infrom(infile);	}	if (outfile != nil) {	    outto(outfile);	}	execv(argv[0], argv);	_exit(1);    }    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) {	    panic("error %d trying to continue process", errno);	}	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 mc68000 || m68000	    if (p->status == STOPPED and p->signo == SIGTRAP) {		p->reg[PROGCTR] += 2;	    }#	endif	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);

⌨️ 快捷键说明

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