rsc | 0a61c07 | 2004-04-19 18:18:37 +0000 | [diff] [blame] | 1 | // |
| 2 | // usage: acid -l pool -l leak |
| 3 | // |
| 4 | include("/sys/src/libc/port/pool.acid"); |
| 5 | |
| 6 | defn |
| 7 | dumppool(p) |
| 8 | { |
| 9 | complex Pool p; |
| 10 | a = p.arenalist; |
| 11 | |
| 12 | while a != 0 && a < 0x60000000 do { |
| 13 | complex Arena a; |
| 14 | dumparena(a); |
| 15 | a = a.down; |
| 16 | } |
| 17 | } |
| 18 | |
| 19 | defn |
| 20 | dumparena(arena) |
| 21 | { |
| 22 | local atail, b, nb; |
| 23 | |
| 24 | atail = A2TB(arena); |
| 25 | complex Bhdr arena; |
| 26 | b = a; |
| 27 | while b < atail && b.magic != ARENATAIL_MAGIC do { |
| 28 | dumpblock(b); |
| 29 | nb = B2NB(b); |
| 30 | if nb == b then { |
| 31 | print("B2NB(", b\X, ") = b\n"); |
| 32 | b = atail; // end loop |
| 33 | } |
| 34 | if nb > atail then { |
| 35 | b = (Bhdr)(b+4); |
| 36 | print("lost at block ", (b-4)\X, ", scanning forward\n"); |
| 37 | while b < atail && b.magic != KEMPT_MAGIC && b.magic != FREE_MAGIC do |
| 38 | b = (Bhdr)(b+4); |
| 39 | print("stopped at ", b\X, " ", *b\X, "\n"); |
| 40 | }else |
| 41 | b = nb; |
| 42 | } |
| 43 | if b != atail then |
| 44 | print("found wrong tail to arena ", arena\X, " wanted ", atail\X, "\n"); |
| 45 | } |
| 46 | |
| 47 | defn |
| 48 | isptr(a) |
| 49 | { |
| 50 | if end <= a && a < xbloc then |
| 51 | return 1; |
| 52 | if 0x7efff000 <= a && a < 0x7ffff000 then |
| 53 | return 1; |
| 54 | return 0; |
| 55 | } |
| 56 | |
| 57 | defn |
| 58 | dumpblock(addr) |
| 59 | { |
| 60 | complex Bhdr addr; |
| 61 | |
| 62 | if addr.magic == KEMPT_MAGIC || addr.magic == FREE_MAGIC then { |
| 63 | local a, x, s; |
| 64 | |
| 65 | a = addr; |
| 66 | complex Alloc a; |
| 67 | |
| 68 | x = addr+8; |
| 69 | if addr.magic == KEMPT_MAGIC then |
| 70 | s = "block"; |
| 71 | else |
| 72 | s = "free"; |
| 73 | print(s, " ", addr\X, " ", a.size\X, " "); |
| 74 | print(*(addr+8)\X, " ", *(addr+12)\X, "\n"); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | defn |
| 79 | dumprange(s, e, type) |
| 80 | { |
| 81 | local x, y; |
| 82 | |
| 83 | print("range ", type, " ", s\X, " ", e\X, "\n"); |
| 84 | x = s; |
| 85 | while x < e do { |
| 86 | y = *x; |
| 87 | if isptr(y) then print("data ", x\X, " ", y\X, " ", type, "\n"); |
| 88 | x = x + 4; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | defn |
| 93 | dumpmem() |
| 94 | { |
| 95 | local s; |
| 96 | |
| 97 | xbloc = *bloc; |
| 98 | // assume map()[1] is "data" |
| 99 | dumprange(map()[1][1], end, "bss"); // bss |
| 100 | dumprange(end, xbloc, "alloc"); // allocated |
| 101 | |
| 102 | if 0x7efff000 < *SP && *SP < 0x7ffff000 then |
| 103 | s = *SP; |
| 104 | else |
| 105 | s = 0x7fff7000; // 32 k |
| 106 | |
| 107 | dumprange(s, 0x7ffff000, "stack"); |
| 108 | } |
| 109 | |
| 110 | defn |
| 111 | dumpregs() |
| 112 | { |
| 113 | dumprange(0, sizeofUreg, "reg"); |
| 114 | } |
| 115 | |
| 116 | |
| 117 | defn |
| 118 | leakdump(l) |
| 119 | { |
| 120 | print("==LEAK BEGIN==\n"); |
| 121 | dumppool(sbrkmem); |
| 122 | dumpmem(); |
| 123 | dumpregs(); |
| 124 | while l != {} do { |
| 125 | setproc(head l); |
| 126 | dumpregs(); |
| 127 | l = tail l; |
| 128 | } |
| 129 | print("==LEAK END==\n"); |
| 130 | } |
| 131 | |
| 132 | defn |
| 133 | blockdump() |
| 134 | { |
| 135 | print("==BLOCK BEGIN==\n"); |
| 136 | dumppool(sbrkmem); |
| 137 | print("==BLOCK END==\n"); |
| 138 | } |