else:
print "{0: <#020x}".format(i)
+def iotrace_parse_Copt(Copt):
+ """Parses the -C option argument and returns a list of CPUs
+ """
+ cpusOpt = Copt
+ cpuList = cpusOpt.split(",")
+ chosen_cpus = []
+ for cpu_num_string in cpuList:
+ try:
+ if '-' in cpu_num_string:
+ parts = cpu_num_string.split('-')
+ if len(parts) != 2 or not (parts[0].isdigit() and parts[1].isdigit()):
+ raise ArgumentError("Invalid cpu specification: %s" % cpu_num_string)
+ firstRange = int(parts[0])
+ lastRange = int(parts[1])
+ if firstRange >= kern.globals.real_ncpus or lastRange >= kern.globals.real_ncpus:
+ raise ValueError()
+ if lastRange < firstRange:
+ raise ArgumentError("Invalid CPU range specified: `%s'" % cpu_num_string)
+ for cpu_num in range(firstRange, lastRange + 1):
+ if cpu_num not in chosen_cpus:
+ chosen_cpus.append(cpu_num)
+ else:
+ chosen_cpu = int(cpu_num_string)
+ if chosen_cpu < 0 or chosen_cpu >= kern.globals.real_ncpus:
+ raise ValueError()
+ if chosen_cpu not in chosen_cpus:
+ chosen_cpus.append(chosen_cpu)
+ except ValueError:
+ raise ArgumentError("Invalid CPU number specified. Valid range is 0..%d" % (kern.globals.real_ncpus - 1))
+
+ return chosen_cpus
+
+
+@lldb_command('iotrace', 'C:N:S:RB')
+def IOTrace_cmd(cmd_args=[], cmd_options={}):
+ """ Prints the iotrace ring buffers for all CPUs by default.
+ Arguments:
+ -B : Print backtraces for each ring entry
+ -C <cpuSpec#>[,...,<cpuSpec#N>] : Limit trace entries to those generated by the specified CPUs (each cpuSpec can be a
+ single CPU number or a range separated by a dash (e.g. "0-3"))
+ -N <count> : Limit output to the first <count> entries (across all chosen CPUs)
+ -R : Display results in reverse-sorted order (oldest first; default is newest-first)
+ -S <sort_key_field_name> : Sort output by specified iotrace_entry_t field name (instead of by timestamp)
+ """
+ IDX_CPU = 0
+ IDX_RINGPOS = 1
+ IDX_RINGENTRY = 2
+ MAX_IOTRACE_BACKTRACES = 16
+
+ if kern.arch != "x86_64":
+ print "Sorry, iotrace is an x86-only command."
+ return
+
+ if '-S' in cmd_options:
+ field_arg = cmd_options['-S']
+ try:
+ getattr(kern.globals.iotrace_ring[0][0], field_arg)
+ sort_key_field_name = field_arg
+ except AttributeError:
+ raise ArgumentError("Invalid sort key field name `%s'" % field_arg)
+ else:
+ sort_key_field_name = 'start_time_abs'
+
+ if '-C' in cmd_options:
+ chosen_cpus = iotrace_parse_Copt(cmd_options['-C'])
+ else:
+ chosen_cpus = [x for x in range(kern.globals.real_ncpus)]
+
+ try:
+ limit_output_count = int(cmd_options['-N'])
+ except ValueError:
+ raise ArgumentError("Invalid output count `%s'" % cmd_options['-N']);
+ except KeyError:
+ limit_output_count = None
+
+ reverse_sort = '-R' in cmd_options
+ backtraces = '-B' in cmd_options
+
+ # entries will be a list of 3-tuples, each holding the CPU on which the iotrace entry was collected,
+ # the original ring index, and the iotrace entry.
+ entries = []
+ for x in chosen_cpus:
+ ring_slice = [(x, y, kern.globals.iotrace_ring[x][y]) for y in range(kern.globals.iotrace_entries_per_cpu)]
+ entries.extend(ring_slice)
+
+ total_entries = len(entries)
+
+ entries.sort(key=lambda x: getattr(x[IDX_RINGENTRY], sort_key_field_name), reverse=reverse_sort)
+
+ if limit_output_count is not None and limit_output_count > total_entries:
+ print ("NOTE: Output count `%d' is too large; showing all %d entries" % (limit_output_count, total_entries));
+ limit_output_count = total_entries
+
+ if len(chosen_cpus) < kern.globals.real_ncpus:
+ print "NOTE: Limiting to entries from cpu%s %s" % ("s" if len(chosen_cpus) > 1 else "", str(chosen_cpus))
+
+ if limit_output_count is not None and limit_output_count < total_entries:
+ entries_to_display = limit_output_count
+ print "NOTE: Limiting to the %s" % ("first entry" if entries_to_display == 1 else ("first %d entries" % entries_to_display))
+ else:
+ entries_to_display = total_entries
+
+ print "%-19s %-8s %-10s %-20s SZ %-18s %-17s DATA" % (
+ "START TIME",
+ "DURATION",
+ "CPU#[RIDX]",
+ " TYPE",
+ " VIRT ADDR",
+ " PHYS ADDR")
+
+ for x in xrange(entries_to_display):
+ print "%-20u(%6u) %6s[%02d] %-20s %d 0x%016x 0x%016x 0x%x" % (
+ entries[x][IDX_RINGENTRY].start_time_abs,
+ entries[x][IDX_RINGENTRY].duration,
+ "CPU%d" % entries[x][IDX_CPU],
+ entries[x][IDX_RINGPOS],
+ str(entries[x][IDX_RINGENTRY].iotype).split("=")[1].strip(),
+ entries[x][IDX_RINGENTRY].size,
+ entries[x][IDX_RINGENTRY].vaddr,
+ entries[x][IDX_RINGENTRY].paddr,
+ entries[x][IDX_RINGENTRY].val)
+ if backtraces:
+ for btidx in range(MAX_IOTRACE_BACKTRACES):
+ nextbt = entries[x][IDX_RINGENTRY].backtrace[btidx]
+ if nextbt == 0:
+ break
+ print "\t" + GetSourceInformationForAddress(nextbt)
+
+
from memory import *
from ioreg import *
from mbufs import *
from net import *
+from skywalk import *
from kdp import *
from userspace import *
from pci import *
from structanalyze import *
from ipcimportancedetail import *
from bank import *
+from turnstile import *
from kasan import *
from kauth import *
from waitq import *
from pgtrace import *
from xnutriage import *
from kevent import *
+from workqueue import *
from ntstat import *
-
+from zonetriage import *