update to version 3.0
[unix-history] / usr / src / old / dbx / process.c
index 06f35b7..f6dd774 100644 (file)
@@ -1,6 +1,8 @@
 /* Copyright (c) 1982 Regents of the University of California */
 
 /* Copyright (c) 1982 Regents of the University of California */
 
-static char sccsid[] = "@(#)process.c  1.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)process.c  1.17 (Berkeley) %G%";
+
+static char rcsid[] = "$Header: process.c,v 1.5 84/12/26 10:41:37 linton Exp $";
 
 /*
  * Process management.
 
 /*
  * Process management.
@@ -23,7 +25,6 @@ static        char sccsid[] = "@(#)process.c  1.16 (Berkeley) %G%";
 #include "coredump.h"
 #include <signal.h>
 #include <errno.h>
 #include "coredump.h"
 #include <signal.h>
 #include <errno.h>
-#include <ptrace.h>
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/user.h>
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/user.h>
@@ -70,7 +71,7 @@ struct Process {
     Word oreg[NREG];           /* registers when process last stopped */
     short status;              /* either STOPPED or FINISHED */
     short signo;               /* signal that stopped process */
     Word oreg[NREG];           /* registers when process last stopped */
     short status;              /* either STOPPED or FINISHED */
     short signo;               /* signal that stopped process */
-    short sigcode;             /* auxiliary signal info code */
+    short sigcode;             /* extra signal information */
     int exitval;               /* return value from exit() */
     long sigset;               /* bit array of traced signals */
     CacheWord word[CSIZE];     /* text segment cache */
     int exitval;               /* return value from exit() */
     long sigset;               /* bit array of traced signals */
     CacheWord word[CSIZE];     /* text segment cache */
@@ -87,7 +88,7 @@ typedef enum { TEXTSEG, DATASEG } PioSeg;
 
 private struct Process pbuf;
 
 
 private struct Process pbuf;
 
-#define MAXNCMDARGS 100         /* maximum number of arguments to RUN */
+#define MAXNCMDARGS 1000         /* maximum number of arguments to RUN */
 
 extern int errno;
 
 
 extern int errno;
 
@@ -176,10 +177,10 @@ String infile, outfile;
     } else {
        argv[argc] = nil;
     }
     } else {
        argv[argc] = nil;
     }
+    pstart(process, argv, infile, outfile);
     if (remade(objname)) {
        reinit(argv, infile, outfile);
     }
     if (remade(objname)) {
        reinit(argv, infile, outfile);
     }
-    pstart(process, argv, infile, outfile);
     if (process->status == STOPPED) {
        pc = 0;
        setcurfunc(program);
     if (process->status == STOPPED) {
        pc = 0;
        setcurfunc(program);
@@ -309,9 +310,6 @@ typedef int Intfunc();
 private Intfunc *dbintr;
 private intr();
 
 private Intfunc *dbintr;
 private intr();
 
-#define succeeds    == true
-#define fails       == false
-
 public cont(signo)
 integer signo;
 {
 public cont(signo)
 integer signo;
 {
@@ -336,7 +334,7 @@ integer signo;
            resume(s);
            unsetallbps();
            s = DEFSIG;
            resume(s);
            unsetallbps();
            s = DEFSIG;
-           if (bpact() fails) {
+           if (not isbperr() or not bpact()) {
                printstatus();
            }
        }
                printstatus();
            }
        }
@@ -346,12 +344,12 @@ integer signo;
 }
 
 /*
 }
 
 /*
- * This routine is called if we get an interrupt while "running" px
+ * 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
  * 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
+ * that when the process resumes it will get the interrupt,
  * which will then be handled.
  */
 
  * which will then be handled.
  */
 
@@ -381,7 +379,11 @@ int signo;
        if (p->signo != 0) {
            error("program terminated by signal %d", p->signo);
        } else if (not runfirst) {
        if (p->signo != 0) {
            error("program terminated by signal %d", p->signo);
        } else if (not runfirst) {
-           error("program unexpectedly exited with %d", p->exitval);
+           if (p->exitval == 0) {
+               error("program exited");
+           } else {
+               error("program exited with code %d", p->exitval);
+           }
        }
     }
 }
        }
     }
 }
@@ -457,7 +459,7 @@ Symbol f;
                    contto(addr);
                }
            }
                    contto(addr);
                }
            }
-           if (bpact() fails) {
+           if (not bpact()) {
                isstopped = true;
                printstatus();
            }
                isstopped = true;
                printstatus();
            }
