kernel 6.2 KB

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