Blob


1 include("/sys/lib/acid/syscall");
3 // print various /proc files
4 defn fd() {
5 rc("cat /proc/"+itoa(pid)+"/fd");
6 }
8 defn segment() {
9 rc("cat /proc/"+itoa(pid)+"/segment");
10 }
12 defn ns() {
13 rc("cat /proc/"+itoa(pid)+"/ns");
14 }
16 defn qid(qid) {
17 complex Qid qid;
18 return itoa(qid.path\X)+"."+itoa(qid.vers\X);
19 }
21 defn cname(c) {
22 complex Cname c;
23 if c != 0 then {
24 return *(c.s\s);
25 } else
26 return "<null>";
27 }
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, " ", cname(h.c.name), "\n");
36 h = h.hash;
37 }
38 }
40 defn imagecache() {
41 local i;
43 i=0; loop 1,IHASHSIZE do {
44 imagecacheline(imagealloc.free[i]);
45 i = i+1;
46 }
47 }
49 // dump channels
50 defn chan(c) {
51 local d, q;
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 }
67 defn chans() {
68 local c;
70 c = (Chan)chanalloc.list;
71 while c != 0 do {
72 chan(c);
73 c=(Chan)c.link;
74 }
75 }
77 // manipulate processes
78 defn proctab(x) {
79 return procalloc.arena+sizeofProc*x;
80 }
82 defn proc(p) {
83 complex Proc p;
84 local s, i;
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 }
97 defn procenv(p) {
98 complex Proc p;
99 local e, v;
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;
113 KSTACK=4096;
115 defn procstksize(p) {
116 complex Proc p;
117 local top, sp;
119 if p.state != 0 then { // 0 is Dead
120 top = p.kstack+KSTACK;
121 sp = *p.sched;
122 print(top-sp\D, "\n");
126 defn procstk(p) {
127 complex Proc p;
128 local l;
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);
139 defn procs() {
140 local i;
142 i=0; loop 1,conf.nproc do {
143 proc(proctab(i));
144 i = i+1;
148 defn stacks() {
149 local i, p;
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);
158 i = i+1;
162 defn stacksizes() {
163 local i;
165 i=0; loop 1,conf.nproc do {
166 procstksize(proctab(i));
167 i = i+1;
171 // segment-related
172 defn procsegs(p) {
173 complex Proc p;
174 local i;
176 i=0; loop 1,NSEG do {
177 psegment(p.seg[i]);
178 i = i+1;
182 segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
183 defn psegment(s) {
184 complex Segment s;
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");
191 // find physical address for an address in a given process
192 defn procaddr(p, a) {
193 complex Proc p;
194 local i, s, r;
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);
205 i = i+1;
207 return r;
210 // find an address in a given segment
211 defn segaddr(s, a) {
212 complex Segment s;
213 local pte, pg;
215 a = a - s.base;
216 if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
217 return 0;
220 pte = s.map[a/PTEMAPMEM];
221 if pte == 0 then {
222 return 0;
225 complex Pte pte;
226 pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
227 if pg == 0 then {
228 return 0;
231 if pg & 1 then { // swapped out, return disk address
232 return pg&~1;
235 complex Page pg;
236 return (0x80000000|(pg.pa+(a%BY2PG)))\X;
239 // PC only
240 MACHADDR = 0x80004000;
241 PTEMAPMEM = (1024*1024);
242 BY2PG = 4096;
243 PTEPERTAB = (PTEMAPMEM/BY2PG);
244 defn up() {
245 local mach;
247 mach = MACHADDR;
248 complex Mach mach;
249 return mach.externup;
252 defn intrcount() {
253 local p, pp, t, i, j;
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;
267 print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");
272 print(acidfile);
274 defn needacid(s){
275 print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
276 print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
279 if (map()[2]) != {} then { // map has more than two elements -> active proc
280 kdir = "unknown";
282 if objtype == "386" then {
283 map({"*data", 0x80000000, 0xffffffff, 0x80000000});
284 kdir="pc";
286 if (objtype == "mips" || objtype == "mips2") then {
287 kdir = "ch";
289 if objtype == "alpha" then {
290 map({"*data", 0x80000000, 0xffffffff, 0x80000000});
291 kdir = "alpha";
293 needacid("proc");