+# Count the vouchers in a given task's ipc space
+@header("{: <20s} {: <6s} {: <12s} {: <8s}".format("task", "pid", "name", "#vouchers"))
+def GetTaskVoucherCount(t):
+ space = t.itk_space
+ is_tableval = space.is_table
+ num_entries = int(space.is_table_size)
+ count = 0
+ for index in range (0, num_entries):
+ entryval = GetObjectAtIndexFromArray(is_tableval, index)
+ entry_ie_bits = unsigned(entryval.ie_bits)
+ if (int(entry_ie_bits) & 0x00070000 ) != 0:
+ port = Cast(entryval.ie_object, 'ipc_port_t')
+ if int(port.ip_object.io_bits) & 0x800 :
+ # Is kObject
+ io_bits = unsigned(port.ip_object.io_bits)
+ objtype_index = io_bits & 0x3ff
+ if objtype_index < len(xnudefines.kobject_types) :
+ objtype_str = xnudefines.kobject_types[objtype_index]
+ if objtype_str == "VOUCHER":
+ count += 1
+ format_str = "{: <#020x} {: <6d} {: <12s} {: <8d}"
+ pval = Cast(t.bsd_info, 'proc *')
+ return format_str.format(t, pval.p_pid, GetProcNameForTask(t), count)
+
+# Macro: countallvouchers
+@lldb_command('countallvouchers', fancy=True)
+def CountAllVouchers(cmd_args=None, cmd_options={}, O=None):
+ """ Routine to count the number of vouchers by task. Useful for finding leaks.
+ Usage: countallvouchers
+ """
+
+ with O.table(GetTaskVoucherCount.header):
+ for t in kern.tasks:
+ print(GetTaskVoucherCount(t))
+