1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)runcont.c 1.3 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 } 121 122 /* 123 * Run starts debuggee executing. 124 */ 125 126 run() 127 { 128 fixbps(); 129 curline = 0; 130 argv[argc] = NIL; 131 start(argv, infile, outfile); 132 just_started = TRUE; 133 isstopped = FALSE; 134 cont(); 135 } 136 137 /* 138 * Continue execution wherever we left off. 139 * 140 * Note that this routine never returns. Eventually bpact() will fail 141 * and we'll call printstatus or step will call it. 142 */ 143 144 typedef int INTFUNC(); 145 146 LOCAL INTFUNC *dbintr; 147 LOCAL intr(); 148 149 #define succeeds == TRUE 150 #define fails == FALSE 151 152 cont() 153 { 154 dbintr = signal(SIGINT, intr); 155 if (just_started) { 156 just_started = FALSE; 157 } else { 158 if (!isstopped) { 159 error("can't continue execution"); 160 } 161 isstopped = FALSE; 162 step(); 163 } 164 for (;;) { 165 if (single_stepping) { 166 printnews(); 167 } else { 168 setallbps(); 169 resume(); 170 unsetallbps(); 171 if (bpact() fails) { 172 printstatus(); 173 } 174 } 175 step(); 176 } 177 /* NOTREACHED */ 178 } 179 180 /* 181 * This routine is called if we get an interrupt while "running" px 182 * but actually in the debugger. Could happen, for example, while 183 * processing breakpoints. 184 * 185 * We basically just want to keep going; the assumption is 186 * that when the process resumes it will get the interrupt 187 * which will then be handled. 188 */ 189 190 LOCAL intr() 191 { 192 signal(SIGINT, intr); 193 } 194 195 fixintr() 196 { 197 signal(SIGINT, dbintr); 198 } 199