kernel 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 cname(c) {
  17. complex Cname c;
  18. if c != 0 then {
  19. return *(c.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(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. chan(c);
  61. c=(Chan)c.link;
  62. }
  63. }
  64. // manipulate processes
  65. defn proctab(x) {
  66. return procalloc.arena+sizeofProc*x;
  67. }
  68. defn proc(p) {
  69. complex Proc p;
  70. local s, i;
  71. if p.state != 0 then { // 0 is Dead
  72. s = p.psstate;
  73. if s == 0 then {
  74. s = "kproc";
  75. } else {
  76. s = *(s\s);
  77. }
  78. 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");
  79. }
  80. }
  81. defn procenv(p) {
  82. complex Proc p;
  83. local e, v;
  84. e = p.egrp;
  85. complex Egrp e;
  86. v = e.entries;
  87. while v != 0 do {
  88. complex Evalue v;
  89. print(*(v.name\s), "=");
  90. printstringn(v.value, v.len);
  91. print("\n");
  92. v = v.link;
  93. }
  94. }
  95. KSTACK=4096;
  96. defn procstksize(p) {
  97. complex Proc p;
  98. local top, sp;
  99. if p.state != 0 then { // 0 is Dead
  100. top = p.kstack+KSTACK;
  101. sp = *p.sched;
  102. print(top-sp\D, "\n");
  103. }
  104. }
  105. defn procstk(p) {
  106. complex Proc p;
  107. local l;
  108. if p.state != 0 then { // 0 is Dead
  109. l = p.sched;
  110. if objtype=="386" then
  111. _stk(gotolabel, *l, linkreg(0), 0);
  112. else
  113. _stk(*(l+4), *l, linkreg(0), 0);
  114. }
  115. }
  116. defn procs() {
  117. local i;
  118. i=0; loop 1,conf.nproc do {
  119. proc(proctab(i));
  120. i = i+1;
  121. }
  122. }
  123. defn stacks() {
  124. local i, p;
  125. i=0; loop 1,conf.nproc do {
  126. p = (Proc)proctab(i);
  127. if p.state != 0 then {
  128. print("=========================================================\n");
  129. proc(p);
  130. procstk(p);
  131. }
  132. i = i+1;
  133. }
  134. }
  135. defn stacksizes() {
  136. local i;
  137. i=0; loop 1,conf.nproc do {
  138. procstksize(proctab(i));
  139. i = i+1;
  140. }
  141. }
  142. // segment-related
  143. defn procsegs(p) {
  144. complex Proc p;
  145. local i;
  146. i=0; loop 1,NSEG do {
  147. psegment(p.seg[i]);
  148. i = i+1;
  149. }
  150. }
  151. segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
  152. defn psegment(s) {
  153. complex Segment s;
  154. if s != 0 then {
  155. print(s\X, " ", segtypes[s.type&SG_TYPE], " ", s.base\X, "-", s.top\X, " image ", s.image\X, "\n");
  156. }
  157. }
  158. // find physical address for an address in a given process
  159. defn procaddr(p, a) {
  160. complex Proc p;
  161. local i, s, r;
  162. r = 0;
  163. i=0; loop 1,NSEG do {
  164. s = p.seg[i];
  165. if s != 0 then {
  166. complex Segment s;
  167. if s.base <= a && a < s.top then {
  168. r = segaddr(s, a);
  169. }
  170. }
  171. i = i+1;
  172. }
  173. return r;
  174. }
  175. // find an address in a given segment
  176. defn segaddr(s, a) {
  177. complex Segment s;
  178. local pte, pg;
  179. a = a - s.base;
  180. if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
  181. return 0;
  182. }
  183. pte = s.map[a/PTEMAPMEM];
  184. if pte == 0 then {
  185. return 0;
  186. }
  187. complex Pte pte;
  188. pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
  189. if pg == 0 then {
  190. return 0;
  191. }
  192. if pg & 1 then { // swapped out, return disk address
  193. return pg&~1;
  194. }
  195. complex Page pg;
  196. return (0x80000000|(pg.pa+(a%BY2PG)))\X;
  197. }
  198. // PC only
  199. MACHADDR = 0x80004000;
  200. PTEMAPMEM = (1024*1024);
  201. BY2PG = 4096;
  202. PTEPERTAB = (PTEMAPMEM/BY2PG);
  203. defn up() {
  204. local mach;
  205. mach = MACHADDR;
  206. complex Mach mach;
  207. return mach.externup;
  208. }
  209. print("/sys/lib/acid/kernel");
  210. defn needacid(s){
  211. print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
  212. print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
  213. }
  214. if (map()[2]) != {} then { // map has more than two elements -> active proc
  215. kdir = "unknown";
  216. if objtype == "386" then {
  217. map({"*data", 0x80000000, 0xffffffff, 0x80000000});
  218. kdir="pc";
  219. }
  220. if (objtype == "mips" || objtype == "mips2") then {
  221. kdir = "ch";
  222. }
  223. if objtype == "alpha" then {
  224. map({"*data", 0x80000000, 0xffffffff, 0x80000000});
  225. kdir = "alpha";
  226. }
  227. needacid("proc");
  228. }