Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
include("/sys/lib/acid/syscall");
2
 
3
// print various /proc files
4
defn fd() {
5
	rc("cat /proc/"+itoa(pid)+"/fd");
6
}
7
 
8
defn segment() {
9
	rc("cat /proc/"+itoa(pid)+"/segment");
10
}
11
 
12
defn ns() {
13
	rc("cat /proc/"+itoa(pid)+"/ns");
14
}
15
 
16
defn qid(qid) {
17
	complex Qid qid;
18
	return itoa(qid.path\X)+"."+itoa(qid.vers\X);
19
}
20
 
21
defn path(p) {
22
	complex Path p;
23
	if p != 0 then {
24
		return *(p.s\s);
25
	} else
26
		return "<null>";
27
}
28
 
29
// print Image cache contents
30
// requires include("/sys/src/9/xxx/segment.acid")
31
IHASHSIZE = 64;
32
defn imagecacheline(h) {
33
	while h != 0 do {
34
		complex Image h;
35
		print (h\X, " ", qid(h.qid), " type ", h.type\D, " ref ", h.ref, " next ", h.next\X, " ", path(h.c.path), "\n");
36
		h = h.hash;
37
	}
38
}
39
 
40
defn imagecache() {
41
	local i;
42
 
43
	i=0; loop 1,IHASHSIZE do {
44
		imagecacheline(imagealloc.free[i]);
45
		i = i+1;
46
	}
47
}
48
 
49
// dump channels
50
defn chan(c) {
51
	local d, q;
52
 
53
	c = (Chan)c;
54
	d=(Dev)(*(devtab+4*c.type));
55
	q=c.qid;
56
	print("chan(", c\X, "): ref=", c.ref\D, " #", d.dc\r, c.dev\D, " (", q.path, " ", q.vers\D, " ", q.type\X, ")");
57
	print(" fid=", c.fid\D, " iounit=", c.iounit\D);
58
	if c.ref != 0 then {
59
		print(" ", path(c.path), " mchan=", c.mchan\X);
60
		if c.mchan != 0 then {
61
			print(" ", path(c.mchan.path));
62
		}
63
	}
64
	print("\n");
65
}
66
 
67
defn chans() {
68
	local c;
69
 
70
	c = (Chan)chanalloc.list;
71
	while c != 0 do {
72
		if c.ref != 0 then
73
			chan(c);
74
		c=(Chan)c.link;
75
	}
76
}
77
 
78
defn nchans() {
79
	local c, n;
80
 
81
	n = 0;
82
	c = (Chan)chanalloc.list;
83
	while c != 0 do {
84
		if c.ref != 0 then
85
			n++;
86
		c = (Chan)c.link;
87
	}
88
	return n;
89
}
90
 
91
defn activechanlist() {
92
	local l, n;
93
 
94
	l = {};
95
	c = (Chan)chanalloc.list;
96
	while c != 0 do {
97
		if c.ref != 0 then
98
			l = append l,c;
99
		c = (Chan)c.link;
100
	}
101
	return l;
102
}
103
 
104
defn difflist(a, b) {
105
	local l, x;
106
 
107
	l = {};
108
	while a != {} do {
109
		x = head a;
110
		if match(x, b) == -1 then
111
			l = append l, x;
112
		a = tail a;
113
	}
114
	return l;
115
}
116
 
117
_active_chan_list = {};
118
defn newchans() {
119
	local l, new;
120
 
121
	l = activechanlist();
122
	if _active_chan_list != {} then
123
		newerchans(_active_chan_list);
124
	_active_chan_list = l;
125
}
126
 
127
defn newerchans(oldlist){
128
	local new;
129
 
130
	new = difflist(activechanlist(), oldlist);
131
	while new != {} do {
132
		chan(head new);
133
		new = tail new;
134
	}
135
}
136
 
137
// look for channels that refer to themselves
138
defn badchans() {
139
	local bad, c, i, len, mtpt, p;
140
 
141
	c = (Chan)chanalloc.list;
142
	while c != 0 do {
143
		if c.ref != 0 then {
144
			bad = "";
145
			p = (Path)c.path;
146
			if p != 0 then {
147
				path(p);
148
				mtpt = p.mtpt;
149
				len = p.mlen;
150
				i=0; loop 1,len do {
151
					if mtpt[i] == c then
152
						bad = bad+" mtpt self-ref";
153
					i = i+1;
154
				}
155
			}
156
			if bad != "" then
157
				print("chan(", c\X, "):", bad, "\n");
158
		}
159
		c = (Chan)c.link;
160
	}
161
}
162
 
163
// manipulate processes
164
defn proctab(x) {
165
	return procalloc.arena+sizeofProc*x;
166
}
167
 
168
defn proc(p) {
169
	complex Proc p;
170
	local s, i;
171
 
172
	if p.state != 0 && p.pid != 0 && p.text != 0 then {	// 0 is Dead
173
		s = p.psstate;
174
		if s == 0 then {
175
			s = "kproc";
176
		} else {
177
			s = *(s\s);
178
		}
179
		print(p\X, " ", p.pid, ": ", *(p.text\s), " ", *(p.user\s), " pc ", p.pc\X, " ", s, " (", *(statename[p.state]\s), ") ut ", p.time[0]\D, " st ", p.time[1]\D, " qpc ", p.qpc\X, "\n");
180
	}
181
}
182
 