@@ -495,9 +497,8 @@ public stepover()
 }
 
 /*
 }
 
 /*
- * Resume execution up to the given address.  It is assumed that
- * no breakpoints exist between the current address and the one
- * we're stepping to.  This saves us from setting all the breakpoints.
+ * Resume execution up to the given address.  We can either ignore
+ * breakpoints (stepto) or catch them (contto).
  */
 
 public stepto(addr)
  */
 
 public stepto(addr)
@@ -611,16 +612,43 @@ Process p;
 }
 
 /*
 }
 
 /*
- * Return the signal number which stopped the process.
+ * 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 Integer errnum(p)
+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;
 }
 
 Process p;
 {
     return p->signo;
 }
 
-public Integer errcode(p)
+/*
+ * Return the signal code associated with the signal.
+ */
+
+public integer errcode (p)
 Process p;
 {
     return p->sigcode;
 Process p;
 {
     return p->sigcode;
@@ -630,7 +658,7 @@ Process p;
  * Return the termination code of the process.
  */
 
  * Return the termination code of the process.
  */
 
-public Integer exitcode(p)
+public integer exitcode (p)
 Process p;
 {
     return p->exitval;
 Process p;
 {
     return p->exitval;
@@ -704,14 +732,16 @@ int nbytes;
 {
     Intfunc *f;
 
 {
     Intfunc *f;
 
-    f = onsyserr(EIO, read_err);
     badaddr = addr;
     if (coredump) {
     badaddr = addr;
     if (coredump) {
+       f = onsyserr(EFAULT, read_err);
        coredump_readdata(buff, addr, nbytes);
        coredump_readdata(buff, addr, nbytes);
+       onsyserr(EFAULT, f);
     } else {
     } else {
+       f = onsyserr(EIO, read_err);
        pio(process, PREAD, DATASEG, buff, addr, nbytes);
        pio(process, PREAD, DATASEG, buff, addr, nbytes);
+       onsyserr(EIO, f);
     }
     }
-    onsyserr(EIO, f);
 }
 
 /*
 }
 
 /*
@@ -769,10 +799,24 @@ private write_err()
 #define FIRSTSIG        SIGINT
 #define LASTSIG         SIGQUIT
 #define ischild(pid)    ((pid) == 0)
 #define FIRSTSIG        SIGINT
 #define LASTSIG         SIGQUIT
 #define ischild(pid)    ((pid) == 0)
-#define traceme()       ptrace(PT_TRACE_ME, 0, 0, 0)
+#define traceme()       ptrace(0, 0, 0, 0)
 #define setrep(n)       (1 << ((n)-1))
 #define istraced(p)     (p->sigset&setrep(p->signo))
 
 #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 */
+
 /*
  * Start up a new process by forking and exec-ing the
  * given argument list, returning when the process is loaded
 /*
  * Start up a new process by forking and exec-ing the
  * given argument list, returning when the process is loaded
@@ -794,13 +838,16 @@ String outfile;
 
     if (p->pid != 0) {
        pterm(p);
 
     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)) {
     psigtrace(p, SIGTRAP, true);
     p->pid = vfork();
     if (p->pid == -1) {
        panic("can't fork");
     }
     if (ischild(p->pid)) {
+       nocatcherrs();
        traceme();
        if (infile != nil) {
            infrom(infile);
        traceme();
        if (infile != nil) {
            infrom(infile);
@@ -809,17 +856,16 @@ String outfile;
            outto(outfile);
        }
        execv(argv[0], argv);
            outto(outfile);
        }
        execv(argv[0], argv);
-       write(2, "can't exec ", 11);
-       write(2, argv[0], strlen(argv[0]));
-       write(2, "\n", 1);
        _exit(1);
     }
     pwait(p->pid, &status);
     getinfo(p, status);
     if (p->status != STOPPED) {
        _exit(1);
     }
     pwait(p->pid, &status);
     getinfo(p, status);
     if (p->status != STOPPED) {
-       error("program could not begin execution");
+       beginerrmsg();
+       fprintf(stderr, "warning: cannot execute %s\n", argv[0]);
+    } else {
+       ptraced(p->pid);
     }
     }
-    ptraced(p->pid);
 }
 
 /*
 }
 
 /*
@@ -832,7 +878,7 @@ Process p;
     integer status;
 
     if (p != nil and p->pid != 0) {
     integer status;
 
     if (p != nil and p->pid != 0) {
-       ptrace(PT_KILL, p->pid, 0, 0);
+       ptrace(PKILL, p->pid, 0, 0);
        pwait(p->pid, &status);
        unptraced(p->pid);
     }
        pwait(p->pid, &status);
        unptraced(p->pid);
     }
@@ -855,7 +901,7 @@ int signo;
     int s, status;
 
     if (p->pid == 0) {
     int s, status;
 
     if (p->pid == 0) {
-       error("program not active");
+       error("program is not active");
     }
     s = signo;
     do {
     }
     s = signo;
     do {
@@ -866,14 +912,15 @@ int signo;
            fflush(stdout);
        }
        sigs_off();
            fflush(stdout);
        }
        sigs_off();
-       if (ptrace(PT_CONTINUE, p->pid, p->reg[PROGCTR], p->signo) < 0) {
+       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);
            panic("error %d trying to continue process", errno);
        }
        pwait(p->pid, &status);
        sigs_on();
        getinfo(p, status);
-       if (traceexec and not istraced(p)) {
-           printf("!! ignored signal %d at 0x%x\n", p->signo, p->reg[PROGCTR]);
+       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;
            fflush(stdout);
        }
        s = p->signo;
@@ -892,27 +939,41 @@ public pstep(p, signo)
 Process p;
 integer signo;
 {
 Process p;
 integer signo;
 {
-    int status;
+    int s, status;
 
 
-    setinfo(p, signo);
-    if (traceexec) {
-       printf("!! pstep from pc 0x%x with signal %d (%d)\n",
-           p->reg[PROGCTR], signo, p->signo);
-       fflush(stdout);
-    }
-    sigs_off();
-    if (ptrace(PT_STEP, 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);
+    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) {
     if (traceexec) {
-       printf("!! pstep to pc 0x%x on signal %d\n", p->reg[PROGCTR], p->signo);
+       printf("!! pstep to 0x%x on signal %d\n",
+           p->reg[PROGCTR], p->signo);
        fflush(stdout);
     }
     if (p->status != STOPPED) {
        fflush(stdout);
     }
     if (p->status != STOPPED) {
-       error("program unexpectedly exited with %d\n", p->exitval);
+       if (p->exitval == 0) {
+           error("program exited\n");
+       } else {
+           error("program exited with code %d\n", p->exitval);
+       }
     }
 }
 
     }
 }
 
@@ -999,16 +1060,16 @@ register int status;
     } else {
        p->status = p->signo;
        p->signo = p->exitval;
     } else {
        p->status = p->signo;
        p->signo = p->exitval;
-       p->sigcode = ptrace(PT_READ_U, p->pid, &((struct user *)0)->u_code, 0);
+       p->sigcode = ptrace(UREAD, p->pid, &((struct user *) 0)->u_code, 0);
        p->exitval = 0;
        p->exitval = 0;
-       p->mask = ptrace(PT_READ_U, p->pid, regloc(PS), 0);
+       p->mask = ptrace(UREAD, p->pid, regloc(PS), 0);
        for (i = 0; i < NREG; i++) {
        for (i = 0; i < NREG; i++) {
-           p->reg[i] = ptrace(PT_READ_U, p->pid, regloc(rloc[i]), 0);
+           p->reg[i] = ptrace(UREAD, p->pid, regloc(rloc[i]), 0);
            p->oreg[i] = p->reg[i];
        }
        savetty(stdout, &(p->ttyinfo));
        addr = (Address) &(((struct user *) 0)->u_signal[p->signo]);
            p->oreg[i] = p->reg[i];
        }
        savetty(stdout, &(p->ttyinfo));
        addr = (Address) &(((struct user *) 0)->u_signal[p->signo]);
-       p->sigstatus = (Address) ptrace(PT_READ_U, p->pid, addr, 0);
+       p->sigstatus = (Address) ptrace(UREAD, p->pid, addr, 0);
     }
 }
 
     }
 }
 
@@ -1032,7 +1093,7 @@ int signo;
     }
     for (i = 0; i < NREG; i++) {
        if ((r = p->reg[i]) != p->oreg[i]) {
     }
     for (i = 0; i < NREG; i++) {
        if ((r = p->reg[i]) != p->oreg[i]) {
-           ptrace(PT_WRITE_U, p->pid, regloc(rloc[i]), r);
+           ptrace(UWRITE, p->pid, regloc(rloc[i]), r);
        }
     }
     restoretty(stdout, &(p->ttyinfo));
        }
     }
     restoretty(stdout, &(p->ttyinfo));
@@ -1164,7 +1225,7 @@ register int addr;
            wp = &p->word[cachehash(addr)];
            if (addr == 0 or wp->addr != addr) {
                ++nreads;
            wp = &p->word[cachehash(addr)];
            if (addr == 0 or wp->addr != addr) {
                ++nreads;
-               w = ptrace(PT_READ_I, p->pid, addr, 0);
+               w = ptrace(IREAD, p->pid, addr, 0);
                wp->addr = addr;
                wp->val = w;
            } else {
                wp->addr = addr;
                wp->val = w;
            } else {
@@ -1173,7 +1234,7 @@ register int addr;
            break;
 
        case DATASEG:
            break;
 
        case DATASEG:
-           w = ptrace(PT_READ_D, p->pid, addr, 0);
+           w = ptrace(DREAD, p->pid, addr, 0);
            break;
 
        default:
            break;
 
        default:
@@ -1202,11 +1263,11 @@ Word data;
            wp = &p->word[cachehash(addr)];
            wp->addr = addr;
            wp->val = data;
            wp = &p->word[cachehash(addr)];
            wp->addr = addr;
            wp->val = data;
-           ptrace(PT_WRITE_I, p->pid, addr, data);
+           ptrace(IWRITE, p->pid, addr, data);
            break;
 
        case DATASEG:
            break;
 
        case DATASEG:
-           ptrace(PT_WRITE_D, p->pid, addr, data);
+           ptrace(DWRITE, p->pid, addr, data);
            break;
 
        default:
            break;
 
        default:
@@ -1215,6 +1276,16 @@ Word data;
     }
 }
 
     }
 }
 
+/*
+ * 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);
 public printptraceinfo()
 {
     printf("%d fetchs, %d reads, %d writes\n", nfetchs, nreads, nwrites);
@@ -1276,64 +1347,71 @@ Fileid newfd;
     }
 }
 
     }
 }
 
-#define        bit(i)          (1 << ((i)-1))
 /*
 /*
- * Signal manipulation routines.
+ * Signal name manipulation.
  */
  */
-static String signames[NSIG] = {
-       0,
-       "HUP",
-       "INT",
-       "QUIT",
-       "ILL",
-       "TRAP",
-       "IOT",
-       "EMT",
-       "FPE",
-       "KILL",
-       "BUS",
-       "SEGV",
-       "SYS",
-       "PIPE",
-       "ALRM",
-       "TERM",
-       0,
-       "STOP",
-       "TSTP",
-       "CONT",
-       "CHLD",
-       "TTIN",
-       "TTOU",
-       "TINT",
-       "XCPU",
-       "XFSZ",
+
+private String signames[NSIG] = {
+    0,
+    "HUP", "INT", "QUIT", "ILL", "TRAP",
+    "IOT", "EMT", "FPE", "KILL", "BUS",
+    "SEGV", "SYS", "PIPE", "ALRM", "TERM",
+    0, "STOP", "TSTP", "CONT", "CHLD",
+    "TTIN", "TTOU", "TINT", "XCPU", "XFSZ",
 };
 
 /*
 };
 
 /*
- * Map a signal name to a number.
+ * Get the signal number associated with a given name.
+ * The name is first translated to upper case if necessary.
  */
  */
-public signalname(s)
+
+public integer siglookup (s)
 String s;
 {
 String s;
 {
-       register String *p;
-
-       if (strneq(s, "SIG", 3))
-           s += 3;
-       for (p = signames; p < &signames[NSIG]; p++)
-               if (*p && streq(*p, s))
-                       return (p - signames);
-       error("%s: Unknown signal.", 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
+ * Print all signals being ignored by the debugger.
+ * These signals are auotmatically
  * passed on to the debugged process.
  */
  * passed on to the debugged process.
  */
-public printsigsignored(p)
+
+public printsigsignored (p)
 Process p;
 {
 Process p;
 {
-
     printsigs(~p->sigset);
 }
 
     printsigs(~p->sigset);
 }
 
@@ -1341,26 +1419,30 @@ Process p;
  * Print all signals being intercepted by
  * the debugger for the specified process.
  */
  * Print all signals being intercepted by
  * the debugger for the specified process.
  */
+
 public printsigscaught(p)
 Process p;
 {
 public printsigscaught(p)
 Process p;
 {
-
     printsigs(p->sigset);
 }
 
     printsigs(p->sigset);
 }
 
-private printsigs(vec)
-register Integer vec;
+private printsigs (set)
+integer set;
 {
 {
-    register Integer s;
-    String sep = "";
-
-    for (s = 1; s < NSIG; s++)
-       if (vec & bit(s) && signames[s]) {
-           printf("%s%s", sep, signames[s]);
-           sep = " ";
+    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 (*sep != '\0') {
+    }
+    if (separator[0] == ' ') {
        putchar('\n');
        putchar('\n');
-       fflush(stdout);
     }
 }
     }
 }