]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/acid/leak
devproc: fix mistake
[plan9front.git] / sys / lib / acid / leak
1 //
2 // usage: acid -l pool -l leak
3 //
4 include("/sys/src/libc/port/pool." + objtype + ".acid");
5
6 defn
7 dumppool(p, sum)
8 {
9         complex Pool p;
10         a = p.arenalist;
11
12         print("A: ", p.arenalist\A, "\n");
13         while a != 0 do {
14                 complex Arena a;
15                 dumparena(a, sum);
16                 a = a.down;
17         }
18 }
19
20 defn
21 dumparena(arena, sum)
22 {
23         local atail, b, nb;
24
25         atail = A2TB(arena);
26         complex Bhdr arena;
27         b = a;
28         print("B: ", b\A, " ", atail\A, "\n");
29         while b < atail && b.magic != ARENATAIL_MAGIC do {
30                 dumpblock(b, sum);
31                 nb = B2NB(b);
32                 if nb == b then {
33                         print("B2NB(", b\A, ") = b\n");
34                         b = atail;      // end loop
35                 }
36                 if nb > atail then {
37                         b = (Bhdr)(b+4);
38                         print("lost at block ", (b-4)\A, ", scanning forward\n");
39                         while b < atail && b.magic != ALLOC_MAGIC && b.magic != FREE_MAGIC do
40                                 b = (Bhdr)(b+4);
41                         print("stopped at ", b\A, " ", *b\A, "\n");
42                 }else
43                         b = nb;
44         }
45         if b != atail then
46                 print("found wrong tail to arena ", arena\A, " wanted ", atail\A, "\n");
47 }
48
49 defn
50 isptr(a)
51 {
52         if end <= a && a < xbloc then
53                 return 1;
54         if 0xdefff000 <= a && a < 0xdffff000 then
55                 return 1;
56         return 0;
57 }
58
59 lastalloc = 0;
60 lastcount = 0;
61 lastsize = 0;
62 defn
63 emitsum()
64 {
65         if lastalloc then
66                 print("summary ", lastalloc\a, " ", lastcount\D, " ", lastsize\D, "\n");
67         lastalloc = 0;
68         lastcount = 0;
69         lastsize = 0;
70 }
71
72 defn
73 sxpc(addr)
74 {
75         if objtype == "amd64" && addr & 0x80000000 then {
76                 return addr | 0xffffffff00000000;
77         }
78         return addr;
79 }
80
81 defn
82 dumpblock(addr, sum)
83 {
84         complex Bhdr addr;
85
86         if addr.magic == ALLOC_MAGIC || (!sum && addr.magic == FREE_MAGIC) then {
87                 local a, x, s, allocpc, reallocpc;
88
89                 a = addr;
90                 complex Alloc a;
91
92                 x = fmt(addr+sizeofBhdr, 'X');
93                 if addr.magic == ALLOC_MAGIC then {
94                         // for mallocalign()
95                         while *x == ALIGN_MAGIC do {
96                                 x = x + 4;
97                         }
98                 }
99                 allocpc=sxpc(x[0]);
100                 reallocpc=sxpc(x[1]);
101                 if sum then {
102                         if allocpc != lastalloc then {
103                                 emitsum();
104                                 lastalloc = allocpc;
105                         }
106                         lastcount = lastcount+1;
107                         lastsize = lastsize+a.size;
108                 }else{
109                         if addr.magic == ALLOC_MAGIC then {
110                                 s = "block";
111                         } else
112                                 s = "free";
113                         print(s, " ", addr\A, " ", a.size\X, " ");
114                         print(x[0]\X, " ", x[1]\X, " ", allocpc\a, " ", reallocpc\a, "\n");
115                 }
116         }
117 }
118
119 defn
120 dumprange(s, e, type)
121 {
122         local x, y;
123
124         print("range ", type, " ", s\X, " ", e\X, "\n");
125         x = s;
126         while x < e do {
127                 y = *(x\X);
128                 if isptr(y) then print("data ", x\X, " ", y\X, " ", type, "\n");
129                 x = x + 4;
130         }
131 }
132
133 defn
134 stacktop()
135 {
136         local e, m;
137         
138         m = map();
139         while m != {} do {
140                 e = head m;
141                 if e[0] == "*data" then
142                         return e[2];
143                 m = tail m;
144         }
145         return 0xdffff000;
146 }
147                         
148 defn
149 dumpmem()
150 {
151         local s, top;
152
153         xbloc = *bloc;
154         // assume map()[1] is "data" 
155         dumprange(map()[1][1], end, "bss");     // bss
156         dumprange(end, xbloc, "alloc"); // allocated
157
158         top = stacktop() - 8;
159         if top-0x01000000 < *SP && *SP < top then
160                 s = *SP;
161         else
162                 s = top-32*1024;
163
164         dumprange(s, top, "stack");
165 }
166
167 defn
168 dumpregs()
169 {
170         dumprange(0, sizeofUreg, "reg");
171 }
172
173
174 defn
175 leakdump(l)
176 {
177         print("==LEAK BEGIN==\n");
178         dumppool(*mainmem, 0);
179         dumpmem();
180         dumpregs();
181         while l != {} do {
182                 setproc(head l);
183                 dumpregs();
184                 l = tail l;
185         }
186         print("==LEAK END==\n");
187 }
188
189 defn
190 blockdump()
191 {
192         print("==BLOCK BEGIN==\n");
193         dumppool(*mainmem, 0);
194         print("==BLOCK END==\n");
195 }
196
197 defn
198 blocksummary()
199 {
200         print("==BLOCK BEGIN==\n");
201         dumppool(*mainmem, 1);
202         emitsum();
203         print("==BLOCK END==\n");
204 }
205
206 print("/sys/lib/acid/leak");