]>
Commit | Line | Data |
---|---|---|
39236c6e A |
1 | |
2 | """ Please make sure you read the README COMPLETELY BEFORE reading anything below. | |
fe8ab488 | 3 | It is very critical that you read coding guidelines in Section E in README file. |
39236c6e A |
4 | """ |
5 | ||
6 | from xnu import * | |
7 | from utils import * | |
8 | ||
9 | from mbufdefines import * | |
10 | import xnudefines | |
11 | ||
12 | # Macro: mbuf_stat | |
13 | @lldb_command('mbuf_stat') | |
14 | def MBufStat(cmd_args=None): | |
fe8ab488 | 15 | """ Print extended mbuf allocator statistics. |
39236c6e A |
16 | """ |
17 | hdr_format = "{0: <16s} {1: >8s} {2: >8s} {3: ^16s} {4: >8s} {5: >12s} {6: >8s} {7: >8s} {8: >8s}" | |
18 | print hdr_format.format('class', 'total', 'cached', 'uncached', 'inuse', 'failed', 'waiter', 'notified', 'purge') | |
19 | print hdr_format.format('name', 'objs', 'objs', 'objs/slabs', 'objs', 'alloc count', 'count', 'count', 'count') | |
20 | print hdr_format.format('-'*16, '-'*8, '-'*8, '-'*16, '-'*8, '-'*12, '-'*8, '-'*8, '-'*8) | |
21 | entry_format = "{0: <16s} {1: >8d} {2: >8d} {3:>7d} / {4:<6d} {5: >8d} {6: >12d} {7: >8d} {8: >8d} {9: >8d}" | |
22 | num_items = sizeof(kern.globals.mbuf_table) / sizeof(kern.globals.mbuf_table[0]) | |
23 | ncpus = int(kern.globals.ncpu) | |
24 | for i in range(num_items): | |
fe8ab488 | 25 | mbuf = kern.globals.mbuf_table[i] |
39236c6e A |
26 | mcs = Cast(mbuf.mtbl_stats, 'mb_class_stat_t *') |
27 | mc = mbuf.mtbl_cache | |
28 | total = 0 | |
29 | total += int(mc.mc_full.bl_total) * int(mc.mc_cpu[0].cc_bktsize) | |
30 | ccp_arr = mc.mc_cpu | |
31 | for i in range(ncpus): | |
32 | ccp = ccp_arr[i] | |
33 | if int(ccp.cc_objs) > 0: | |
34 | total += int(ccp.cc_objs) | |
35 | if int(ccp.cc_pobjs) > 0: | |
36 | total += int(ccp.cc_pobjs) | |
37 | print entry_format.format(mcs.mbcl_cname, mcs.mbcl_total, total, | |
38 | mcs.mbcl_infree, mcs.mbcl_slab_cnt, | |
39 | (mcs.mbcl_total - total - mcs.mbcl_infree), | |
40 | mcs.mbcl_fail_cnt, mbuf.mtbl_cache.mc_waiter_cnt, | |
41 | mcs.mbcl_notified, mcs.mbcl_purge_cnt | |
42 | ) | |
43 | # EndMacro: mbuf_stat | |
fe8ab488 | 44 | |
39236c6e A |
45 | # Macro: mbuf_walkpkt |
46 | @lldb_command('mbuf_walkpkt') | |
47 | def MbufWalkPacket(cmd_args=None): | |
48 | """ Walk the mbuf packet chain (m_nextpkt) | |
49 | """ | |
fe8ab488 A |
50 | if not cmd_args: |
51 | raise ArgumentError("Missing argument 0 in user function.") | |
52 | ||
39236c6e A |
53 | mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *') |
54 | cnt = 1 | |
55 | tot = 0 | |
56 | while (mp): | |
57 | out_string = "" | |
58 | mbuf_walk_packet_format = "{0:4d} 0x{1:x} [len {2:4d}, type {3:2d}, " | |
59 | out_string += mbuf_walk_packet_format.format(cnt, mp, mp.m_hdr.mh_len, mp.m_hdr.mh_type) | |
60 | if (kern.globals.mclaudit != 0): | |
61 | out_string += GetMbufBuf2Mca(mp) + ", " | |
62 | tot = tot + mp.m_hdr.mh_len | |
63 | out_string += "total " + str(tot) + "]" | |
64 | print out_string | |
65 | mp = mp.m_hdr.mh_nextpkt | |
66 | cnt += 1 | |
67 | # EndMacro: mbuf_walkpkt | |
68 | ||
69 | # Macro: mbuf_walk | |
70 | @lldb_command('mbuf_walk') | |
71 | def MbufWalk(cmd_args=None): | |
72 | """ Walk the mbuf chain (m_next) | |
73 | """ | |
74 | mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *') | |
75 | cnt = 1 | |
76 | tot = 0 | |
77 | while (mp): | |
78 | out_string = "" | |
79 | mbuf_walk_format = "{0:4d} 0x{1:x} [len {2:4d}, type {3:2d}, " | |
80 | out_string += mbuf_walk_format.format(cnt, mp, mp.m_hdr.mh_len, mp.m_hdr.mh_type) | |
81 | if (kern.globals.mclaudit != 0): | |
82 | out_string += GetMbufBuf2Mca(mp) + ", " | |
83 | tot = tot + mp.m_hdr.mh_len | |
84 | out_string += "total " + str(tot) + "]" | |
85 | print out_string | |
86 | mp = mp.m_hdr.mh_next | |
87 | cnt += 1 | |
88 | # EndMacro: mbuf_walk | |
89 | ||
90 | # Macro: mbuf_buf2slab | |
91 | @lldb_command('mbuf_buf2slab') | |
92 | def MbufBuf2Slab(cmd_args=None): | |
93 | """ Given an mbuf object, find its corresponding slab address | |
94 | """ | |
fe8ab488 A |
95 | if not cmd_args: |
96 | raise ArgumentError("Missing argument 0 in user function.") | |
97 | ||
39236c6e | 98 | m = kern.GetValueFromAddress(cmd_args[0], 'mbuf *') |
3e170ce0 | 99 | slab = GetMbufSlab(m) |
39236c6e A |
100 | if (kern.ptrsize == 8): |
101 | mbuf_slab_format = "0x{0:<16x}" | |
102 | print mbuf_slab_format.format(slab) | |
103 | else: | |
104 | mbuf_slab_format = "0x{0:<8x}" | |
105 | print mbuf_slab_format.format(slab) | |
106 | # EndMacro: mbuf_buf2slab | |
107 | ||
108 | # Macro: mbuf_buf2mca | |
109 | @lldb_command('mbuf_buf2mca') | |
110 | def MbufBuf2Mca(cmd_args=None): | |
111 | """ Find the mcache audit structure of the corresponding mbuf | |
112 | """ | |
113 | m = kern.GetValueFromAddress(cmd_args[0], 'mbuf *') | |
114 | print GetMbufBuf2Mca(m) | |
115 | return | |
116 | # EndMacro: mbuf_buf2mca | |
117 | ||
118 | # Macro: mbuf_slabs | |
119 | @lldb_command('mbuf_slabs') | |
120 | def MbufSlabs(cmd_args=None): | |
121 | """ Print all slabs in the group | |
122 | """ | |
fe8ab488 | 123 | |
39236c6e | 124 | out_string = "" |
fe8ab488 A |
125 | if not cmd_args: |
126 | raise ArgumentError("Invalid arguments passed.") | |
127 | ||
39236c6e A |
128 | slg = kern.GetValueFromAddress(cmd_args[0], 'mcl_slabg_t *') |
129 | x = 0 | |
130 | ||
131 | if (kern.ptrsize == 8): | |
132 | slabs_string_format = "{0:>4d}: 0x{1:16x} 0x{2:16x} 0x{3:16x} {4:4s} {5:20d} {6:3d} {7:3d} {8:3d} {9:3d} {10:>6s} " | |
133 | out_string += "slot slab next obj mca tstamp C R N size flags\n" | |
134 | out_string += "---- ------------------ ------------------ ------------------ ------------------ ---------- -- -- -- ------ -----\n" | |
135 | else: | |
136 | slabs_string_format = "{0:>4d}: 0x{1:8x} 0x{2:8x} 0x{3:8x} {4:4s} {5:20d} {6:3d} {7:3d} {8:3d} {9:3d} {10:>6s} " | |
137 | out_string += "slot slab next obj mca tstamp C R N size flags\n" | |
138 | out_string += "---- ---------- ---------- ---------- ---------- ---------- -- -- -- ------ -----\n" | |
139 | ||
3e170ce0 A |
140 | mbutl = cast(kern.globals.mbutl, 'unsigned char *') |
141 | nslabspmb = int((1 << MBSHIFT) >> unsigned(kern.globals.page_shift)) | |
142 | while x < nslabspmb: | |
39236c6e A |
143 | sl = addressof(slg.slg_slab[x]) |
144 | mca = 0 | |
145 | obj = sl.sl_base | |
146 | ts = 0 | |
147 | ||
148 | if (kern.globals.mclaudit != 0): | |
3e170ce0 A |
149 | mca = GetMbufMcaPtr(obj, sl.sl_class) |
150 | trn = (mca.mca_next_trn + unsigned(kern.globals.mca_trn_max) - 1) % unsigned(kern.globals.mca_trn_max) | |
fe8ab488 | 151 | ts = mca.mca_trns[trn].mca_tstamp |
39236c6e A |
152 | |
153 | out_string += slabs_string_format.format((x + 1), sl, sl.sl_next, obj, hex(mca), int(ts), int(sl.sl_class), int(sl.sl_refcnt), int(sl.sl_chunks), int(sl.sl_len), hex(sl.sl_flags)) | |
154 | ||
155 | if (sl.sl_flags != 0): | |
156 | out_string += "<" | |
157 | if sl.sl_flags & SLF_MAPPED: | |
158 | out_string += "mapped" | |
159 | if sl.sl_flags & SLF_PARTIAL: | |
160 | out_string += ",partial" | |
161 | if sl.sl_flags & SLF_DETACHED: | |
162 | out_string += ",detached" | |
163 | out_string += ">" | |
164 | out_string += "\n" | |
165 | ||
166 | if sl.sl_chunks > 1: | |
167 | z = 1 | |
168 | c = sl.sl_len/sl.sl_chunks | |
169 | ||
170 | while z < sl.sl_chunks: | |
171 | obj = sl.sl_base + (c * z) | |
172 | mca = 0 | |
173 | ts = 0 | |
174 | ||
175 | if (kern.globals.mclaudit != 0): | |
3e170ce0 A |
176 | mca = GetMbufMcaPtr(obj, sl.sl_class) |
177 | trn = (mca.mca_next_trn + unsigned(kern.globals.mca_trn_max) - 1) % unsigned(kern.globals.mca_trn_max) | |
fe8ab488 | 178 | ts = mca.mca_trns[trn].mca_tstamp |
39236c6e A |
179 | |
180 | if (kern.ptrsize == 8): | |
181 | out_string += " " + hex(obj) + " " + hex(mca) + " " + str(unsigned(ts)) + "\n" | |
182 | else: | |
183 | out_string += " " + hex(obj) + " " + hex(mca) + " " + str(unsigned(ts)) + "\n" | |
184 | ||
185 | z += 1 | |
186 | x += 1 | |
187 | print out_string | |
188 | # EndMacro: mbuf_slabs | |
189 | ||
190 | # Macro: mbuf_slabstbl | |
191 | @lldb_command('mbuf_slabstbl') | |
192 | def MbufSlabsTbl(cmd_args=None): | |
193 | """ Print slabs table | |
194 | """ | |
195 | out_string = "" | |
196 | x = 0 | |
197 | ||
198 | if (kern.ptrsize == 8): | |
199 | out_string += "slot slabg slabs range\n" | |
200 | out_string += "---- ------------------ -------------------------------------------\n" | |
201 | else: | |
202 | out_string += "slot slabg slabs range\n" | |
203 | out_string += "---- ---------- ---------------------------\n" | |
204 | ||
205 | slabstbl = kern.globals.slabstbl | |
206 | slabs_table_blank_string_format = "{0:>3d}: - \n" | |
3e170ce0 | 207 | nslabspmb = int(((1 << MBSHIFT) >> unsigned(kern.globals.page_shift))) |
39236c6e A |
208 | while (x < unsigned(kern.globals.maxslabgrp)): |
209 | slg = slabstbl[x] | |
210 | if (slg == 0): | |
211 | out_string += slabs_table_blank_string_format.format(x+1) | |
212 | else: | |
213 | if (kern.ptrsize == 8): | |
214 | slabs_table_string_format = "{0:>3d}: 0x{1:16x} [ 0x{2:16x} - 0x{3:16x} ]\n" | |
3e170ce0 | 215 | out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1])) |
39236c6e A |
216 | else: |
217 | slabs_table_string_format = "{0:>3d}: 0x{1:8x} [ 0x{2:8x} - 0x{3:8x} ]\n" | |
3e170ce0 | 218 | out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1])) |
39236c6e A |
219 | |
220 | x += 1 | |
221 | print out_string | |
222 | # EndMacro: mbuf_slabstbl | |
223 | ||
3e170ce0 A |
224 | def GetMbufMcaPtr(m, cl): |
225 | pgshift = int(kern.globals.page_shift) | |
226 | ix = int((m - Cast(kern.globals.mbutl, 'char *')) >> pgshift) | |
227 | page_addr = (Cast(kern.globals.mbutl, 'char *') + (ix << pgshift)) | |
228 | ||
229 | if (int(cl) == 0): | |
230 | midx = int((m - page_addr) >> 8) | |
231 | mca = kern.globals.mclaudit[ix].cl_audit[midx] | |
232 | elif (int(cl) == 1): | |
233 | midx = int((m - page_addr) >> 11) | |
234 | mca = kern.globals.mclaudit[ix].cl_audit[midx] | |
235 | elif (int(cl) == 2): | |
236 | midx = int((m - page_addr) >> 12) | |
237 | mca = kern.globals.mclaudit[ix].cl_audit[midx] | |
238 | else: | |
239 | mca = kern.globals.mclaudit[ix].cl_audit[0] | |
240 | return Cast(mca, 'mcache_audit_t *') | |
241 | ||
242 | def GetMbufSlab(m): | |
243 | pgshift = int(kern.globals.page_shift) | |
244 | gix = int((Cast(m, 'char *') - Cast(kern.globals.mbutl, 'char *')) >> MBSHIFT) | |
245 | slabstbl = kern.globals.slabstbl | |
246 | ix = int((Cast(m, 'char *') - Cast(slabstbl[gix].slg_slab[0].sl_base, 'char *')) >> pgshift) | |
247 | return addressof(slabstbl[gix].slg_slab[ix]) | |
39236c6e A |
248 | |
249 | def GetMbufBuf2Mca(m): | |
3e170ce0 A |
250 | sl = GetMbufSlab(m) |
251 | mca = GetMbufMcaPtr(m, sl.sl_class) | |
39236c6e A |
252 | return str(mca) |
253 | ||
254 | def GetMbufWalkAllSlabs(show_a, show_f, show_tr): | |
255 | out_string = "" | |
256 | ||
257 | kern.globals.slabstbl[0] | |
fe8ab488 | 258 | |
39236c6e A |
259 | x = 0 |
260 | total = 0 | |
261 | total_a = 0 | |
262 | total_f = 0 | |
263 | ||
264 | if (show_a and not(show_f)): | |
265 | out_string += "Searching only for active... \n" | |
266 | if (not(show_a) and show_f): | |
267 | out_string += "Searching only for inactive... \n" | |
268 | if (show_a and show_f): | |
269 | out_string += "Displaying all... \n" | |
270 | ||
271 | if (kern.ptrsize == 8): | |
272 | show_mca_string_format = "{0:>4s} {1:>4s} {2:>16s} {3:>16s} {4:>16} {5:>12s} {6:12s}" | |
273 | out_string += show_mca_string_format.format("slot", "idx", "slab address", "mca address", "obj address", "type", "allocation state\n") | |
274 | else: | |
275 | show_mca_string_format = "{0:4s} {1:4s} {2:8s} {3:8s} {4:8} {5:12s} {6:12s}" | |
276 | out_string += show_mca_string_format.format("slot", "idx", "slab address", "mca address", "obj address", "type", "allocation state\n") | |
277 | ||
3e170ce0 | 278 | nslabspmb = unsigned((1 << MBSHIFT) >> unsigned(kern.globals.page_shift)) |
39236c6e A |
279 | while (x < unsigned(kern.globals.slabgrp)): |
280 | slg = kern.globals.slabstbl[x] | |
281 | y = 0 | |
282 | stop = 0 | |
3e170ce0 | 283 | while ((y < nslabspmb) and (stop == 0)): |
39236c6e A |
284 | sl = addressof(slg.slg_slab[y]) |
285 | base = sl.sl_base | |
3e170ce0 | 286 | mca = GetMbufMcaPtr(base, sl.sl_class) |
39236c6e A |
287 | first = 1 |
288 | ||
289 | while ((Cast(mca, 'int') != 0) and (unsigned(mca.mca_addr) != 0)): | |
290 | printmca = 0 | |
fe8ab488 | 291 | if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)): |
39236c6e A |
292 | total_a = total_a + 1 |
293 | printmca = show_a | |
294 | else: | |
295 | total_f = total_f + 1 | |
296 | printmca = show_f | |
297 | ||
298 | if (printmca != 0): | |
299 | if (first == 1): | |
300 | if (kern.ptrsize == 8): | |
301 | mca_string_format = "{0:4d} {1:4d} 0x{2:16x} " | |
302 | out_string += mca_string_format.format(x, y, sl) | |
303 | else: | |
304 | mca_string_format = "{0:4d} {1:4d} 0x{02:8x} " | |
305 | out_string += mca_string_format.format(x, y, sl) | |
306 | else: | |
307 | if (kern.ptrsize == 8): | |
308 | out_string += " " | |
309 | else: | |
310 | out_string += " " | |
311 | ||
312 | if (kern.ptrsize == 8): | |
313 | mca_string_format = "0x{0:16x} 0x{1:16x}" | |
314 | out_string += mca_string_format.format(mca, mca.mca_addr) | |
315 | else: | |
316 | mca_string_format = "0x{0:8x} 0x{1:8x}" | |
317 | out_string += mca_string_format.format(mca, mca.mca_addr) | |
318 | ||
319 | out_string += GetMbufMcaCtype(mca, 0) | |
320 | ||
fe8ab488 | 321 | if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)): |
39236c6e A |
322 | out_string += "active " |
323 | else: | |
324 | out_string += " freed " | |
325 | if (first == 1): | |
326 | first = 0 | |
327 | out_string += "\n" | |
328 | total = total + 1 | |
329 | ||
330 | if (show_tr != 0): | |
fe8ab488 A |
331 | trn = (mca.mca_next_trn + idx - 1) % unsigned(kern.globals.mca_trn_max) |
332 | out_string += "Transaction " + str(int(trn)) + " at " + str(int(mca.mca_trns[int(trn)].mca_tstamp)) + " by thread: 0x" + str(hex(mca.mca_trns[int(trn)].mca_thread)) + ":\n" | |
39236c6e | 333 | cnt = 0 |
fe8ab488 A |
334 | while (cnt < mca.mca_trns[int(trn)].mca_depth): |
335 | kgm_pc = mca.mca_trns[int(trn)].mca_stack[int(cnt)] | |
39236c6e | 336 | out_string += str(int(cnt) + 1) + " " |
fe8ab488 | 337 | out_string += GetPc(kgm_pc) |
39236c6e A |
338 | cnt += 1 |
339 | ||
fe8ab488 A |
340 | print out_string |
341 | out_string = "" | |
39236c6e A |
342 | mca = mca.mca_next |
343 | ||
344 | y += 1 | |
345 | if (slg.slg_slab[int(y)].sl_base == 0): | |
346 | stop = 1 | |
347 | x += 1 | |
348 | ||
349 | if (total and show_a and show_f): | |
350 | out_string += "total objects = " + str(int(total)) + "\n" | |
351 | out_string += "active/unfreed objects = " + str(int(total_a)) + "\n" | |
352 | out_string += "freed/in_cache objects = " + str(int(total_f)) + "\n" | |
353 | ||
354 | return out_string | |
355 | ||
356 | def GetMbufMcaCtype(mca, vopt): | |
357 | cp = mca.mca_cache | |
358 | mca_class = unsigned(cp.mc_private) | |
fe8ab488 | 359 | csize = unsigned(kern.globals.mbuf_table[mca_class].mtbl_stats.mbcl_size) |
39236c6e A |
360 | done = 0 |
361 | out_string = " " | |
362 | if (csize == MSIZE): | |
363 | if (vopt): | |
364 | out_string += "M (mbuf) " | |
365 | else: | |
366 | out_string += "M " | |
367 | return out_string | |
368 | if (csize == MCLBYTES): | |
369 | if (vopt): | |
370 | out_string += "CL (2K cluster) " | |
371 | else: | |
372 | out_string += "CL " | |
373 | return out_string | |
3e170ce0 | 374 | if (csize == MBIGCLBYTES): |
39236c6e A |
375 | if (vopt): |
376 | out_string += "BCL (4K cluster) " | |
377 | else: | |
378 | out_string += "BCL " | |
379 | return out_string | |
380 | if (csize == M16KCLBYTES): | |
381 | if (vopt): | |
382 | out_string += "JCL (16K cluster) " | |
383 | else: | |
384 | out_string += "JCL " | |
385 | return out_string | |
386 | ||
387 | if (csize == (MSIZE + MCLBYTES)): | |
388 | if (mca.mca_uflags & MB_SCVALID): | |
389 | if (mca.mca_uptr): | |
390 | out_string += "M+CL " | |
391 | if vopt: | |
392 | out_string += "(paired mbuf, 2K cluster) " | |
393 | else: | |
394 | out_string += "M-CL " | |
395 | if vopt: | |
396 | out_string += "(unpaired mbuf, 2K cluster) " | |
397 | else: | |
398 | if (mca.mca_uptr): | |
399 | out_string += "CL+M " | |
400 | if vopt: | |
401 | out_string += "(paired 2K cluster, mbuf) " | |
402 | else: | |
403 | out_string += "CL-M " | |
404 | if vopt: | |
405 | out_string += "(unpaired 2K cluster, mbuf) " | |
406 | return out_string | |
407 | ||
3e170ce0 | 408 | if (csize == (MSIZE + MBIGCLBYTES)): |
39236c6e A |
409 | if (mca.mca_uflags & MB_SCVALID): |
410 | if (mca.mca_uptr): | |
411 | out_string += "M+BCL " | |
412 | if vopt: | |
413 | out_string += "(paired mbuf, 4K cluster) " | |
414 | else: | |
415 | out_string += "M-BCL " | |
fe8ab488 | 416 | if vopt: |
39236c6e A |
417 | out_string += "(unpaired mbuf, 4K cluster) " |
418 | else: | |
419 | if (mca.mca_uptr): | |
420 | out_string += "BCL+M " | |
421 | if vopt: | |
422 | out_string += "(paired 4K cluster, mbuf) " | |
423 | else: | |
424 | out_string += "BCL-m " | |
425 | if vopt: | |
426 | out_string += "(unpaired 4K cluster, mbuf) " | |
427 | return out_string | |
428 | ||
429 | if (csize == (MSIZE + M16KCLBYTES)): | |
430 | if (mca.mca_uflags & MB_SCVALID): | |
431 | if (mca.mca_uptr): | |
432 | out_string += "M+BCL " | |
433 | if vopt: | |
434 | out_string += "(paired mbuf, 4K cluster) " | |
435 | else: | |
436 | out_string += "M-BCL " | |
437 | if vopt: | |
438 | out_string += "(unpaired mbuf, 4K cluster) " | |
439 | else: | |
440 | if (mca.mca_uptr): | |
441 | out_string += "BCL+M " | |
442 | if vopt: | |
443 | out_string += "(paired 4K cluster, mbuf) " | |
444 | else: | |
445 | out_string += "BCL-m " | |
446 | if vopt: | |
447 | out_string += "(unpaired 4K cluster, mbuf) " | |
448 | return out_string | |
449 | ||
450 | out_string += "unknown: " + cp.mc_name | |
451 | return out_string | |
fe8ab488 | 452 | |
39236c6e A |
453 | kgm_pkmod = 0 |
454 | kgm_pkmodst = 0 | |
455 | kgm_pkmoden = 0 | |
456 | ||
457 | def GetPointerAsString(kgm_pc): | |
458 | if (kern.ptrsize == 8): | |
459 | pointer_format_string = "0x{0:<16x} " | |
460 | else: | |
461 | pointer_format_string = "0x{0:<8x} " | |
462 | return pointer_format_string.format(kgm_pc) | |
463 | ||
464 | def GetKmodAddrIntAsString(kgm_pc): | |
465 | global kgm_pkmod | |
466 | global kgm_pkmodst | |
467 | global kgm_pkmoden | |
468 | ||
469 | out_string = "" | |
470 | mh_execute_addr = int(lldb_run_command('p/x (uintptr_t *)&_mh_execute_header').split('=')[-1].strip(), 16) | |
471 | ||
472 | out_string += GetPointerAsString(kgm_pc) | |
473 | if ((unsigned(kgm_pc) >= unsigned(kgm_pkmodst)) and (unsigned(kgm_pc) < unsigned(kgm_pkmoden))): | |
474 | kgm_off = kgm_pc - kgm_pkmodst | |
475 | out_string += "<" + str(Cast(kgm_pkmod, 'kmod_info_t *').name) + " + 0x" + str(kgm_off) + ">" | |
476 | else: | |
477 | kgm_kmodp = kern.globals.kmod | |
478 | if ((kern.arch == 'x86_64') and (long(kgm_pc) >= long(mh_execute_addr))): | |
479 | kgm_kmodp = 0 | |
480 | ||
481 | while kgm_kmodp: | |
482 | kgm_off = unsigned((kgm_pc - kgm_kmodp.address) & 0x00000000ffffffff) | |
483 | if ((long(kgm_kmodp.address) <= long(kgm_pc)) and (kgm_off) < unsigned(kgm_kmodp.size)): | |
484 | kgm_pkmod = kgm_kmodp | |
485 | kgm_pkmodst = unsigned(kgm_kmodp.address) | |
486 | kgm_pkmoden = unsigned(kgm_pkmodst + kgm_kmodp.size) | |
487 | kgm_kmodp = 0 | |
488 | else: | |
489 | kgm_kmodp = kgm_kmodp.next | |
490 | return out_string | |
491 | ||
492 | def GetPc(kgm_pc): | |
493 | out_string = "" | |
494 | mh_execute_addr = int(lldb_run_command('p/x (uintptr_t *)&_mh_execute_header').split('=')[-1].strip(), 16) | |
fe8ab488 | 495 | if (unsigned(kgm_pc) < unsigned(mh_execute_addr) or unsigned(kgm_pc) >= unsigned(kern.globals.vm_kernel_top)): |
39236c6e A |
496 | out_string += GetKmodAddrIntAsString(kgm_pc) |
497 | else: | |
498 | out_string += GetSourceInformationForAddress(int(kgm_pc)) | |
499 | return out_string + "\n" | |
500 | ||
501 | ||
502 | # Macro: mbuf_showactive | |
503 | @lldb_command('mbuf_showactive') | |
504 | def MbufShowActive(cmd_args=None): | |
505 | """ Print all active/in-use mbuf objects | |
506 | """ | |
fe8ab488 | 507 | if cmd_args: |
39236c6e A |
508 | print GetMbufWalkAllSlabs(1, 0, cmd_args[0]) |
509 | else: | |
510 | print GetMbufWalkAllSlabs(1, 0, 0) | |
511 | # EndMacro: mbuf_showactive | |
512 | ||
513 | ||
514 | # Macro: mbuf_showinactive | |
515 | @lldb_command('mbuf_showinactive') | |
516 | def MbufShowInactive(cmd_args=None): | |
517 | """ Print all freed/in-cache mbuf objects | |
518 | """ | |
519 | print GetMbufWalkAllSlabs(0, 1, 0) | |
520 | # EndMacro: mbuf_showinactive | |
521 | ||
522 | ||
523 | # Macro: mbuf_showmca | |
524 | @lldb_command('mbuf_showmca') | |
525 | def MbufShowMca(cmd_args=None): | |
526 | """ Print the contents of an mbuf mcache audit structure | |
527 | """ | |
528 | out_string = "" | |
3e170ce0 | 529 | pgshift = unsigned(kern.globals.page_shift) |
fe8ab488 | 530 | if cmd_args: |
39236c6e A |
531 | mca = kern.GetValueFromAddress(cmd_args[0], 'mcache_audit_t *') |
532 | cp = mca.mca_cache | |
533 | out_string += "object type:\t" | |
534 | out_string += GetMbufMcaCtype(mca, 1) | |
535 | out_string += "\nControlling mcache :\t" + hex(mca.mca_cache) + " (" + str(cp.mc_name) + ")\n" | |
536 | if (mca.mca_uflags & MB_SCVALID): | |
3e170ce0 A |
537 | mbutl = Cast(kern.globals.mbutl, 'unsigned char *') |
538 | ix = (mca.mca_addr - mbutl) >> pgshift | |
539 | clbase = mbutl + (ix << pgshift) | |
39236c6e A |
540 | mclidx = (mca.mca_addr - clbase) >> 8 |
541 | out_string += "mbuf obj :\t\t" + hex(mca.mca_addr) + "\n" | |
542 | out_string += "mbuf index :\t\t" + str(mclidx + 1) + " (out of 16) in cluster base " + hex(clbase) + "\n" | |
543 | if (int(mca.mca_uptr) != 0): | |
544 | peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *') | |
545 | out_string += "paired cluster obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n" | |
546 | out_string += "saved contents :\t" + hex(mca.mca_contents) + " (" + str(int(mca.mca_contents_size)) + " bytes)\n" | |
547 | else: | |
548 | out_string += "cluster obj :\t\t" + hex(mca.mca_addr) + "\n" | |
549 | if (mca.mca_uptr != 0): | |
550 | peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *') | |
551 | out_string += "paired mbuf obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n" | |
39236c6e | 552 | |
3e170ce0 | 553 | for idx in range(unsigned(kern.globals.mca_trn_max), 0, -1): |
fe8ab488 A |
554 | trn = (mca.mca_next_trn + idx - 1) % unsigned(kern.globals.mca_trn_max) |
555 | out_string += "transaction {:d} (tstamp {:d}, thread 0x{:x}):\n".format(trn, mca.mca_trns[trn].mca_tstamp, mca.mca_trns[trn].mca_thread) | |
556 | cnt = 0 | |
557 | while (cnt < mca.mca_trns[trn].mca_depth): | |
558 | kgm_pc = mca.mca_trns[trn].mca_stack[cnt] | |
559 | out_string += " " + str(cnt + 1) + ". " | |
560 | out_string += GetPc(kgm_pc) | |
561 | cnt += 1 | |
562 | ||
563 | msc = cast(mca.mca_contents, 'mcl_saved_contents_t *') | |
564 | msa = addressof(msc.sc_scratch) | |
39236c6e | 565 | if (mca.mca_uflags & MB_SCVALID): |
39236c6e | 566 | if (msa.msa_depth > 0): |
fe8ab488 | 567 | out_string += "Recent scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_tstamp, msa.msa_thread) |
39236c6e A |
568 | cnt = 0 |
569 | while (cnt < msa.msa_depth): | |
570 | kgm_pc = msa.msa_stack[cnt] | |
571 | out_string += " " + str(cnt + 1) + ". " | |
572 | out_string += GetPc(kgm_pc) | |
573 | cnt += 1 | |
574 | ||
575 | if (msa.msa_pdepth > 0): | |
fe8ab488 A |
576 | out_string += "previous scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_ptstamp, msa.msa_pthread) |
577 | if (msa): | |
578 | cnt = 0 | |
579 | while (cnt < msa.msa_pdepth): | |
580 | kgm_pc = msa.msa_pstack[cnt] | |
581 | out_string += " " + str(cnt + 1) + ". " | |
582 | out_string += GetPc(kgm_pc) | |
583 | cnt += 1 | |
584 | else: | |
39236c6e A |
585 | out_string += "Missing argument 0 in user function." |
586 | ||
587 | print out_string | |
588 | # EndMacro: mbuf_showmca | |
589 | ||
590 | ||
591 | # Macro: mbuf_showall | |
592 | @lldb_command('mbuf_showall') | |
593 | def MbufShowAll(cmd_args=None): | |
594 | """ Print all mbuf objects | |
595 | """ | |
fe8ab488 | 596 | print GetMbufWalkAllSlabs(1, 1, 0) |
39236c6e A |
597 | # EndMacro: mbuf_showall |
598 | ||
599 | # Macro: mbuf_countchain | |
600 | @lldb_command('mbuf_countchain') | |
601 | def MbufCountChain(cmd_args=None): | |
602 | """ Count the length of an mbuf chain | |
603 | """ | |
fe8ab488 A |
604 | if not cmd_args: |
605 | raise ArgumentError("Missing argument 0 in user function.") | |
606 | ||
39236c6e A |
607 | mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *') |
608 | ||
609 | pkt = 0 | |
610 | nxt = 0 | |
fe8ab488 | 611 | |
39236c6e A |
612 | while (mp): |
613 | pkt = pkt + 1 | |
614 | mn = mp.m_hdr.mh_next | |
615 | while (mn): | |
616 | nxt = nxt + 1 | |
617 | mn = mn.m_hdr.mh_next | |
618 | ||
619 | mp = mp.m_hdr.mh_nextpkt | |
620 | ||
621 | if (((pkt + nxt) % 50) == 0): | |
622 | print " ..." + str(pkt_nxt) | |
623 | ||
624 | print "Total: " + str(pkt + nxt) + " (via m_next: " + str(nxt) + ")" | |
625 | # EndMacro: mbuf_countchain | |
626 | ||
627 | ||
628 | ||
629 | # Macro: mbuf_topleak | |
630 | @lldb_command('mbuf_topleak') | |
631 | def MbufTopLeak(cmd_args=None): | |
632 | """ Print the top suspected mbuf leakers | |
633 | """ | |
634 | topcnt = 0 | |
635 | if (int(len(cmd_args)) > 0 and int(cmd_args[0]) < 5): | |
636 | maxcnt = cmd_args[0] | |
637 | else: | |
638 | maxcnt = 5 | |
639 | while (topcnt < maxcnt): | |
640 | print GetMbufTraceLeak(kern.globals.mleak_top_trace[topcnt]) | |
641 | topcnt += 1 | |
642 | ||
643 | # EndMacro: mbuf_topleak | |
644 | ||
645 | def GetMbufTraceLeak(trace): | |
646 | out_string = "" | |
647 | if (trace.allocs != 0): | |
648 | out_string += hex(trace) + ":" + str(trace.allocs) + " outstanding allocs\n" | |
649 | out_string += "Backtrace saved " + str(trace.depth) + " deep\n" | |
650 | if (trace.depth != 0): | |
651 | cnt = 0 | |
652 | while (cnt < trace.depth): | |
653 | out_string += str(cnt + 1) + ": " | |
654 | out_string += GetPc(trace.addr[cnt]) | |
655 | out_string += "\n" | |
656 | cnt += 1 | |
657 | return out_string | |
658 | ||
659 | ||
660 | # Macro: mbuf_traceleak | |
661 | @lldb_command('mbuf_traceleak') | |
662 | def MbufTraceLeak(cmd_args=None): | |
663 | """ Print the leak information for a given leak address | |
664 | Given an mbuf leak trace (mtrace) structure address, print out the | |
665 | stored information with that trace | |
666 | syntax: (lldb) mbuf_traceleak <addr> | |
667 | """ | |
fe8ab488 A |
668 | if not cmd_args: |
669 | raise ArgumentError("Missing argument 0 in user function.") | |
670 | ||
39236c6e A |
671 | trace = kern.GetValueFromAddress(cmd_args[0], 'mtrace *') |
672 | print GetMbufTraceLeak(trace) | |
673 | # EndMacro: mbuf_traceleak | |
674 | ||
675 | ||
676 | # Macro: mcache_walkobj | |
677 | @lldb_command('mcache_walkobj') | |
678 | def McacheWalkObject(cmd_args=None): | |
679 | """ Given a mcache object address, walk its obj_next pointer | |
680 | """ | |
fe8ab488 A |
681 | if not cmd_args: |
682 | raise ArgumentError("Missing argument 0 in user function.") | |
683 | ||
39236c6e A |
684 | out_string = "" |
685 | p = kern.GetValueFromAddress(cmd_args[0], 'mcache_obj_t *') | |
686 | cnt = 1 | |
687 | total = 0 | |
688 | while (p): | |
689 | mcache_object_format = "{0:>4d}: 0x{1:>16x}" | |
690 | out_string += mcache_object_format.format(cnt, p) + "\n" | |
691 | p = p.obj_next | |
692 | cnt += 1 | |
693 | print out_string | |
694 | # EndMacro: mcache_walkobj | |
695 | ||
696 | # Macro: mcache_stat | |
697 | @lldb_command('mcache_stat') | |
698 | def McacheStat(cmd_args=None): | |
699 | """ Print all mcaches in the system. | |
700 | """ | |
701 | head = kern.globals.mcache_head | |
702 | out_string = "" | |
703 | mc = cast(head.lh_first, 'mcache *') | |
704 | if (kern.ptrsize == 8): | |
705 | mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>20s} {3:>5s} {4:>5s} {5:>20s} {6:>30s} {7:>18s}" | |
706 | else: | |
707 | mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>12s} {3:>5s} {4:>5s} {5:>12s} {6:>30s} {7:>18s}" | |
fe8ab488 | 708 | |
39236c6e A |
709 | if (kern.ptrsize == 8): |
710 | mcache_stat_data_format_string = "{0:<24s} {1:>12s} {2:>20s} {3:>5s} {4:>5s} {5:>22s} {6:>12d} {7:>8d} {8:>8d} {9:>18d}" | |
711 | else: | |
712 | mcache_stat_data_format_string = "{0:<24s} {1:>12s} {2:>12s} {3:>5s} {4:>5s} {5:>14s} {6:>12d} {7:>8d} {8:>8d} {9:>18d}" | |
fe8ab488 A |
713 | |
714 | out_string += mcache_stat_format_string.format("cache name", "cache state", "cache addr", "buf size", "buf align", "backing zone", "wait nowait failed", "bufs incache") | |
39236c6e | 715 | out_string += "\n" |
fe8ab488 | 716 | |
39236c6e A |
717 | ncpu = int(kern.globals.ncpu) |
718 | while mc != 0: | |
719 | bktsize = mc.mc_cpu[0].cc_bktsize | |
720 | cache_state = "" | |
721 | if (mc.mc_flags & MCF_NOCPUCACHE): | |
722 | cache_state = "disabled" | |
723 | else: | |
724 | if (bktsize == 0): | |
725 | cache_state = " offline" | |
726 | else: | |
727 | cache_state = " online" | |
728 | if (mc.mc_slab_zone != 0): | |
729 | backing_zone = mc.mc_slab_zone | |
730 | else: | |
731 | if (kern.ptrsize == 8): | |
732 | backing_zone = " custom" | |
733 | else: | |
734 | backing_zone = " custom" | |
fe8ab488 | 735 | |
39236c6e A |
736 | total = 0 |
737 | total += mc.mc_full.bl_total * bktsize | |
738 | n = 0 | |
739 | while(n < ncpu): | |
740 | ccp = mc.mc_cpu[n] | |
741 | if (ccp.cc_objs > 0): | |
742 | total += ccp.cc_objs | |
743 | if (ccp.cc_pobjs > 0): | |
744 | total += ccp.cc_pobjs | |
745 | n += 1 | |
746 | ccp += 1 | |
747 | ||
748 | out_string += mcache_stat_data_format_string.format(mc.mc_name, cache_state, hex(mc), str(int(mc.mc_bufsize)), str(int(mc.mc_align)), hex(mc.mc_slab_zone), int(mc.mc_wretry_cnt), int(mc.mc_nwretry_cnt), int(mc.mc_nwfail_cnt), total) | |
749 | out_string += "\n" | |
750 | mc = cast(mc.mc_list.le_next, 'mcache *') | |
751 | print out_string | |
752 | # EndMacro: mcache_stat | |
753 | ||
754 | # Macro: mcache_showcache | |
755 | @lldb_command('mcache_showcache') | |
756 | def McacheShowCache(cmd_args=None): | |
757 | """Display the number of objects in cache. | |
758 | """ | |
759 | out_string = "" | |
760 | cp = kern.GetValueFromAddress(cmd_args[0], 'mcache_t *') | |
761 | bktsize = cp.mc_cpu[0].cc_bktsize | |
762 | cnt = 0 | |
763 | total = 0 | |
764 | mcache_cache_format = "{0:<4d} {1:>8d} {2:>8d} {3:>8d}" | |
765 | out_string += "Showing cache " + str(cp.mc_name) + " :\n\n" | |
766 | out_string += " CPU cc_objs cc_pobjs total\n" | |
767 | out_string += "---- ------- -------- --------\n" | |
768 | ncpu = int(kern.globals.ncpu) | |
769 | while (cnt < ncpu): | |
770 | ccp = cp.mc_cpu[cnt] | |
771 | objs = ccp.cc_objs | |
772 | if (objs <= 0): | |
773 | objs = 0 | |
774 | pobjs = ccp.cc_pobjs | |
775 | if (pobjs <= 0): | |
776 | pobjs = 0 | |
777 | tot_cpu = objs + pobjs | |
778 | total += tot_cpu | |
779 | out_string += mcache_cache_format.format(cnt, objs, pobjs, tot_cpu) | |
780 | out_string += "\n" | |
781 | cnt += 1 | |
782 | ||
783 | out_string += " ========\n" | |
784 | out_string += " " + str(total) + "\n\n" | |
785 | total += cp.mc_full.bl_total * bktsize | |
786 | ||
fe8ab488 | 787 | out_string += "Total # of full buckets (" + str(int(bktsize)) + " objs/bkt):\t" + str(int(cp.mc_full.bl_total)) + "\n" |
39236c6e A |
788 | out_string += "Total # of objects cached:\t\t" + str(total) + "\n" |
789 | print out_string | |
790 | # EndMacro: mcache_showcache |