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