X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/e804469b5b0975de34bae1e66c3e6371249d3ee7..0f4556f12c8f75078501c9d1338ae7648a97f975:/usr/src/ucb/dbx/process.c diff --git a/usr/src/ucb/dbx/process.c b/usr/src/ucb/dbx/process.c index 2ce2e43ee0..3755987d52 100644 --- a/usr/src/ucb/dbx/process.c +++ b/usr/src/ucb/dbx/process.c @@ -1,6 +1,6 @@ /* Copyright (c) 1982 Regents of the University of California */ -static char sccsid[] = "@(#)process.c 1.4 2/20/83"; +static char sccsid[] = "@(#)process.c 1.12 8/19/83"; /* * Process management. @@ -14,6 +14,7 @@ static char sccsid[] = "@(#)process.c 1.4 2/20/83"; #include "machine.h" #include "events.h" #include "tree.h" +#include "eval.h" #include "operators.h" #include "source.h" #include "object.h" @@ -32,6 +33,8 @@ typedef struct Process *Process; Process process; +#define DEFSIG -1 + #include "machine.h" #endif @@ -58,14 +61,15 @@ typedef struct { struct Process { int pid; /* process being traced */ - int mask; /* ps */ - Word reg[NREG]; /* process's registers */ + 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 */ int exitval; /* return value from exit() */ long sigset; /* bit array of traced signals */ CacheWord word[CSIZE]; /* text segment cache */ + Ttyinfo ttyinfo; /* process' terminal characteristics */ }; /* @@ -77,7 +81,9 @@ typedef enum { TEXTSEG, DATASEG } PioSeg; private struct Process pbuf; -#define MAXNCMDARGS 10 /* maximum number of arguments to RUN */ +#define MAXNCMDARGS 100 /* maximum number of arguments to RUN */ + +extern int errno; private Boolean just_started; private int argc; @@ -106,7 +112,10 @@ public process_init() defregname(identname("$pc", true), PROGCTR); if (coredump) { coredump_readin(process->mask, process->reg, process->signo); + pc = process->reg[PROGCTR]; + getsrcpos(); } + arginit(); } /* @@ -279,7 +288,7 @@ public run() start(argv, infile, outfile); just_started = true; isstopped = false; - cont(); + cont(0); } /* @@ -297,7 +306,8 @@ private intr(); #define succeeds == true #define fails == false -public cont() +public cont(signo) +int signo; { dbintr = signal(SIGINT, intr); if (just_started) { @@ -307,20 +317,20 @@ public cont() error("can't continue execution"); } isstopped = false; - step(); + stepover(); } for (;;) { if (single_stepping) { printnews(); } else { setallbps(); - resume(); + resume(signo); unsetallbps(); if (bpact() fails) { printstatus(); } } - step(); + stepover(); } /* NOTREACHED */ } @@ -349,7 +359,8 @@ public fixintr() * Resume execution. */ -public resume() +public resume(signo) +int signo; { register Process p; @@ -358,13 +369,20 @@ public resume() printf("execution resumes at pc 0x%x\n", process->reg[PROGCTR]); fflush(stdout); } - pcont(p); + pcont(p, signo); pc = process->reg[PROGCTR]; if (traceexec) { printf("execution stops at pc 0x%x on sig %d\n", process->reg[PROGCTR], p->signo); fflush(stdout); } + if (p->status != STOPPED) { + if (p->signo != 0) { + error("program terminated by signal %d", p->signo); + } else if (not runfirst) { + error("program unexpectedly exited with %d", p->exitval); + } + } } /* @@ -400,9 +418,27 @@ public next() isstopped = true; } -public step() +/* + * 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. + */ + +private stepover() { - dostep(false); + Boolean b; + + if (single_stepping) { + dostep(false); + } else { + b = inst_tracing; + inst_tracing = true; + dostep(false); + inst_tracing = b; + } } /* @@ -415,7 +451,7 @@ public stepto(addr) Address addr; { setbp(addr); - resume(); + resume(DEFSIG); unsetbp(addr); if (not isbperr()) { printstatus(); @@ -429,6 +465,8 @@ Address addr; public printstatus() { + int status; + if (process->status == FINISHED) { exit(0); } else { @@ -465,9 +503,11 @@ public printloc() printf("in "); printname(stdout, curfunc); putchar(' '); - if (curline > 0) { + if (curline > 0 and not useInstLoc) { printsrcpos(); } else { + useInstLoc = false; + curline = 0; printf("at 0x%x", pc); } } @@ -513,14 +553,15 @@ Process p; * 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, we catch - * that here and assume its due to a misguided address. + * 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 rwerr(); +private read_err(), write_err(); /* * Read from the process' instruction area. @@ -533,7 +574,7 @@ int nbytes; { Intfunc *f; - f = onsyserr(EIO, rwerr); + f = onsyserr(EIO, read_err); badaddr = addr; if (coredump) { coredump_readtext(buff, addr, nbytes); @@ -558,7 +599,7 @@ int nbytes; if (coredump) { error("no process to write to"); } - f = onsyserr(EIO, rwerr); + f = onsyserr(EIO, write_err); badaddr = addr; pio(process, PWRITE, TEXTSEG, buff, addr, nbytes); onsyserr(EIO, f); @@ -575,7 +616,7 @@ int nbytes; { Intfunc *f; - f = onsyserr(EIO, rwerr); + f = onsyserr(EIO, read_err); badaddr = addr; if (coredump) { coredump_readdata(buff, addr, nbytes); @@ -599,19 +640,28 @@ int nbytes; if (coredump) { error("no process to write to"); } - f = onsyserr(EIO, rwerr); + f = onsyserr(EIO, write_err); badaddr = addr; pio(process, PWRITE, DATASEG, buff, addr, nbytes); onsyserr(EIO, f); } /* - * Error handler. + * 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 rwerr() +private read_err() { - error("bad read/write process address 0x%x", badaddr); + /* + * Ignore. + */ +} + +private write_err() +{ + error("can't write to process (address 0x%x)", badaddr); } /* @@ -620,7 +670,7 @@ private rwerr() /* * This magic macro enables us to look at the process' registers - * in its user structure. Very gross. + * in its user structure. */ #define regloc(reg) (ctob(UPAGES) + ( sizeof(int) * (reg) )) @@ -667,17 +717,19 @@ String infile; String outfile; { int status; + Fileid in, out; - if (p->pid != 0) { /* child already running? */ - ptrace(PKILL, p->pid, 0, 0); /* ... kill it! */ + if (p->pid != 0) { /* child already running? */ + ptrace(PKILL, p->pid, 0, 0); /* ... kill it! */ + pwait(p->pid, &status); /* wait for it to exit */ + unptraced(p->pid); } psigtrace(p, SIGTRAP, true); - if ((p->pid = vfork()) == -1) { + p->pid = vfork(); + if (p->pid == -1) { panic("can't fork"); } if (ischild(p->pid)) { - Fileid in, out; - traceme(); if (infile != nil) { in = open(infile, 0); @@ -699,7 +751,7 @@ String outfile; } fswap(1, out); } - execvp(argv[0], argv); + execv(argv[0], argv); write(2, "can't exec ", 11); write(2, argv[0], strlen(argv[0])); write(2, "\n", 1); @@ -710,20 +762,22 @@ String outfile; if (p->status != STOPPED) { error("program could not begin execution"); } + ptraced(p->pid); } /* - * Continue a stopped process. The 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, + * 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) +private pcont(p, signo) Process p; +int signo; { int status; @@ -731,10 +785,10 @@ Process p; error("program not active"); } do { - setinfo(p); + setinfo(p, signo); sigs_off(); if (ptrace(CONT, p->pid, p->reg[PROGCTR], p->signo) < 0) { - panic("can't continue process"); + panic("error %d trying to continue process", errno); } pwait(p->pid, &status); sigs_on(); @@ -751,7 +805,7 @@ Process p; { int status; - setinfo(p); + setinfo(p, DEFSIG); sigs_off(); ptrace(SSTEP, p->pid, p->reg[PROGCTR], p->signo); pwait(p->pid, &status); @@ -836,6 +890,7 @@ register int status; p->exitval = ((status >> 8)&0377); if (p->signo != STOPPED) { p->status = FINISHED; + p->pid = 0; } else { p->status = p->signo; p->signo = p->exitval; @@ -845,6 +900,7 @@ register int status; p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0); p->oreg[i] = p->reg[i]; } + savetty(stdout, &(p->ttyinfo)); } } @@ -852,20 +908,26 @@ register int status; * Set process's user area information from given process structure. */ -private setinfo(p) +private setinfo(p, signo) register Process p; +int signo; { register int i; register int r; - if (istraced(p)) { - p->signo = 0; + if (signo == DEFSIG) { + if (istraced(p)) { + 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); } } + restoretty(stdout, &(p->ttyinfo)); } /*