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