xref: /plan9/sys/src/cmd/db/main.c (revision 588d0145e19f8596f2f4442d05dd8a9eda147983)
1 /*
2  * db - main command loop and error/interrupt handling
3  */
4 #include "defs.h"
5 #include "fns.h"
6 
7 int wtflag = OREAD;
8 BOOL kflag;
9 
10 BOOL mkfault;
11 ADDR maxoff;
12 
13 int xargc;		/* bullshit */
14 
15 extern	BOOL	executing;
16 extern	int	infile;
17 int	exitflg;
18 extern	int	eof;
19 
20 int	alldigs(char*);
21 void	fault(void*, char*);
22 
23 extern	char	*Ipath;
24 jmp_buf env;
25 static char *errmsg;
26 
27 void
main(int argc,char ** argv)28 main(int argc, char **argv)
29 {
30 	char b1[100];
31 	char b2[100];
32 	char *s;
33 	char *name;
34 
35 	name = 0;
36 	outputinit();
37 	maxoff = MAXOFF;
38 	ARGBEGIN{
39 	case 'k':
40 		kflag = 1;
41 		break;
42 	case 'w':
43 		wtflag = ORDWR;		/* suitable for open() */
44 		break;
45 	case 'I':
46 		s = ARGF();
47 		if(s == 0)
48 			dprint("missing -I argument\n");
49 		else
50 			Ipath = s;
51 		break;
52 	case 'm':
53 		name = ARGF();
54 		if(name == 0)
55 			dprint("missing -m argument\n");
56 		break;
57 	}ARGEND
58 	symfil = 0;
59 	corfil = 0;
60 	if (argc > 0 && !alldigs(argv[0])) {
61 		symfil = argv[0];
62 		argv++;
63 		argc--;
64 	}
65 	if(argc==1 && alldigs(argv[0])){
66 		char *cpu, *p, *q;
67 
68 		pid = atoi(argv[0]);
69 		pcsactive = 0;
70 		if (!symfil) {
71 			if(kflag){
72 				cpu = getenv("cputype");
73 				if(cpu == 0){
74 					cpu = "386";
75 					dprint("$cputype not set; assuming %s\n", cpu);
76 				}
77 				p = getenv("terminal");
78 				if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){
79 					strcpy(b1, "/386/9pc");
80 					dprint("missing or bad $terminal; assuming %s\n", b1);
81 				}else{
82 					p++;
83 					q = strchr(p, ' ');
84 					if(q)
85 						*q = 0;
86 					sprint(b1, "/%s/9%s", cpu, p);
87 
88 				}
89 			}else
90 				sprint(b1, "/proc/%s/text", argv[0]);
91 			symfil = b1;
92 		}
93 		sprint(b2, "/proc/%s/mem", argv[0]);
94 		corfil = b2;
95 	} else if (argc > 0) {
96 		fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");
97 		exits("usage");
98 	}
99 	if (!symfil)
100 		symfil = "8.out";
101 	xargc = argc;
102 	notify(fault);
103 	setsym();
104 	dotmap = dumbmap(-1);
105 	if (name && machbyname(name) == 0)
106 		dprint("unknown machine %s\n", name);
107 	dprint("%s binary\n", mach->name);
108 	if(setjmp(env) == 0){
109 		if (corfil) {
110 			setcor();	/* could get error */
111 			dprint("%s\n", machdata->excep(cormap, rget));
112 			printpc();
113 		}
114 	}
115 
116 	setjmp(env);
117 	if (executing)
118 		delbp();
119 	executing = FALSE;
120 	for (;;) {
121 		flushbuf();
122 		if (errmsg) {
123 			dprint(errmsg);
124 			printc('\n');
125 			errmsg = 0;
126 			exitflg = 0;
127 		}
128 		if (mkfault) {
129 			mkfault=0;
130 			printc('\n');
131 			prints(DBNAME);
132 		}
133 		clrinp();
134 		rdc();
135 		reread();
136 		if (eof) {
137 			if (infile == STDIN)
138 				done();
139 			iclose(-1, 0);
140 			eof = 0;
141 			longjmp(env, 1);
142 		}
143 		exitflg = 0;
144 		command(0, 0);
145 		reread();
146 		if (rdc() != '\n')
147 			error("newline expected");
148 	}
149 }
150 
151 int
alldigs(char * s)152 alldigs(char *s)
153 {
154 	while(*s){
155 		if(*s<'0' || '9'<*s)
156 			return 0;
157 		s++;
158 	}
159 	return 1;
160 }
161 
162 void
done(void)163 done(void)
164 {
165 	if (pid)
166 		endpcs();
167 	exits(exitflg? "error": 0);
168 }
169 
170 /*
171  * An error occurred; save the message for later printing,
172  * close open files, and reset to main command loop.
173  */
174 void
error(char * n)175 error(char *n)
176 {
177 	errmsg = n;
178 	iclose(0, 1);
179 	oclose();
180 	flush();
181 	delbp();
182 	ending = 0;
183 	longjmp(env, 1);
184 }
185 
186 void
errors(char * m,char * n)187 errors(char *m, char *n)
188 {
189 	static char buf[128];
190 
191 	sprint(buf, "%s: %s", m, n);
192 	error(buf);
193 }
194 
195 /*
196  * An interrupt occurred;
197  * seek to the end of the current file
198  * and remember that there was a fault.
199  */
200 void
fault(void * a,char * s)201 fault(void *a, char *s)
202 {
203 	USED(a);
204 	if(strncmp(s, "interrupt", 9) == 0){
205 		seek(infile, 0L, 2);
206 		mkfault++;
207 		noted(NCONT);
208 	}
209 	noted(NDFLT);
210 }
211