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

📄 process.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)process.c	5.6 (Berkeley) 6/1/90";#endif /* not lint *//* * Process management. * * This module contains the routines to manage the execution and * tracing of the debuggee process. */#include "defs.h"#include "process.h"#include "machine.h"#include "events.h"#include "tree.h"#include "eval.h"#include "operators.h"#include "source.h"#include "object.h"#include "mappings.h"#include "main.h"#include "coredump.h"#include <signal.h>#include <errno.h>#include <sys/stat.h>#ifndef publictypedef struct Process *Process;Process process;#define DEFSIG -1#include "machine.h"#endif#define NOTSTARTED 1#define STOPPED 0177#define FINISHED 0/* * A cache of the instruction segment is kept to reduce the number * of system calls.  Might be better just to read the entire * code space into memory. */#define CACHESIZE 1003typedef struct {    Word addr;    Word val;} CacheWord;/* * This structure holds the information we need from the user structure. */struct Process {    int pid;			/* process being traced */    int mask;			/* process status word */    Word reg[NREG];		/* process' registers */    Word oreg[NREG];		/* registers when process last stopped */    short status;		/* either STOPPED or FINISHED */    short signo;		/* signal that stopped process */    short sigcode;		/* extra signal information */    int exitval;		/* return value from exit() */    long sigset;		/* bit array of traced signals */    CacheWord word[CACHESIZE];	/* text segment cache */    Ttyinfo ttyinfo;		/* process' terminal characteristics */    Address sigstatus;		/* process' handler for current signal */};/* * These definitions are for the arguments to "pio". */typedef enum { PREAD, PWRITE } PioOp;typedef enum { TEXTSEG, DATASEG } PioSeg;private struct Process pbuf;#define MAXNCMDARGS 1000         /* maximum number of arguments to RUN */extern int errno;private Boolean just_started;private int argc;private String argv[MAXNCMDARGS];private String infile, outfile;/* * Initialize process information. */public process_init(){    register integer i;    char buf[10];    process = &pbuf;    process->status = (coredump) ? STOPPED : NOTSTARTED;    setsigtrace();#   if vax || tahoe	for (i = 0; i < NREG; i++) {	    sprintf(buf, "$r%d", i);	    defregname(identname(buf, false), i);	}#	ifdef vax	    defregname(identname("$ap", true), ARGP);#	endif#   else#       ifdef mc68000	    for (i = 0; i < 8; i++) {		sprintf(buf, "$d%d", i);		defregname(identname(buf, false), i);		sprintf(buf, "$a%d", i);		defregname(identname(buf, false), i + 8);	    }#       endif#   endif    defregname(identname("$fp", true), FRP);    defregname(identname("$sp", true), STKP);    defregname(identname("$pc", true), PROGCTR);    if (coredump) {	coredump_readin(process->mask, process->reg, process->signo);	pc = process->reg[PROGCTR];    }    arginit();}/* * Routines to get at process information from outside this module. */public Word reg(n)Integer n;{    register Word w;    if (n == NREG) {	w = process->mask;    } else {	w = process->reg[n];    }    return w;}public setreg(n, w)Integer n;Word w;{    process->reg[n] = w;}/* * Begin execution. * * We set a breakpoint at the end of the code so that the * process data doesn't disappear after the program terminates. */private Boolean remade();public start(argv, infile, outfile)String argv[];String infile, outfile;{    String pargv[4];    Node cond;    if (coredump) {	coredump = false;	fclose(corefile);	coredump_close();    }    if (argv == nil) {	argv = pargv;	pargv[0] = objname;	pargv[1] = nil;    } else {	argv[argc] = nil;    }    pstart(process, argv, infile, outfile);    if (remade(objname)) {	reinit(argv, infile, outfile);    }    if (process->status == STOPPED) {	pc = CODESTART;	setcurfunc(program);	if (objsize != 0) {	    cond = build(O_EQ, build(O_SYM, pcsym), build(O_LCON, lastaddr()));	    event_once(cond, buildcmdlist(build(O_ENDX)));	}    }}/* * Check to see if the object file has changed since the symbolic * information last was read. */private time_t modtime;private Boolean remade(filename)String filename;{    struct stat s;    Boolean b;    stat(filename, &s);    b = (Boolean) (modtime != 0 and modtime < s.st_mtime);    modtime = s.st_mtime;    return b;}/* * Set up what signals we want to trace. */private setsigtrace(){    register Integer i;    register Process p;    p = process;    for (i = 1; i <= NSIG; i++) {	psigtrace(p, i, true);    }    psigtrace(p, SIGHUP, false);    psigtrace(p, SIGKILL, false);    psigtrace(p, SIGALRM, false);#   ifdef SIGTSTP	psigtrace(p, SIGTSTP, false);	psigtrace(p, SIGCONT, false);#   endif    psigtrace(p, SIGCHLD, false);    psigtrace(p, SIGWINCH, false);}/* * Initialize the argument list. */public arginit(){    infile = nil;    outfile = nil;    argv[0] = objname;    argc = 1;}/* * Add an argument to the list for the debuggee. */public newarg(arg)String arg;{    if (argc >= MAXNCMDARGS) {	error("too many arguments");    }    argv[argc++] = arg;}/* * Set the standard input for the debuggee. */public inarg(filename)String filename;{    if (infile != nil) {	error("multiple input redirects");    }    infile = filename;}/* * Set the standard output for the debuggee. * Probably should check to avoid overwriting an existing file. */public outarg(filename)String filename;{    if (outfile != nil) {	error("multiple output redirect");    }    outfile = filename;}/* * Start debuggee executing. */public run(){    process->status = STOPPED;    fixbps();    curline = 0;    start(argv, infile, outfile);    just_started = true;    isstopped = false;    cont(0);}/* * Continue execution wherever we left off. * * Note that this routine never returns.  Eventually bpact() will fail * and we'll call printstatus or step will call it. */typedef int Intfunc();private sig_t dbintr;private void intr();public cont(signo)integer signo;{    integer s;    dbintr = signal(SIGINT, intr);    if (just_started) {	just_started = false;    } else {	if (not isstopped) {	    error("can't continue execution");	}	isstopped = false;	stepover();    }    s = signo;    for (;;) {	if (single_stepping) {	    printnews();	} else {	    setallbps();	    resume(s);	    unsetallbps();	    s = DEFSIG;	    if (not isbperr() or not bpact()) {		printstatus();	    }	}	stepover();    }    /* NOTREACHED */}/* * This routine is called if we get an interrupt while "running" * but actually in the debugger.  Could happen, for example, while * processing breakpoints. * * We basically just want to keep going; the assumption is * that when the process resumes it will get the interrupt, * which will then be handled. */private void intr(){    signal(SIGINT, intr);}public fixintr(){    signal(SIGINT, dbintr);}/* * Resume execution. */public resume(signo)int signo;{    register Process p;    p = process;    pcont(p, signo);    pc = process->reg[PROGCTR];    if (p->status != STOPPED) {	if (p->signo != 0) {	    error("program terminated by signal %d", p->signo);	} else if (not runfirst) {	    if (p->exitval == 0) {		error("program exited");	    } else {		error("program exited with code %d", p->exitval);	    }	}    }}/* * 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 is what is called when the step command is given. * It has to play with the "isstopped" information. */public stepc(){    if (not isstopped) {	error("can't continue execution");    }    isstopped = false;    dostep(false);    isstopped = true;}public next(){    Address oldfrp, newfrp;    if (not isstopped) {	error("can't continue execution");    }    isstopped = false;    oldfrp = reg(FRP);    do {	dostep(true);	pc = reg(PROGCTR);	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.

⌨️ 快捷键说明

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