1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)runcont.c 1.4 03/08/82"; 4 5 /* 6 * Execution management. 7 */ 8 9 #include "defs.h" 10 #include <signal.h> 11 #include "process.h" 12 #include "machine.h" 13 #include "object.h" 14 #include "main.h" 15 #include "breakpoint.h" 16 #include "command.h" 17 #include "process.rep" 18 19 #define MAXNARGS 100 /* maximum number of arguments to RUN */ 20 21 typedef char *String; 22 23 LOCAL BOOLEAN just_started; 24 LOCAL int argc; 25 LOCAL String argv[MAXNARGS]; 26 LOCAL String infile; 27 LOCAL String outfile; 28 LOCAL PROCESS pbuf; 29 30 /* 31 * This is a px-related kludge to deal with the possibility 32 * of object code magically coming from a tmp file. 33 */ 34 35 LOCAL String mode; 36 LOCAL String realname; 37 38 setargs(m, r) 39 char *m, *r; 40 { 41 mode = m; 42 realname = r; 43 } 44 45 /* 46 * Initialize the argument list. 47 */ 48 49 arginit() 50 { 51 infile = NIL; 52 outfile = NIL; 53 # if (isvaxpx) 54 argv[0] = mode; 55 argv[1] = objname; 56 if (option('t') && realname == NIL) { 57 argc = 2; 58 } else { 59 argv[2] = realname; 60 argc = 3; 61 } 62 # else 63 argv[0] = objname; 64 argc = 1; 65 # endif 66 } 67 68 /* 69 * Add an argument to the list for the debuggee. 70 */ 71 72 newarg(arg) 73 String arg; 74 { 75 if (argc >= MAXNARGS) { 76 error("too many arguments to run"); 77 } 78 argv[argc++] = arg; 79 } 80 81 /* 82 * Set the standard input for the debuggee. 83 */ 84 85 inarg(filename) 86 String filename; 87 { 88 if (infile != NIL) { 89 error("multiple input redirects"); 90 } 91 infile = filename; 92 } 93 94 /* 95 * Set the standard output for the debuggee. 96 * Probably should check to avoid overwriting an existing file. 97 */ 98 99 outarg(filename) 100 String filename; 101 { 102 if (outfile != NIL) { 103 error("multiple output redirect"); 104 } 105 outfile = filename; 106 } 107 108 /* 109 * Initial start of the process. The idea is to get it to the point 110 * where the object code has been loaded but execution has not begun. 111 */ 112 113 initstart() 114 { 115 arginit(); 116 argv[argc] = NIL; 117 process = &pbuf; 118 initcache(process); 119 start(argv, infile, outfile); 120 if (process->status != STOPPED) { 121 panic("could not start program"); 122 } 123 } 124 125 /* 126 * Run starts debuggee executing. 127 */ 128 129 run() 130 { 131 fixbps(); 132 curline = 0; 133 argv[argc] = NIL; 134 start(argv, infile, outfile); 135 if (process->status == STOPPED) { 136 just_started = TRUE; 137 isstopped = FALSE; 138 cont(); 139 } else if (option('r')) { 140 panic("could not start program"); 141 } 142 } 143 144 /* 145 * Continue execution wherever we left off. 146 * 147 * Note that this routine never returns. Eventually bpact() will fail 148 * and we'll call printstatus or step will call it. 149 */ 150 151 typedef int INTFUNC(); 152 153 LOCAL INTFUNC *dbintr; 154 LOCAL intr(); 155 156 #define succeeds == TRUE 157 #define fails == FALSE 158 159 cont() 160 { 161 dbintr = signal(SIGINT, intr); 162 if (just_started) { 163 just_started = FALSE; 164 } else { 165 if (!isstopped) { 166 error("can't continue execution"); 167 } 168 isstopped = FALSE; 169 step(); 170 } 171 for (;;) { 172 if (single_stepping) { 173 printnews(); 174 } else { 175 setallbps(); 176 resume(); 177 unsetallbps(); 178 if (bpact() fails) { 179 printstatus(); 180 } 181 } 182 step(); 183 } 184 /* NOTREACHED */ 185 } 186 187 /* 188 * This routine is called if we get an interrupt while "running" px 189 * but actually in the debugger. Could happen, for example, while 190 * processing breakpoints. 191 * 192 * We basically just want to keep going; the assumption is 193 * that when the process resumes it will get the interrupt 194 * which will then be handled. 195 */ 196 197 LOCAL intr() 198 { 199 signal(SIGINT, intr); 200 } 201 202 fixintr() 203 { 204 signal(SIGINT, dbintr); 205 } 206