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