blob: 494ab9c348914bbdac3e2e03b6a3dc4c185f8404 [file] [log] [blame]
rsc0a61c072004-04-19 18:18:37 +00001include("/sys/lib/acid/syscall");
2
3// print various /proc files
4defn fd() {
5 rc("cat /proc/"+itoa(pid)+"/fd");
6}
7
8defn segment() {
9 rc("cat /proc/"+itoa(pid)+"/segment");
10}
11
12defn ns() {
13 rc("cat /proc/"+itoa(pid)+"/ns");
14}
15
16defn qid(qid) {
17 complex Qid qid;
18 return itoa(qid.path\X)+"."+itoa(qid.vers\X);
19}
20
21defn cname(c) {
22 complex Cname c;
23 if c != 0 then {
24 return *(c.s\s);
25 } else
26 return "<null>";
27}
28
29// print Image cache contents
30// requires include("/sys/src/9/xxx/segment.acid")
31IHASHSIZE = 64;
32defn 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, " ", cname(h.c.name), "\n");
36 h = h.hash;
37 }
38}
39
40defn 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
50defn chan(c) {
51 local d, q;
52
53 c = (Chan)c;
54 d=(Dev)(*(devtab+4*c.type));
55 q=c.qid;
56 print(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(" ", cname(c.name), " mchan=", c.mchan\X);
60 if c.mchan != 0 then {
61 print(" ", cname(c.mchan.name));
62 }
63 }
64 print("\n");
65}
66
67defn chans() {
68 local c;
69
70 c = (Chan)chanalloc.list;
71 while c != 0 do {
72 chan(c);
73 c=(Chan)c.link;
74 }
75}
76
77// manipulate processes
78defn proctab(x) {
79 return procalloc.arena+sizeofProc*x;
80}
81
82defn proc(p) {
83 complex Proc p;
84 local s, i;
85
86 if p.state != 0 then { // 0 is Dead
87 s = p.psstate;
88 if s == 0 then {
89 s = "kproc";
90 } else {
91 s = *(s\s);
92 }
93 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");
94 }
95}
96
97defn procenv(p) {
98 complex Proc p;
99 local e, v;
100
101 e = p.egrp;
102 complex Egrp e;
103 v = e.entries;
104 while v != 0 do {
105 complex Evalue v;
106 print(*(v.name\s), "=");
107 printstringn(v.value, v.len);
108 print("\n");
109 v = v.link;
110 }
111}
112
113KSTACK=4096;
114
115defn procstksize(p) {
116 complex Proc p;
117 local top, sp;
118
119 if p.state != 0 then { // 0 is Dead
120 top = p.kstack+KSTACK;
121 sp = *p.sched;
122 print(top-sp\D, "\n");
123 }
124}
125
126defn procstk(p) {
127 complex Proc p;
128 local l;
129
130 if p.state != 0 then { // 0 is Dead
131 l = p.sched;
132 if objtype=="386" then
133 _stk(gotolabel, *l, linkreg(0), 0);
134 else
135 _stk(*(l+4), *l, linkreg(0), 0);
136 }
137}
138
139defn procs() {
140 local i;
141
142 i=0; loop 1,conf.nproc do {
143 proc(proctab(i));
144 i = i+1;
145 }
146}
147
148defn stacks() {
149 local i, p;
150
151 i=0; loop 1,conf.nproc do {
152 p = (Proc)proctab(i);
153 if p.state != 0 then {
154 print("=========================================================\n");
155 proc(p);
156 procstk(p);
157 }
158 i = i+1;
159 }
160}
161
162defn stacksizes() {
163 local i;
164
165 i=0; loop 1,conf.nproc do {
166 procstksize(proctab(i));
167 i = i+1;
168 }
169}
170
171// segment-related
172defn procsegs(p) {
173 complex Proc p;
174 local i;
175
176 i=0; loop 1,NSEG do {
177 psegment(p.seg[i]);
178 i = i+1;
179 }
180}
181
182segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
183defn psegment(s) {
184 complex Segment s;
185
186 if s != 0 then {
187 print(s\X, " ", segtypes[s.type&SG_TYPE], " ", s.base\X, "-", s.top\X, " image ", s.image\X, "\n");
188 }
189}
190
191// find physical address for an address in a given process
192defn procaddr(p, a) {
193 complex Proc p;
194 local i, s, r;
195
196 r = 0;
197 i=0; loop 1,NSEG do {
198 s = p.seg[i];
199 if s != 0 then {
200 complex Segment s;
201 if s.base <= a && a < s.top then {
202 r = segaddr(s, a);
203 }
204 }
205 i = i+1;
206 }
207 return r;
208}
209
210// find an address in a given segment
211defn segaddr(s, a) {
212 complex Segment s;
213 local pte, pg;
214
215 a = a - s.base;
216 if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
217 return 0;
218 }
219
220 pte = s.map[a/PTEMAPMEM];
221 if pte == 0 then {
222 return 0;
223 }
224
225 complex Pte pte;
226 pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
227 if pg == 0 then {
228 return 0;
229 }
230
231 if pg & 1 then { // swapped out, return disk address
232 return pg&~1;
233 }
234
235 complex Page pg;
236 return (0x80000000|(pg.pa+(a%BY2PG)))\X;
237}
238
239// PC only
240MACHADDR = 0x80004000;
241PTEMAPMEM = (1024*1024);
242BY2PG = 4096;
243PTEPERTAB = (PTEMAPMEM/BY2PG);
244defn up() {
245 local mach;
246
247 mach = MACHADDR;
248 complex Mach mach;
249 return mach.externup;
250}
251
252defn intrcount() {
253 local p, pp, t, i, j;
254
255 p = intrtimes;
256 i=0;
257 loop 1,256 do {
258 pp = p[i];
259 i=i+1;
260 if pp != 0 then {
261 j=0;
262 t=0;
263 loop 1,1000 do {
264 t = t+pp[j];
265 j=j+1;
266 }
267 print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");
268 }
269 }
270}
271
272print(acidfile);
273
274defn needacid(s){
275 print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
276 print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
277}
278
279if (map()[2]) != {} then { // map has more than two elements -> active proc
280 kdir = "unknown";
281
282 if objtype == "386" then {
283 map({"*data", 0x80000000, 0xffffffff, 0x80000000});
284 kdir="pc";
285 }
286 if (objtype == "mips" || objtype == "mips2") then {
287 kdir = "ch";
288 }
289 if objtype == "alpha" then {
290 map({"*data", 0x80000000, 0xffffffff, 0x80000000});
291 kdir = "alpha";
292 }
293 needacid("proc");
294}
295