""" Please make sure you read the README COMPLETELY BEFORE reading anything below.
It is very critical that you read coding guidelines in Section E in README file.
"""
from xnu import *
from utils import *
from mbufdefines import *
import xnudefines
@lldb_command('mbuf_stat')
def MBufStat(cmd_args=None):
""" Print extended mbuf allocator statistics.
"""
hdr_format = "{0: <16s} {1: >8s} {2: >8s} {3: ^16s} {4: >8s} {5: >12s} {6: >8s} {7: >8s} {8: >8s} {9: >8s}"
print hdr_format.format('class', 'total', 'cached', 'uncached', 'inuse', 'failed', 'waiter', 'notified', 'purge', 'max')
print hdr_format.format('name', 'objs', 'objs', 'objs/slabs', 'objs', 'alloc count', 'count', 'count', 'count', 'objs')
print hdr_format.format('-'*16, '-'*8, '-'*8, '-'*16, '-'*8, '-'*12, '-'*8, '-'*8, '-'*8, '-'*8)
entry_format = "{0: <16s} {1: >8d} {2: >8d} {3:>7d} / {4:<6d} {5: >8d} {6: >12d} {7: >8d} {8: >8d} {9: >8d} {10: >8d}"
num_items = sizeof(kern.globals.mbuf_table) / sizeof(kern.globals.mbuf_table[0])
ncpus = int(kern.globals.ncpu)
for i in range(num_items):
mbuf = kern.globals.mbuf_table[i]
mcs = Cast(mbuf.mtbl_stats, 'mb_class_stat_t *')
mc = mbuf.mtbl_cache
total = 0
total += int(mc.mc_full.bl_total) * int(mc.mc_cpu[0].cc_bktsize)
ccp_arr = mc.mc_cpu
for i in range(ncpus):
ccp = ccp_arr[i]
if int(ccp.cc_objs) > 0:
total += int(ccp.cc_objs)
if int(ccp.cc_pobjs) > 0:
total += int(ccp.cc_pobjs)
print entry_format.format(mcs.mbcl_cname, mcs.mbcl_total, total,
mcs.mbcl_infree, mcs.mbcl_slab_cnt,
(mcs.mbcl_total - total - mcs.mbcl_infree),
mcs.mbcl_fail_cnt, mbuf.mtbl_cache.mc_waiter_cnt,
mcs.mbcl_notified, mcs.mbcl_purge_cnt,
mbuf.mtbl_maxlimit
)
@lldb_command('mbuf_walkpkt')
def MbufWalkPacket(cmd_args=None):
""" Walk the mbuf packet chain (m_nextpkt)
"""
if not cmd_args:
raise ArgumentError("Missing argument 0 in user function.")
mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
cnt = 1
tot = 0
while (mp):
out_string = ""
mbuf_walk_packet_format = "{0:4d} 0x{1:x} [len {2:4d}, type {3:2d}, "
out_string += mbuf_walk_packet_format.format(cnt, mp, mp.m_hdr.mh_len, mp.m_hdr.mh_type)
if (kern.globals.mclaudit != 0):
out_string += GetMbufBuf2Mca(mp) + ", "
tot = tot + mp.m_hdr.mh_len
out_string += "total " + str(tot) + "]"
print out_string
mp = mp.m_hdr.mh_nextpkt
cnt += 1
@lldb_command('mbuf_walk')
def MbufWalk(cmd_args=None):
""" Walk the mbuf chain (m_next)
"""
mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
cnt = 1
tot = 0
while (mp):
out_string = ""
mbuf_walk_format = "{0:4d} 0x{1:x} [len {2:4d}, type {3:2d}, "
out_string += mbuf_walk_format.format(cnt, mp, mp.m_hdr.mh_len, mp.m_hdr.mh_type)
if (kern.globals.mclaudit != 0):
out_string += GetMbufBuf2Mca(mp) + ", "
tot = tot + mp.m_hdr.mh_len
out_string += "total " + str(tot) + "]"
print out_string
mp = mp.m_hdr.mh_next
cnt += 1
@lldb_command('mbuf_buf2slab')
def MbufBuf2Slab(cmd_args=None):
""" Given an mbuf object, find its corresponding slab address
"""
if not cmd_args:
raise ArgumentError("Missing argument 0 in user function.")
m = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
slab = GetMbufSlab(m)
if (kern.ptrsize == 8):
mbuf_slab_format = "0x{0:<16x}"
print mbuf_slab_format.format(slab)
else:
mbuf_slab_format = "0x{0:<8x}"
print mbuf_slab_format.format(slab)
@lldb_command('mbuf_buf2mca')
def MbufBuf2Mca(cmd_args=None):
""" Find the mcache audit structure of the corresponding mbuf
"""
m = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
print GetMbufBuf2Mca(m)
return
@lldb_command('mbuf_slabs')
def MbufSlabs(cmd_args=None):
""" Print all slabs in the group
"""
out_string = ""
if not cmd_args:
raise ArgumentError("Invalid arguments passed.")
slg = kern.GetValueFromAddress(cmd_args[0], 'mcl_slabg_t *')
x = 0
if (kern.ptrsize == 8):
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} "
out_string += "slot slab next obj mca tstamp C R N size flags\n"
out_string += "---- ------------------ ------------------ ------------------ ------------------ ---------- -- -- -- ------ -----\n"
else:
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} "
out_string += "slot slab next obj mca tstamp C R N size flags\n"
out_string += "---- ---------- ---------- ---------- ---------- ---------- -- -- -- ------ -----\n"
mbutl = cast(kern.globals.mbutl, 'unsigned char *')
nslabspmb = int((1 << MBSHIFT) >> unsigned(kern.globals.page_shift))
while x < nslabspmb:
sl = addressof(slg.slg_slab[x])
mca = 0
obj = sl.sl_base
ts = 0
if (kern.globals.mclaudit != 0):
mca = GetMbufMcaPtr(obj, sl.sl_class)
trn = (mca.mca_next_trn + unsigned(kern.globals.mca_trn_max) - 1) % unsigned(kern.globals.mca_trn_max)
ts = mca.mca_trns[trn].mca_tstamp
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))
if (sl.sl_flags != 0):
out_string += "<"
if sl.sl_flags & SLF_MAPPED:
out_string += "mapped"
if sl.sl_flags & SLF_PARTIAL:
out_string += ",partial"
if sl.sl_flags & SLF_DETACHED:
out_string += ",detached"
out_string += ">"
out_string += "\n"
if sl.sl_chunks > 1:
z = 1
c = sl.sl_len/sl.sl_chunks
while z < sl.sl_chunks:
obj = sl.sl_base + (c * z)
mca = 0
ts = 0
if (kern.globals.mclaudit != 0):
mca = GetMbufMcaPtr(obj, sl.sl_class)
trn = (mca.mca_next_trn + unsigned(kern.globals.mca_trn_max) - 1) % unsigned(kern.globals.mca_trn_max)
ts = mca.mca_trns[trn].mca_tstamp
if (kern.ptrsize == 8):
out_string += " " + hex(obj) + " " + hex(mca) + " " + str(unsigned(ts)) + "\n"
else:
out_string += " " + hex(obj) + " " + hex(mca) + " " + str(unsigned(ts)) + "\n"
z += 1
x += 1
print out_string
@lldb_command('mbuf_slabstbl')
def MbufSlabsTbl(cmd_args=None):
""" Print slabs table
"""
out_string = ""
x = 0
if (kern.ptrsize == 8):
out_string += "slot slabg slabs range\n"
out_string += "---- ------------------ -------------------------------------------\n"
else:
out_string += "slot slabg slabs range\n"
out_string += "---- ---------- ---------------------------\n"
slabstbl = kern.globals.slabstbl
slabs_table_blank_string_format = "{0:>3d}: - \n"
nslabspmb = int(((1 << MBSHIFT) >> unsigned(kern.globals.page_shift)))
while (x < unsigned(kern.globals.maxslabgrp)):
slg = slabstbl[x]
if (slg == 0):
out_string += slabs_table_blank_string_format.format(x+1)
else:
if (kern.ptrsize == 8):
slabs_table_string_format = "{0:>3d}: 0x{1:16x} [ 0x{2:16x} - 0x{3:16x} ]\n"
out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1]))
else:
slabs_table_string_format = "{0:>3d}: 0x{1:8x} [ 0x{2:8x} - 0x{3:8x} ]\n"
out_string += slabs_table_string_format.format(x+1, slg, addressof(slg.slg_slab[0]), addressof(slg.slg_slab[nslabspmb-1]))
x += 1
print out_string
def GetMbufMcaPtr(m, cl):
pgshift = int(kern.globals.page_shift)
ix = int((m - Cast(kern.globals.mbutl, 'char *')) >> pgshift)
page_addr = (Cast(kern.globals.mbutl, 'char *') + (ix << pgshift))
if (int(cl) == 0):
midx = int((m - page_addr) >> 8)
mca = kern.globals.mclaudit[ix].cl_audit[midx]
elif (int(cl) == 1):
midx = int((m - page_addr) >> 11)
mca = kern.globals.mclaudit[ix].cl_audit[midx]
elif (int(cl) == 2):
midx = int((m - page_addr) >> 12)
mca = kern.globals.mclaudit[ix].cl_audit[midx]
else:
mca = kern.globals.mclaudit[ix].cl_audit[0]
return Cast(mca, 'mcache_audit_t *')
def GetMbufSlab(m):
pgshift = int(kern.globals.page_shift)
gix = int((Cast(m, 'char *') - Cast(kern.globals.mbutl, 'char *')) >> MBSHIFT)
slabstbl = kern.globals.slabstbl
ix = int((Cast(m, 'char *') - Cast(slabstbl[gix].slg_slab[0].sl_base, 'char *')) >> pgshift)
return addressof(slabstbl[gix].slg_slab[ix])
def GetMbufBuf2Mca(m):
sl = GetMbufSlab(m)
mca = GetMbufMcaPtr(m, sl.sl_class)
return str(mca)
def GetMbufWalkAllSlabs(show_a, show_f, show_tr):
out_string = ""
kern.globals.slabstbl[0]
x = 0
total = 0
total_a = 0
total_f = 0
if (show_a and not(show_f)):
out_string += "Searching only for active... \n"
if (not(show_a) and show_f):
out_string += "Searching only for inactive... \n"
if (show_a and show_f):
out_string += "Displaying all... \n"
if (kern.ptrsize == 8):
show_mca_string_format = "{0:>4s} {1:>4s} {2:>16s} {3:>16s} {4:>16} {5:>12s} {6:12s}"
out_string += show_mca_string_format.format("slot", "idx", "slab address", "mca address", "obj address", "type", "allocation state\n")
else:
show_mca_string_format = "{0:4s} {1:4s} {2:8s} {3:8s} {4:8} {5:12s} {6:12s}"
out_string += show_mca_string_format.format("slot", "idx", "slab address", "mca address", "obj address", "type", "allocation state\n")
nslabspmb = unsigned((1 << MBSHIFT) >> unsigned(kern.globals.page_shift))
while (x < unsigned(kern.globals.slabgrp)):
slg = kern.globals.slabstbl[x]
y = 0
stop = 0
while ((y < nslabspmb) and (stop == 0)):
sl = addressof(slg.slg_slab[y])
base = sl.sl_base
mca = GetMbufMcaPtr(base, sl.sl_class)
first = 1
while ((Cast(mca, 'int') != 0) and (unsigned(mca.mca_addr) != 0)):
printmca = 0
if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)):
total_a = total_a + 1
printmca = show_a
else:
total_f = total_f + 1
printmca = show_f
if (printmca != 0):
if (first == 1):
if (kern.ptrsize == 8):
mca_string_format = "{0:4d} {1:4d} 0x{2:16x} "
out_string += mca_string_format.format(x, y, sl)
else:
mca_string_format = "{0:4d} {1:4d} 0x{02:8x} "
out_string += mca_string_format.format(x, y, sl)
else:
if (kern.ptrsize == 8):
out_string += " "
else:
out_string += " "
if (kern.ptrsize == 8):
mca_string_format = "0x{0:16x} 0x{1:16x}"
out_string += mca_string_format.format(mca, mca.mca_addr)
else:
mca_string_format = "0x{0:8x} 0x{1:8x}"
out_string += mca_string_format.format(mca, mca.mca_addr)
out_string += GetMbufMcaCtype(mca, 0)
if (mca.mca_uflags & (MB_INUSE | MB_COMP_INUSE)):
out_string += "active "
else:
out_string += " freed "
if (first == 1):
first = 0
out_string += "\n"
total = total + 1
if (show_tr != 0):
if (mca.mca_next_trn == 0):
trn = 1
else:
trn = 0
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"
cnt = 0
while (cnt < mca.mca_trns[int(trn)].mca_depth):
kgm_pc = mca.mca_trns[int(trn)].mca_stack[int(cnt)]
out_string += str(int(cnt) + 1) + " "
out_string += GetPc(kgm_pc)
cnt += 1
print out_string
out_string = ""
mca = mca.mca_next
y += 1
if (slg.slg_slab[int(y)].sl_base == 0):
stop = 1
x += 1
if (total and show_a and show_f):
out_string += "total objects = " + str(int(total)) + "\n"
out_string += "active/unfreed objects = " + str(int(total_a)) + "\n"
out_string += "freed/in_cache objects = " + str(int(total_f)) + "\n"
return out_string
def GetMbufMcaCtype(mca, vopt):
cp = mca.mca_cache
mca_class = unsigned(cp.mc_private)
csize = unsigned(kern.globals.mbuf_table[mca_class].mtbl_stats.mbcl_size)
done = 0
out_string = " "
if (csize == MSIZE):
if (vopt):
out_string += "M (mbuf) "
else:
out_string += "M "
return out_string
if (csize == MCLBYTES):
if (vopt):
out_string += "CL (2K cluster) "
else:
out_string += "CL "
return out_string
if (csize == MBIGCLBYTES):
if (vopt):
out_string += "BCL (4K cluster) "
else:
out_string += "BCL "
return out_string
if (csize == M16KCLBYTES):
if (vopt):
out_string += "JCL (16K cluster) "
else:
out_string += "JCL "
return out_string
if (csize == (MSIZE + MCLBYTES)):
if (mca.mca_uflags & MB_SCVALID):
if (mca.mca_uptr):
out_string += "M+CL "
if vopt:
out_string += "(paired mbuf, 2K cluster) "
else:
out_string += "M-CL "
if vopt:
out_string += "(unpaired mbuf, 2K cluster) "
else:
if (mca.mca_uptr):
out_string += "CL+M "
if vopt:
out_string += "(paired 2K cluster, mbuf) "
else:
out_string += "CL-M "
if vopt:
out_string += "(unpaired 2K cluster, mbuf) "
return out_string
if (csize == (MSIZE + MBIGCLBYTES)):
if (mca.mca_uflags & MB_SCVALID):
if (mca.mca_uptr):
out_string += "M+BCL "
if vopt:
out_string += "(paired mbuf, 4K cluster) "
else:
out_string += "M-BCL "
if vopt:
out_string += "(unpaired mbuf, 4K cluster) "
else:
if (mca.mca_uptr):
out_string += "BCL+M "
if vopt:
out_string += "(paired 4K cluster, mbuf) "
else:
out_string += "BCL-m "
if vopt:
out_string += "(unpaired 4K cluster, mbuf) "
return out_string
if (csize == (MSIZE + M16KCLBYTES)):
if (mca.mca_uflags & MB_SCVALID):
if (mca.mca_uptr):
out_string += "M+BCL "
if vopt:
out_string += "(paired mbuf, 4K cluster) "
else:
out_string += "M-BCL "
if vopt:
out_string += "(unpaired mbuf, 4K cluster) "
else:
if (mca.mca_uptr):
out_string += "BCL+M "
if vopt:
out_string += "(paired 4K cluster, mbuf) "
else:
out_string += "BCL-m "
if vopt:
out_string += "(unpaired 4K cluster, mbuf) "
return out_string
out_string += "unknown: " + cp.mc_name
return out_string
kgm_pkmod = 0
kgm_pkmodst = 0
kgm_pkmoden = 0
def GetPointerAsString(kgm_pc):
if (kern.ptrsize == 8):
pointer_format_string = "0x{0:<16x} "
else:
pointer_format_string = "0x{0:<8x} "
return pointer_format_string.format(kgm_pc)
def GetPc(kgm_pc):
out_string = GetSourceInformationForAddress(unsigned(kgm_pc)) + "\n"
return out_string
@lldb_command('mbuf_showactive')
def MbufShowActive(cmd_args=None):
""" Print all active/in-use mbuf objects
"""
if cmd_args:
print GetMbufWalkAllSlabs(1, 0, cmd_args[0])
else:
print GetMbufWalkAllSlabs(1, 0, 0)
@lldb_command('mbuf_showinactive')
def MbufShowInactive(cmd_args=None):
""" Print all freed/in-cache mbuf objects
"""
print GetMbufWalkAllSlabs(0, 1, 0)
@lldb_command('mbuf_showmca')
def MbufShowMca(cmd_args=None):
""" Print the contents of an mbuf mcache audit structure
"""
out_string = ""
pgshift = unsigned(kern.globals.page_shift)
if cmd_args:
mca = kern.GetValueFromAddress(cmd_args[0], 'mcache_audit_t *')
cp = mca.mca_cache
out_string += "object type:\t"
out_string += GetMbufMcaCtype(mca, 1)
out_string += "\nControlling mcache :\t" + hex(mca.mca_cache) + " (" + str(cp.mc_name) + ")\n"
if (mca.mca_uflags & MB_SCVALID):
mbutl = Cast(kern.globals.mbutl, 'unsigned char *')
ix = (mca.mca_addr - mbutl) >> pgshift
clbase = mbutl + (ix << pgshift)
mclidx = (mca.mca_addr - clbase) >> 8
out_string += "mbuf obj :\t\t" + hex(mca.mca_addr) + "\n"
out_string += "mbuf index :\t\t" + str(mclidx + 1) + " (out of 16) in cluster base " + hex(clbase) + "\n"
if (int(mca.mca_uptr) != 0):
peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *')
out_string += "paired cluster obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n"
out_string += "saved contents :\t" + hex(mca.mca_contents) + " (" + str(int(mca.mca_contents_size)) + " bytes)\n"
else:
out_string += "cluster obj :\t\t" + hex(mca.mca_addr) + "\n"
if (mca.mca_uptr != 0):
peer_mca = cast(mca.mca_uptr, 'mcache_audit_t *')
out_string += "paired mbuf obj :\t" + hex(peer_mca.mca_addr) + " (mca " + hex(peer_mca) + ")\n"
for idx in range(unsigned(kern.globals.mca_trn_max), 0, -1):
trn = (mca.mca_next_trn + idx - 1) % unsigned(kern.globals.mca_trn_max)
out_string += "transaction {:d} (tstamp {:d}, thread 0x{:x}):\n".format(trn, mca.mca_trns[trn].mca_tstamp, mca.mca_trns[trn].mca_thread)
cnt = 0
while (cnt < mca.mca_trns[trn].mca_depth):
kgm_pc = mca.mca_trns[trn].mca_stack[cnt]
out_string += " " + str(cnt + 1) + ". "
out_string += GetPc(kgm_pc)
cnt += 1
msc = cast(mca.mca_contents, 'mcl_saved_contents_t *')
msa = addressof(msc.sc_scratch)
if (mca.mca_uflags & MB_SCVALID):
if (msa.msa_depth > 0):
out_string += "Recent scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_tstamp, msa.msa_thread)
cnt = 0
while (cnt < msa.msa_depth):
kgm_pc = msa.msa_stack[cnt]
out_string += " " + str(cnt + 1) + ". "
out_string += GetPc(kgm_pc)
cnt += 1
if (msa.msa_pdepth > 0):
out_string += "previous scratch transaction (tstamp {:d}, thread 0x{:x}):\n".format(msa.msa_ptstamp, msa.msa_pthread)
if (msa):
cnt = 0
while (cnt < msa.msa_pdepth):
kgm_pc = msa.msa_pstack[cnt]
out_string += " " + str(cnt + 1) + ". "
out_string += GetPc(kgm_pc)
cnt += 1
else:
out_string += "Missing argument 0 in user function."
print out_string
@lldb_command('mbuf_showall')
def MbufShowAll(cmd_args=None):
""" Print all mbuf objects
"""
print GetMbufWalkAllSlabs(1, 1, 1)
@lldb_command('mbuf_countchain')
def MbufCountChain(cmd_args=None):
""" Count the length of an mbuf chain
"""
if not cmd_args:
raise ArgumentError("Missing argument 0 in user function.")
mp = kern.GetValueFromAddress(cmd_args[0], 'mbuf *')
pkt = 0
nxt = 0
while (mp):
pkt = pkt + 1
mn = mp.m_hdr.mh_next
while (mn):
nxt = nxt + 1
mn = mn.m_hdr.mh_next
mp = mp.m_hdr.mh_nextpkt
if (((pkt + nxt) % 50) == 0):
print " ..." + str(pkt_nxt)
print "Total: " + str(pkt + nxt) + " (via m_next: " + str(nxt) + ")"
@lldb_command('mbuf_topleak')
def MbufTopLeak(cmd_args=None):
""" Print the top suspected mbuf leakers
"""
topcnt = 0
if (int(len(cmd_args)) > 0 and int(cmd_args[0]) < 5):
maxcnt = cmd_args[0]
else:
maxcnt = 5
while (topcnt < maxcnt):
print GetMbufTraceLeak(kern.globals.mleak_top_trace[topcnt])
topcnt += 1
def GetMbufTraceLeak(trace):
out_string = ""
if (trace.allocs != 0):
out_string += hex(trace) + ":" + str(trace.allocs) + " outstanding allocs\n"
out_string += "Backtrace saved " + str(trace.depth) + " deep\n"
if (trace.depth != 0):
cnt = 0
while (cnt < trace.depth):
out_string += str(cnt + 1) + ": "
out_string += GetPc(trace.addr[cnt])
out_string += "\n"
cnt += 1
return out_string
@lldb_command('mbuf_largefailures')
def MbufLargeFailures(cmd_args=None):
""" Print the largest allocation failures
"""
topcnt = 0
if (int(len(cmd_args)) > 0 and int(cmd_args[0]) < 5):
maxcnt = cmd_args[0]
else:
maxcnt = 5
while (topcnt < maxcnt):
trace = kern.globals.mtracelarge_table[topcnt]
if (trace.size == 0):
topcnt += 1
continue
print str(trace.size)
if (trace.depth != 0):
cnt = 0
while (cnt < trace.depth):
print str(cnt + 1) + ": " + GetPc(trace.addr[cnt])
cnt += 1
topcnt += 1
@lldb_command('mbuf_traceleak')
def MbufTraceLeak(cmd_args=None):
""" Print the leak information for a given leak address
Given an mbuf leak trace (mtrace) structure address, print out the
stored information with that trace
syntax: (lldb) mbuf_traceleak <addr>
"""
if not cmd_args:
raise ArgumentError("Missing argument 0 in user function.")
trace = kern.GetValueFromAddress(cmd_args[0], 'mtrace *')
print GetMbufTraceLeak(trace)
@lldb_command('mcache_walkobj')
def McacheWalkObject(cmd_args=None):
""" Given a mcache object address, walk its obj_next pointer
"""
if not cmd_args:
raise ArgumentError("Missing argument 0 in user function.")
out_string = ""
p = kern.GetValueFromAddress(cmd_args[0], 'mcache_obj_t *')
cnt = 1
total = 0
while (p):
mcache_object_format = "{0:>4d}: 0x{1:>16x}"
out_string += mcache_object_format.format(cnt, p) + "\n"
p = p.obj_next
cnt += 1
print out_string
@lldb_command('mcache_stat')
def McacheStat(cmd_args=None):
""" Print all mcaches in the system.
"""
head = kern.globals.mcache_head
out_string = ""
mc = cast(head.lh_first, 'mcache *')
if (kern.ptrsize == 8):
mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>20s} {3:>5s} {4:>5s} {5:>20s} {6:>30s} {7:>18s}"
else:
mcache_stat_format_string = "{0:<24s} {1:>8s} {2:>12s} {3:>5s} {4:>5s} {5:>12s} {6:>30s} {7:>18s}"
if (kern.ptrsize == 8):
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}"
else:
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}"
out_string += mcache_stat_format_string.format("cache name", "cache state", "cache addr", "buf size", "buf align", "backing zone", "wait nowait failed", "bufs incache")
out_string += "\n"
ncpu = int(kern.globals.ncpu)
while mc != 0:
bktsize = mc.mc_cpu[0].cc_bktsize
cache_state = ""
if (mc.mc_flags & MCF_NOCPUCACHE):
cache_state = "disabled"
else:
if (bktsize == 0):
cache_state = " offline"
else:
cache_state = " online"
if (mc.mc_slab_zone != 0):
backing_zone = mc.mc_slab_zone
else:
if (kern.ptrsize == 8):
backing_zone = " custom"
else:
backing_zone = " custom"
total = 0
total += mc.mc_full.bl_total * bktsize
n = 0
while(n < ncpu):
ccp = mc.mc_cpu[n]
if (ccp.cc_objs > 0):
total += ccp.cc_objs
if (ccp.cc_pobjs > 0):
total += ccp.cc_pobjs
n += 1
ccp += 1
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)
out_string += "\n"
mc = cast(mc.mc_list.le_next, 'mcache *')
print out_string
@lldb_command('mcache_showcache')
def McacheShowCache(cmd_args=None):
"""Display the number of objects in cache.
"""
out_string = ""
cp = kern.GetValueFromAddress(cmd_args[0], 'mcache_t *')
bktsize = cp.mc_cpu[0].cc_bktsize
cnt = 0
total = 0
mcache_cache_format = "{0:<4d} {1:>8d} {2:>8d} {3:>8d}"
out_string += "Showing cache " + str(cp.mc_name) + " :\n\n"
out_string += " CPU cc_objs cc_pobjs total\n"
out_string += "---- ------- -------- --------\n"
ncpu = int(kern.globals.ncpu)
while (cnt < ncpu):
ccp = cp.mc_cpu[cnt]
objs = ccp.cc_objs
if (objs <= 0):
objs = 0
pobjs = ccp.cc_pobjs
if (pobjs <= 0):
pobjs = 0
tot_cpu = objs + pobjs
total += tot_cpu
out_string += mcache_cache_format.format(cnt, objs, pobjs, tot_cpu)
out_string += "\n"
cnt += 1
out_string += " ========\n"
out_string += " " + str(total) + "\n\n"
total += cp.mc_full.bl_total * bktsize
out_string += "Total # of full buckets (" + str(int(bktsize)) + " objs/bkt):\t" + str(int(cp.mc_full.bl_total)) + "\n"
out_string += "Total # of objects cached:\t\t" + str(total) + "\n"
print out_string
@lldb_command('mbuf_wdlog')
def McacheShowCache(cmd_args=None):
"""Display the watchdog log
"""
lldb_run_command('settings set max-string-summary-length 4096')
print('%s' % lldb_run_command('p/s mbwdog_logging').replace("\\n","\n"))