]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/lldbmacros/xnu.py
xnu-4903.270.47.tar.gz
[apple/xnu.git] / tools / lldbmacros / xnu.py
index 8b5d5bb1e29849e73c1bdfa46458b94e97983cf2..68800167846d8670beadb68280ca5687d225b06f 100755 (executable)
@@ -793,6 +793,135 @@ def WalkList(cmd_args=[], cmd_options={}):
         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 *
@@ -802,6 +931,7 @@ from pmap import *
 from ioreg import *
 from mbufs import *
 from net import *
+from skywalk import *
 from kdp import *
 from userspace import *
 from pci import *
@@ -812,6 +942,7 @@ from atm import *
 from structanalyze import *
 from ipcimportancedetail import *
 from bank import *
+from turnstile import *
 from kasan import *
 from kauth import *
 from waitq import *
@@ -820,5 +951,6 @@ from ktrace import *
 from pgtrace import *
 from xnutriage import *
 from kevent import *
+from workqueue import *
 from ntstat import *
-
+from zonetriage import *