183
defn procenv(p) {
184
	complex Proc p;
185
	local e, v;
186
 
187
	e = p.egrp;
188
	complex Egrp e;
189
	v = e.ent;
190
	while v != 0 do {
191
		complex Evalue v;
192
		print(*(v.name\s), "=");
193
		printstringn(v.value, v.len);
194
		print("\n");
195
		v = v.link;
196
	}
197
}
198
 
199
KSTACK=4096;
200
 
201
defn procstksize(p) {
202
	complex Proc p;
203
	local top, sp;
204
 
205
	if p.state != 0 then {	// 0 is Dead
206
		top = p.kstack+KSTACK;
207
		sp = *p.sched;
208
		print(top-sp\D, "\n");
209
	}
210
}
211
 
212
defn procstk(p) {
213
	complex Proc p;
214
	local l;
215
 
216
	if p.state != 0 then {	// 0 is Dead
217
		l = p.sched;
218
		if objtype=="386" then
219
			_stk(gotolabel, *l, linkreg(0), 0);
220
		else
221
			_stk(*(l+4), *l, linkreg(0), 0);
222
	}
223
}
224
 
225
defn procs() {
226
	local i;
227
 
228
	i=0; loop 1,conf.nproc do {
229
		proc(proctab(i));
230
		i = i+1;
231
	}
232
}
233
 
234
defn stacks() {
235
	local i, p;
236
 
237
	i=0; loop 1,conf.nproc do {
238
		p = (Proc)proctab(i);
239
		if p.state != 0 then {
240
			print("=========================================================\n");
241
			proc(p);
242
			procstk(p);
243
		}
244
		i = i+1;
245
	}
246
}
247
 
248
defn stacksizes() {
249
	local i;
250
 
251
	i=0; loop 1,conf.nproc do {
252
		procstksize(proctab(i));
253
		i = i+1;
254
	}
255
}
256
 
257
// segment-related
258
defn procsegs(p) {
259
	complex Proc p;
260
	local i;
261
 
262
	i=0; loop 1,NSEG do {
263
		psegment(p.seg[i]);
264
		i = i+1;
265
	}
266
}
267
 
268
segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
269
defn psegment(s) {
270
	complex Segment s;
271
 
272
	if s != 0 then {
273
		print(s\X, " ", segtypes[s.type&SG_TYPE], " ", s.base\X, "-", s.top\X, " image ", s.image\X, "\n");
274
	}
275
}
276
 
277
// find physical address for an address in a given process
278
defn procaddr(p, a) {
279
	complex Proc p;
280
	local i, s, r;
281
 
282
	r = 0;
283
	i=0; loop 1,NSEG do {
284
		s = p.seg[i];
285
		if s != 0 then {
286
			complex Segment s;
287
			if s.base <= a && a < s.top then {
288
				r = segaddr(s, a);
289
			}
290
		}
291
		i = i+1;
292
	}
293
	return r;
294
}
295
 
296
// find an address in a given segment
297
defn segaddr(s, a) {
298
	complex Segment s;
299
	local pte, pg;
300
 
301
	a = a - s.base;
302
	if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
303
		return 0;
304
	}
305
 
306
	pte = s.map[a/PTEMAPMEM];
307
	if pte == 0 then {
308
		return 0;
309
	}
310
 
311
	complex Pte pte;
312
	pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
313
	if pg == 0 then {
314
		return 0;
315
	}
316
 
317
	if pg & 1 then {	// swapped out, return disk address
318
		return pg&~1;
319
	}
320
 
321
	complex Page pg;
322
	return (KZERO|(pg.pa+(a%BY2PG)))\X;
323
}
324
 
325
defn kzero() {
326
	return main - (main & 0x0FFFFFFF);
327
}
328
 
329
// PC only
330
PTEMAPMEM = (1024*1024);
331
BY2PG = 4096;
332
PTEPERTAB = (PTEMAPMEM/BY2PG);
333
defn up() {
334
	local mach;
335
 
336
	MACHADDR = KZERO+0x15000;
337
	mach = MACHADDR;
338
	complex Mach mach;
339
	return mach.externup;
340
}
341
 
342
defn intrcount() {
343
	local p, pp, t, i, j;
344
 
345
	p = intrtimes;
346
	i=0;
347
	loop 1,256 do {
348
		pp = p[i];
349
		i=i+1;
350
		if pp != 0 then {
351
			j=0;
352
			t=0;
353
			loop 1,1000 do {
354
				t = t+pp[j];
355
				j=j+1;
356
			}
357
			print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");
358
		}
359
	}
360
}
361
 
362
print("/sys/lib/acid/kernel");
363
 
364
defn needacid(s){
365
	print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
366
	print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
367
}
368
 
369
defn kinit() {
370
if (map()[2]) != {} then {	// map has more than two elements -> active proc
371
	kdir = "unknown";
372
	KZERO = kzero();
373
 
374
	if objtype == "386" then {
375
		map({"*data", KZERO, 0xffffffff, KZERO});
376
		kdir="pc";
377
	}
378
	if (objtype == "mips" || objtype == "mips2") then {
379
		kdir = "ch";
380
	}
381
	if objtype == "alpha" then {
382
		map({"*data", KZERO, 0xffffffff, KZERO});
383
		kdir = "alpha";
384
	}
385
	needacid("proc");
386
}
387
}