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