]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/mbufs.py
xnu-6153.11.26.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 not cmd_args:
51 raise ArgumentError("Missing argument 0 in user function.")
52
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 not cmd_args:
96 raise ArgumentError("Missing argument 0 in user function.")
97
98 m = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
99 slab = GetMbufSlab(m)
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 """
123
124 out_string = ""
125 if not cmd_args:
126 raise ArgumentError("Invalid arguments passed.")
127
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
140 mbutl = cast(kern.globals.mbutl, 'unsigned char *')
141 nslabspmb = int((1 << MBSHIFT) >> unsigned(kern.globals.page_shift))
142 while x < nslabspmb:
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):
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)
151 ts = mca.mca_trns[trn].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 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)
178 ts = mca.mca_trns[trn].mca_tstamp
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"
207 nslabspmb = int(((1 << MBSHIFT) >> unsigned(kern.globals.page_shift)))
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"
215 out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1]))
216 else:
217 slabs_table_string_format = "{0:>3d}: 0x{1:8x} [ 0x{2:8x} - 0x{3:8x} ]\n"
218 out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1]))
219
220 x += 1
221 print out_string
222 # EndMacro: mbuf_slabstbl
223
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])
248
249 def GetMbufBuf2Mca(m):
250 sl = GetMbufSlab(m)
251 mca = GetMbufMcaPtr(m, sl.sl_class)
252 return str(mca)
253
254 def GetMbufWalkAllSlabs(show_a, show_f, show_tr):
255 out_string = ""
256
257 kern.globals.slabstbl[0]
258
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
278 nslabspmb = unsigned((1 << MBSHIFT) >> unsigned(kern.globals.page_shift))
279 while (x < unsigned(kern.globals.slabgrp)):
280 slg = kern.globals.slabstbl[x]
281 y = 0
282 stop = 0
283 while ((y < nslabspmb) and (stop == 0)):
284 sl = addressof(slg.slg_slab[y])
285 base = sl.sl_base
286 mca = GetMbufMcaPtr(base, sl.sl_class)
287 first = 1
288
289 while ((Cast(mca, 'int') != 0) and (unsigned(mca.mca_addr) != 0)):
290 printmca = 0
291 if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)):
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
321 if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)):
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):
331 if (mca.mca_next_trn == 0):
332 trn = 1
333 else:
334 trn = 0
335 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"
336 cnt = 0
337 while (cnt < mca.mca_trns[int(trn)].mca_depth):
338 kgm_pc = mca.mca_trns[int(trn)].mca_stack[int(cnt)]
339 out_string += str(int(cnt) + 1) + " "
340 out_string += GetPc(kgm_pc)
341 cnt += 1
342
343 print out_string
344 out_string = ""
345 mca = mca.mca_next
346
347 y += 1
348 if (slg.slg_slab[int(y)].sl_base == 0):
349 stop = 1
350 x += 1
351
352 if (total and show_a and show_f):
353 out_string += "total objects = " + str(int(total)) + "\n"
354 out_string += "active/unfreed objects = " + str(int(total_a)) + "\n"
355 out_string += "freed/in_cache objects = " + str(int(total_f)) + "\n"
356
357 return out_string
358
359 def GetMbufMcaCtype(mca, vopt):
360 cp = mca.mca_cache
361 mca_class = unsigned(cp.mc_private)
362 csize = unsigned(kern.globals.mbuf_table[mca_class].mtbl_stats.mbcl_size)
363 done = 0
364 out_string = " "
365 if (csize == MSIZE):
366 if (vopt):
367 out_string += "M (mbuf) "
368 else:
369 out_string += "M "
370 return out_string
371 if (csize == MCLBYTES):
372 if (vopt):
373 out_string += "CL (2K cluster) "
374 else:
375 out_string += "CL "
376 return out_string
377 if (csize == MBIGCLBYTES):
378 if (vopt):
379 out_string += "BCL (4K cluster) "
380 else:
381 out_string += "BCL "
382 return out_string
383 if (csize == M16KCLBYTES):
384 if (vopt):
385 out_string += "JCL (16K cluster) "
386 else:
387 out_string += "JCL "
388 return out_string
389
390 if (csize == (MSIZE + MCLBYTES)):
391 if (mca.mca_uflags & MB_SCVALID):
392 if (mca.mca_uptr):
393 out_string += "M+CL "
394 if vopt:
395 out_string += "(paired mbuf, 2K cluster) "
396 else:
397 out_string += "M-CL "
398 if vopt:
399 out_string += "(unpaired mbuf, 2K cluster) "
400 else:
401 if (mca.mca_uptr):
402 out_string += "CL+M "
403 if vopt:
404 out_string += "(paired 2K cluster, mbuf) "
405 else:
406 out_string += "CL-M "
407 if vopt:
408 out_string += "(unpaired 2K cluster, mbuf) "
409 return out_string
410
411 if (csize == (MSIZE + MBIGCLBYTES)):
412 if (mca.mca_uflags & MB_SCVALID):
413 if (mca.mca_uptr):
414 out_string += "M+BCL "
415 if vopt:
416 out_string += "(paired mbuf, 4K cluster) "
417 else:
418 out_string += "M-BCL "
419 if vopt:
420 out_string += "(unpaired mbuf, 4K cluster) "
421 else:
422 if (mca.mca_uptr):
423 out_string += "BCL+M "
424 if vopt:
425 out_string += "(paired 4K cluster, mbuf) "
426 else:
427 out_string += "BCL-m "
428 if vopt:
429 out_string += "(unpaired 4K cluster, mbuf) "
430 return out_string
431
432 if (csize == (MSIZE + M16KCLBYTES)):
433 if (mca.mca_uflags & MB_SCVALID):
434 if (mca.mca_uptr):
435 out_string += "M+BCL "
436 if vopt:
437 out_string += "(paired mbuf, 4K cluster) "
438 else:
439 out_string += "M-BCL "
440 if vopt:
441 out_string += "(unpaired mbuf, 4K cluster) "
442 else:
443 if (mca.mca_uptr):
444 out_string += "BCL+M "
445 if vopt:
446 out_string += "(paired 4K cluster, mbuf) "
447 else:
448 out_string += "BCL-m "
449 if vopt:
450 out_string += "(unpaired 4K cluster, mbuf) "
451 return out_string
452
453 out_string += "unknown: " + cp.mc_name
454 return out_string
455
456 kgm_pkmod = 0
457 kgm_pkmodst = 0
458 kgm_pkmoden = 0
459
460 def GetPointerAsString(kgm_pc):
461 if (kern.ptrsize == 8):
462 pointer_format_string = "0x{0:<16x} "
463 else:
464 pointer_format_string = "0x{0:<8x} "
465 return pointer_format_string.format(kgm_pc)
466
467 def GetPc(kgm_pc):
468 out_string = GetSourceInformationForAddress(unsigned(kgm_pc)) + "\n"
469 return out_string
470
471
472 # Macro: mbuf_showactive
473 @lldb_command('mbuf_showactive')
474 def MbufShowActive(cmd_args=None):
475 """ Print all active/in-use mbuf objects
476 """
477 if cmd_args:
478 print GetMbufWalkAllSlabs(1, 0, cmd_args[0])
479 else:
480 print GetMbufWalkAllSlabs(1, 0, 0)
481 # EndMacro: mbuf_showactive
482
483
484 # Macro: mbuf_showinactive
485 @lldb_command('mbuf_showinactive')
486 def MbufShowInactive(cmd_args=None):
487 """ Print all freed/in-cache mbuf objects
488 """
489 print GetMbufWalkAllSlabs(0, 1, 0)
490 # EndMacro: mbuf_showinactive
491
492
493 # Macro: mbuf_showmca
494 @lldb_command('mbuf_showmca')
495 def MbufShowMca(cmd_args=None):
496 """ Print the contents of an mbuf mcache audit structure
497 """
498 out_string = ""
499 pgshift = unsigned(kern.globals.page_shift)
500 if cmd_args:
501 mca = kern.GetValueFromAddress(cmd_args[0], 'mcache_audit_t *')
502 cp = mca.mca_cache
503 out_string += "object type:\t"
504 out_string += GetMbufMcaCtype(mca, 1)
505 out_string += "\nControlling mcache :\t" + hex(mca.mca_cache) + " (" + str(cp.mc_name) + ")\n"
506 if (mca.mca_uflags & MB_SCVALID):
507 mbutl = Cast(kern.globals.mbutl, 'unsigned char *')
508 ix = (mca.mca_addr - mbutl) >> pgshift
509 clbase = mbutl + (ix << pgshift)
510 mclidx = (mca.mca_addr - clbase) >> 8
511 out_string += "mbuf obj :\t\t" + hex(mca.mca_addr) + "\n"
512 out_string += "mbuf index :\t\t" + str(mclidx + 1) + " (out of 16) in cluster base " + hex(clbase) + "\n"
513 if (int(mca.mca_uptr) != 0):
514 peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *')
515 out_string += "paired cluster obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n"
516 out_string += "saved contents :\t" + hex(mca.mca_contents) + " (" + str(int(mca.mca_contents_size)) + " bytes)\n"
517 else:
518 out_string += "cluster obj :\t\t" + hex(mca.mca_addr) + "\n"
519 if (mca.mca_uptr != 0):
520 peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *')
521 out_string += "paired mbuf obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n"
522
523 for idx in range(unsigned(kern.globals.mca_trn_max), 0, -1):
524 trn = (mca.mca_next_trn + idx - 1) % unsigned(kern.globals.mca_trn_max)
525 out_string += "transaction {:d} (tstamp {:d}, thread 0x{:x}):\n".format(trn, mca.mca_trns[trn].mca_tstamp, mca.mca_trns[trn].mca_thread)
526 cnt = 0
527 while (cnt < mca.mca_trns[trn].mca_depth):
528 kgm_pc = mca.mca_trns[trn].mca_stack[cnt]
529 out_string += " " + str(cnt + 1) + ". "
530 out_string += GetPc(kgm_pc)
531 cnt += 1
532
533 msc = cast(mca.mca_contents, 'mcl_saved_contents_t *')
534 msa = addressof(msc.sc_scratch)
535 if (mca.mca_uflags & MB_SCVALID):
536 if (msa.msa_depth > 0):
537 out_string += "Recent scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_tstamp, msa.msa_thread)
538 cnt = 0
539 while (cnt < msa.msa_depth):
540 kgm_pc = msa.msa_stack[cnt]
541 out_string += " " + str(cnt + 1) + ". "
542 out_string += GetPc(kgm_pc)
543 cnt += 1
544
545 if (msa.msa_pdepth > 0):
546 out_string += "previous scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_ptstamp, msa.msa_pthread)
547 if (msa):
548 cnt = 0
549 while (cnt < msa.msa_pdepth):
550 kgm_pc = msa.msa_pstack[cnt]
551 out_string += " " + str(cnt + 1) + ". "
552 out_string += GetPc(kgm_pc)
553 cnt += 1
554 else:
555 out_string += "Missing argument 0 in user function."
556
557 print out_string
558 # EndMacro: mbuf_showmca
559
560
561 # Macro: mbuf_showall
562 @lldb_command('mbuf_showall')
563 def MbufShowAll(cmd_args=None):
564 """ Print all mbuf objects
565 """
566 print GetMbufWalkAllSlabs(1, 1, 1)
567 # EndMacro: mbuf_showall
568
569 # Macro: mbuf_countchain
570 @lldb_command('mbuf_countchain')
571 def MbufCountChain(cmd_args=None):
572 """ Count the length of an mbuf chain
573 """
574 if not cmd_args:
575 raise ArgumentError("Missing argument 0 in user function.")
576
577 mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
578
579 pkt = 0
580 nxt = 0
581
582 while (mp):
583 pkt = pkt + 1
584 mn = mp.m_hdr.mh_next
585 while (mn):
586 nxt = nxt + 1
587 mn = mn.m_hdr.mh_next
588
589 mp = mp.m_hdr.mh_nextpkt
590
591 if (((pkt + nxt) % 50) == 0):
592 print " ..." + str(pkt_nxt)
593
594 print "Total: " + str(pkt + nxt) + " (via m_next: " + str(nxt) + ")"
595 # EndMacro: mbuf_countchain
596
597
598
599 # Macro: mbuf_topleak
600 @lldb_command('mbuf_topleak')
601 def MbufTopLeak(cmd_args=None):
602 """ Print the top suspected mbuf leakers
603 """
604 topcnt = 0
605 if (int(len(cmd_args)) > 0 and int(cmd_args[0]) < 5):
606 maxcnt = cmd_args[0]
607 else:
608 maxcnt = 5
609 while (topcnt < maxcnt):
610 print GetMbufTraceLeak(kern.globals.mleak_top_trace[topcnt])
611 topcnt += 1
612
613 # EndMacro: mbuf_topleak
614
615 def GetMbufTraceLeak(trace):
616 out_string = ""
617 if (trace.allocs != 0):
618 out_string += hex(trace) + ":" + str(trace.allocs) + " outstanding allocs\n"
619 out_string += "Backtrace saved " + str(trace.depth) + " deep\n"
620 if (trace.depth != 0):
621 cnt = 0
622 while (cnt < trace.depth):
623 out_string += str(cnt + 1) + ": "
624 out_string += GetPc(trace.addr[cnt])
625 out_string += "\n"
626 cnt += 1
627 return out_string
628
629 @lldb_command('mbuf_largefailures')
630 def MbufLargeFailures(cmd_args=None):
631 """ Print the largest allocation failures
632 """
633 topcnt = 0
634 if (int(len(cmd_args)) > 0 and int(cmd_args[0]) < 5):
635 maxcnt = cmd_args[0]
636 else:
637 maxcnt = 5
638 while (topcnt < maxcnt):
639 trace = kern.globals.mtracelarge_table[topcnt]
640 if (trace.size == 0):
641 topcnt += 1
642 continue
643 print str(trace.size)
644 if (trace.depth != 0):
645 cnt = 0
646 while (cnt < trace.depth):
647 print str(cnt + 1) + ": " + GetPc(trace.addr[cnt])
648 cnt += 1
649 topcnt += 1
650
651
652 # Macro: mbuf_traceleak
653 @lldb_command('mbuf_traceleak')
654 def MbufTraceLeak(cmd_args=None):
655 """ Print the leak information for a given leak address
656 Given an mbuf leak trace (mtrace) structure address, print out the
657 stored information with that trace
658 syntax: (lldb) mbuf_traceleak <addr>
659 """
660 if not cmd_args:
661 raise ArgumentError("Missing argument 0 in user function.")
662
663 trace = kern.GetValueFromAddress(cmd_args[0], 'mtrace *')
664 print GetMbufTraceLeak(trace)
665 # EndMacro: mbuf_traceleak
666
667
668 # Macro: mcache_walkobj
669 @lldb_command('mcache_walkobj')
670 def McacheWalkObject(cmd_args=None):
671 """ Given a mcache object address, walk its obj_next pointer
672 """
673 if not cmd_args:
674 raise ArgumentError("Missing argument 0 in user function.")
675
676 out_string = ""
677 p = kern.GetValueFromAddress(cmd_args[0], 'mcache_obj_t *')
678 cnt = 1
679 total = 0
680 while (p):
681 mcache_object_format = "{0:>4d}: 0x{1:>16x}"
682 out_string += mcache_object_format.format(cnt, p) + "\n"
683 p = p.obj_next
684 cnt += 1
685 print out_string
686 # EndMacro: mcache_walkobj
687
688 # Macro: mcache_stat
689 @lldb_command('mcache_stat')
690 def McacheStat(cmd_args=None):
691 """ Print all mcaches in the system.
692 """
693 head = kern.globals.mcache_head
694 out_string = ""
695 mc = cast(head.lh_first, 'mcache *')
696 if (kern.ptrsize == 8):
697 mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>20s} {3:>5s} {4:>5s} {5:>20s} {6:>30s} {7:>18s}"
698 else:
699 mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>12s} {3:>5s} {4:>5s} {5:>12s} {6:>30s} {7:>18s}"
700
701 if (kern.ptrsize == 8):
702 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}"
703 else:
704 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}"
705
706 out_string += mcache_stat_format_string.format("cache name", "cache state", "cache addr", "buf size", "buf align", "backing zone", "wait nowait failed", "bufs incache")
707 out_string += "\n"
708
709 ncpu = int(kern.globals.ncpu)
710 while mc != 0:
711 bktsize = mc.mc_cpu[0].cc_bktsize
712 cache_state = ""
713 if (mc.mc_flags & MCF_NOCPUCACHE):
714 cache_state = "disabled"
715 else:
716 if (bktsize == 0):
717 cache_state = " offline"
718 else:
719 cache_state = " online"
720 if (mc.mc_slab_zone != 0):
721 backing_zone = mc.mc_slab_zone
722 else:
723 if (kern.ptrsize == 8):
724 backing_zone = " custom"
725 else:
726 backing_zone = " custom"
727
728 total = 0
729 total += mc.mc_full.bl_total * bktsize
730 n = 0
731 while(n < ncpu):
732 ccp = mc.mc_cpu[n]
733 if (ccp.cc_objs > 0):
734 total += ccp.cc_objs
735 if (ccp.cc_pobjs > 0):
736 total += ccp.cc_pobjs
737 n += 1
738 ccp += 1
739
740 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)
741 out_string += "\n"
742 mc = cast(mc.mc_list.le_next, 'mcache *')
743 print out_string
744 # EndMacro: mcache_stat
745
746 # Macro: mcache_showcache
747 @lldb_command('mcache_showcache')
748 def McacheShowCache(cmd_args=None):
749 """Display the number of objects in cache.
750 """
751 out_string = ""
752 cp = kern.GetValueFromAddress(cmd_args[0], 'mcache_t *')
753 bktsize = cp.mc_cpu[0].cc_bktsize
754 cnt = 0
755 total = 0
756 mcache_cache_format = "{0:<4d} {1:>8d} {2:>8d} {3:>8d}"
757 out_string += "Showing cache " + str(cp.mc_name) + " :\n\n"
758 out_string += " CPU cc_objs cc_pobjs total\n"
759 out_string += "---- ------- -------- --------\n"
760 ncpu = int(kern.globals.ncpu)
761 while (cnt < ncpu):
762 ccp = cp.mc_cpu[cnt]
763 objs = ccp.cc_objs
764 if (objs <= 0):
765 objs = 0
766 pobjs = ccp.cc_pobjs
767 if (pobjs <= 0):
768 pobjs = 0
769 tot_cpu = objs + pobjs
770 total += tot_cpu
771 out_string += mcache_cache_format.format(cnt, objs, pobjs, tot_cpu)
772 out_string += "\n"
773 cnt += 1
774
775 out_string += " ========\n"
776 out_string += " " + str(total) + "\n\n"
777 total += cp.mc_full.bl_total * bktsize
778
779 out_string += "Total # of full buckets (" + str(int(bktsize)) + " objs/bkt):\t" + str(int(cp.mc_full.bl_total)) + "\n"
780 out_string += "Total # of objects cached:\t\t" + str(total) + "\n"
781 print out_string
782 # EndMacro: mcache_showcache
783
784 # Macro: mbuf_wdlog
785 @lldb_command('mbuf_wdlog')
786 def McacheShowCache(cmd_args=None):
787 """Display the watchdog log
788 """
789 lldb_run_command('settings set max-string-summary-length 4096')
790 print('%s' % lldb_run_command('p/s mbwdog_logging').replace("\\n","\n"))
791 # EndMacro: mbuf_wdlog