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