fixed problem with stab type for initialized static variables,
[unix-history] / usr / src / old / dbx / main.c
CommitLineData
00102538
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
1c5b15ac 3static char sccsid[] = "@(#)main.c 1.5 %G%";
00102538
ML
4
5/*
6 * Debugger main routine.
7 */
8
9#include "defs.h"
10#include <setjmp.h>
11#include <signal.h>
12#include <errno.h>
13#include "main.h"
1c5b15ac 14#include "symbols.h"
00102538
ML
15#include "scanner.h"
16#include "process.h"
17#include "source.h"
18#include "object.h"
1c5b15ac 19#include "mappings.h"
00102538
ML
20
21#ifndef public
22
23#define isterm(file) (interactive or isatty(fileno(file)))
24
39144fe1
ML
25#include <sgtty.h>
26
27typedef struct sgttyb Ttyinfo;
28
00102538
ML
29#endif
30
31public Boolean coredump; /* true if using a core dump */
32public Boolean runfirst; /* run program immediately */
33public Boolean interactive; /* standard input IS a terminal */
34public Boolean lexdebug; /* trace yylex return values */
35public Boolean tracebpts; /* trace create/delete breakpoints */
36public Boolean traceexec; /* trace process execution */
37public Boolean tracesyms; /* print symbols as their read */
38
39public File corefile; /* File id of core dump */
40
41#define FIRST_TIME 0 /* initial value setjmp returns */
42
43private Boolean initdone = false; /* true if initialization done */
44private jmp_buf env; /* setjmp/longjmp data */
45private char outbuf[BUFSIZ]; /* standard output buffer */
46private char namebuf[512]; /* possible name of object file */
47private int firstarg; /* first program argument (for -r) */
48
39144fe1
ML
49private Ttyinfo ttyinfo;
50
00102538
ML
51private catchintr();
52
53/*
54 * Main program.
55 */
56
57main(argc, argv)
58int argc;
59String argv[];
60{
61 register Integer i;
39144fe1 62 extern String date;
00102538
ML
63
64 cmdname = argv[0];
65 catcherrs();
66 onsyserr(EINTR, nil);
67 setbuf(stdout, outbuf);
39144fe1
ML
68 printf("dbx version of %s.\nType 'help' for help.\n", date);
69 fflush(stdout);
00102538
ML
70 scanargs(argc, argv);
71 language_init();
72 process_init();
73 if (runfirst) {
74 if (setjmp(env) == FIRST_TIME) {
75 arginit();
76 for (i = firstarg; i < argc; i++) {
77 newarg(argv[i]);
78 }
79 run();
80 /* NOTREACHED */
81 } else {
82 runfirst = false;
83 }
84 } else {
85 init();
86 }
87 setjmp(env);
39144fe1 88 restoretty(stdout, &ttyinfo);
00102538
ML
89 signal(SIGINT, catchintr);
90 yyparse();
91 putchar('\n');
92 quit(0);
93}
94
95/*
96 * Initialize the world, including setting initial input file
97 * if the file exists.
98 */
99
100public init()
101{
102 File f;
103 String home;
104 char buf[100];
105 extern String getenv();
106
39144fe1 107 savetty(stdout, &ttyinfo);
00102538
ML
108 enterkeywords();
109 scanner_init();
110 if (not coredump and not runfirst) {
111 start(nil, nil, nil);
112 }
39144fe1
ML
113 printf("reading symbolic information ...");
114 fflush(stdout);
00102538 115 readobj(objname);
39144fe1
ML
116 printf("\n");
117 fflush(stdout);
1c5b15ac
ML
118 if (coredump) {
119 curfunc = whatblock(pc);
120 } else {
121 curfunc = program;
122 }
00102538
ML
123 bpinit();
124 f = fopen(initfile, "r");
125 if (f != nil) {
126 fclose(f);
127 setinput(initfile);
128 } else {
129 home = getenv("HOME");
130 if (home != nil) {
131 sprintf(buf, "%s/%s", home, initfile);
132 f = fopen(buf, "r");
133 if (f != nil) {
134 fclose(f);
135 setinput(strdup(buf));
136 }
137 }
138 }
139 initdone = true;
140}
141
142/*
143 * Re-initialize the world, first de-allocating all storage.
144 * This is necessary when the symbol information must be re-read
145 * from the object file when it has changed.
146 *
147 * Before "forgetting" things, we save the current tracing/breakpoint
148 * information to a temp file. Then after re-creating the world,
149 * we read the temp file as commands. This isn't always the right thing;
150 * if a procedure that was being traced is deleted, an error message
151 * will be generated.
152 *
153 * If the argument vector is not nil, then this is re-initialize is being
154 * done in preparation for running the program. Since we want to process
155 * the commands in the temp file before running the program, we add the
156 * run command at the end of the temp file. In this case, reinit longjmps
157 * back to parsing rather than returning.
158 */
159
160public reinit(argv, infile, outfile)
161String *argv;
162String infile;
163String outfile;
164{
165 register Integer i;
166 String tmpfile;
167 extern String mktemp();
168
169 tmpfile = mktemp("/tmp/dbxXXXX");
170 setout(tmpfile);
171 status();
172 print_alias(nil);
173 if (argv != nil) {
174 printf("run");
175 for (i = 1; argv[i] != nil; i++) {
176 printf(" %s", argv[i]);
177 }
178 if (infile != nil) {
179 printf(" < %s", infile);
180 }
181 if (outfile != nil) {
182 printf(" > %s", outfile);
183 }
184 putchar('\n');
185 }
186 unsetout();
187 bpfree();
188 objfree();
189 process_init();
190 enterkeywords();
191 scanner_init();
192 readobj(objname);
193 bpinit();
194 fflush(stdout);
195 setinput(tmpfile);
196 unlink(tmpfile);
197 if (argv != nil) {
198 longjmp(env, 1);
199 /* NOTREACHED */
200 }
201}
202
203/*
204 * After a non-fatal error we jump back to command parsing.
205 */
206
207public erecover()
208{
209 if (initdone) {
210 gobble();
211 longjmp(env, 1);
212 }
213}
214
215/*
216 * This routine is called when an interrupt occurs.
217 */
218
219private catchintr()
220{
221 putchar('\n');
222 longjmp(env, 1);
223}
224
225/*
226 * Scan the argument list.
227 */
228
229private scanargs(argc, argv)
230int argc;
231String argv[];
232{
233 register int i, j;
234 register Boolean foundfile;
235 register File f;
236 char *tmp;
237
238 runfirst = false;
239 interactive = false;
240 lexdebug = false;
241 tracebpts = false;
242 traceexec = false;
243 tracesyms = false;
244 foundfile = false;
245 corefile = nil;
246 coredump = true;
247 sourcepath = list_alloc();
248 list_append(list_item("."), nil, sourcepath);
249 i = 1;
f14ef1ce 250 while (i < argc and (not foundfile or corefile == nil)) {
00102538
ML
251 if (argv[i][0] == '-') {
252 if (streq(argv[i], "-I")) {
253 ++i;
254 if (i >= argc) {
255 fatal("missing directory for -I");
256 }
257 list_append(list_item(argv[i]), nil, sourcepath);
258 } else {
259 for (j = 1; argv[i][j] != '\0'; j++) {
260 setoption(argv[i][j]);
261 }
262 }
263 } else if (not foundfile) {
264 objname = argv[i];
265 foundfile = true;
266 } else if (coredump and corefile == nil) {
267 corefile = fopen(argv[i], "r");
268 if (corefile == nil) {
269 coredump = false;
270 }
271 }
272 ++i;
273 }
274 if (i < argc and not runfirst) {
275 fatal("extraneous argument %s", argv[i]);
276 }
277 firstarg = i;
278 if (not foundfile and isatty(0)) {
279 printf("enter object file name (default is `%s'): ", objname);
280 fflush(stdout);
281 gets(namebuf);
282 if (namebuf[0] != '\0') {
283 objname = namebuf;
284 }
285 }
286 f = fopen(objname, "r");
287 if (f == nil) {
288 fatal("can't read %s", objname);
289 } else {
290 fclose(f);
291 }
292 if (rindex(objname, '/') != nil) {
293 tmp = strdup(objname);
294 *(rindex(tmp, '/')) = '\0';
295 list_append(list_item(tmp), nil, sourcepath);
296 }
297 if (coredump and corefile == nil) {
298 corefile = fopen("core", "r");
299 if (corefile == nil) {
300 coredump = false;
301 }
302 }
303}
304
305/*
306 * Take appropriate action for recognized command argument.
307 */
308
309private setoption(c)
310char c;
311{
312 switch (c) {
313 case 'r': /* run program before accepting commands */
314 runfirst = true;
315 coredump = false;
316 break;
317
318 case 'i':
319 interactive = true;
320 break;
321
322 case 'b':
323 tracebpts = true;
324 break;
325
326 case 'e':
327 traceexec = true;
328 break;
329
330 case 's':
331 tracesyms = true;
332 break;
333
334 case 'l':
335# ifdef LEXDEBUG
336 lexdebug = true;
337# else
338 fatal("\"-l\" only applicable when compiled with LEXDEBUG");
339# endif
340 break;
341
342 default:
343 fatal("unknown option '%c'", c);
344 }
345}
346
39144fe1
ML
347/*
348 * Save/restore the state of a tty.
349 */
350
351public savetty(f, t)
352File f;
353Ttyinfo *t;
354{
355 gtty(fileno(f), t);
356}
357
358public restoretty(f, t)
359File f;
360Ttyinfo *t;
361{
362 stty(fileno(f), t);
363}
364
00102538
ML
365/*
366 * Exit gracefully.
367 */
368
369public quit(r)
370Integer r;
371{
372 exit(r);
373}