]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/lldbmacros/kevent.py
xnu-6153.41.3.tar.gz
[apple/xnu.git] / tools / lldbmacros / kevent.py
index 8f9f7c9513d7d2d1d1fe04991a576930a5d2ce5a..4c4e7d7e82f785dc5a3dbcd5606ee62e7225948f 100755 (executable)
@@ -1,4 +1,5 @@
 from xnu import *
+from workqueue import GetWorkqueueThreadRequestSummary
 
 def IterateProcKqueues(proc):
     """ Iterate through all kqueues in the given process
@@ -57,7 +58,7 @@ def IterateProcKqworkloops(proc):
 
     hash_mask = proc_filedesc.fd_kqhashmask
     for i in xrange(hash_mask + 1):
-        for kqwl in IterateListEntry(proc_filedesc.fd_kqhash[i], 'struct kqworkloop *', 'kqwl_hashlink', list_prefix='s'):
+        for kqwl in IterateListEntry(proc_filedesc.fd_kqhash[i], 'struct kqworkloop *', 'kqwl_hashlink'):
             yield kqwl
 
 def IterateAllKqueues():
@@ -67,9 +68,10 @@ def IterateAllKqueues():
             kq - yields each kqueue in the system
     """
     for t in kern.tasks:
-        if unsigned(t.bsd_info) == 0:
+        proc = unsigned(t.bsd_info)
+        if proc == 0:
             continue
-        proc = kern.GetValueFromAddress(t.bsd_info, 'proc_t')
+        proc = kern.GetValueFromAddress(proc, 'proc_t')
         for kq in IterateProcKqueues(proc):
             yield kq
 
@@ -99,39 +101,44 @@ def GetKnoteKqueue(kn):
             kn - the knote object
         returns: kq - the kqueue corresponding to the knote
     """
-    return kern.GetValueFromAddress(kn.kn_kq_packed + kern.VM_MIN_KERNEL_AND_KEXT_ADDRESS, 'struct kqueue *')
+    return kern.GetValueFromAddress(int(kn.kn_kq_packed), 'struct kqueue *')
 
 @lldb_type_summary(['knote *'])
-@header('{:<20s} {:<20s} {:<10s} {:<20s} {:<20s} {:<30s} {:<10} {:<10} {:<10} {:<30s}'.format('knote', 'ident', 'kev_flags', 'kqueue', 'udata', 'filtops', 'qos_use', 'qos_req', 'qos_ovr', 'status'))
+@header('{:<20s} {:<20s} {:<10s} {:<20s} {:<20s} {:<30s} {:<10} {:<10} {:<10} {:<20s}'.format('knote', 'ident', 'kev_flags', 'kqueue', 'udata', 'filtops', 'qos_req', 'qos_use', 'qos_ovr', 'status'))
 def GetKnoteSummary(kn):
     """ Summarizes a knote and related information
 
         returns: str - summary of knote
     """
-    format_string = '{o: <#020x} {o.kn_kevent.ident: <#020x} {o.kn_kevent.flags: <#010x} {kq_ptr: <#020x} {o.kn_kevent.udata: <#020x} {ops_str: <30s} {qos_use: <10s} {qos_req: <10s} {qos_ovr: <10s} {st_str: <30s}'
+    format_string = '{o: <#020x} {o.kn_kevent.kei_ident: <#020x} {o.kn_kevent.kei_flags: <#010x} {kq_ptr: <#020x} {o.kn_kevent.kei_udata: <#020x} {ops_str: <30s} {qos_req: <10s} {qos_use: <10s} {qos_ovr: <10s} {st_str: <20s}'
     state = unsigned(kn.kn_status)
-    fops_str = kern.Symbolicate(kern.globals.sysfilt_ops[unsigned(kn.kn_filtid)])
+    fops_str = kern.Symbolicate(kern.globals.sysfilt_ops[unsigned(kn.kn_kevent.kei_filtid)])
+    qos_index = int(kn.kn_qos_index)
+    if qos_index > 6:
+        qos_req = qos_index
+    else:
+        qos_req = int((kn.kn_kevent.kei_qos & 0x003fff00) >> 8).bit_length()
     return format_string.format(
             o=kn,
-            qos_use=xnudefines.thread_qos_short_strings[int(kn.kn_qos_index)],
-            qos_req=xnudefines.thread_qos_short_strings[int(kn.kn_req_index)],
+            qos_req=xnudefines.thread_qos_short_strings[qos_req],
+            qos_use=xnudefines.thread_qos_short_strings[qos_index],
             qos_ovr=xnudefines.thread_qos_short_strings[int(kn.kn_qos_override)],
             st_str=xnudefines.GetStateString(xnudefines.kn_state_strings, state),
             kq_ptr=int(GetKnoteKqueue(kn)),
             ops_str=fops_str)
 
-@lldb_command('showknote')
-def ShowKnote(cmd_args=None):
+@lldb_command('showknote', fancy=True)
+def ShowKnote(cmd_args=None, cmd_options={}, O=None):
     """ Show information about a knote
 
         usage: showknote <struct knote *>
     """
     if not cmd_args:
-        raise ArgumentError('missing struct knote * argument')
+        return O.error('missing struct knote * argument')
 
     kn = kern.GetValueFromAddress(cmd_args[0], 'struct knote *')
-    print GetKnoteSummary.header
-    print GetKnoteSummary(kn)
+    with O.table(GetKnoteSummary.header):
+        print GetKnoteSummary(kn)
 
 def IterateKqueueKnotes(kq):
     """ Iterate through all knotes of a given kqueue
@@ -147,43 +154,15 @@ def IterateKqueueKnotes(kq):
             continue
         yield kn
 
-@lldb_type_summary(['struct kqrequest *'])
-@header('{:<20s} {:<20s} {:<5s} {:<5s} {:<5s} {:<5s} {:s}'.format('kqrequest', 'thread', 'qos', 'ovr_qos', 'w_qos', 'sa_qos', 'state'))
-def GetKqrequestSummary(kqr):
-    """ Summarize kqrequest information
-
-        params:
-            kqr - the kqrequest object
-        returns: str - summary of kqrequest
-    """
-    fmt = '{kqrp: <#020x} {kqr.kqr_bound.kqrb_thread: <#020x} {qos: <5s} {ovr_qos: <5s} {w_qos: <5s} {sa_qos: <5s} {state_str:<s}'
-    return fmt.format(kqrp=int(kqr),
-            kqr=kqr,
-            qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_qos_index)],
-            ovr_qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_override_index)],
-            w_qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_dsync_waiters_qos)],
-            sa_qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_stayactive_qos)],
-            state_str=xnudefines.GetStateString(xnudefines.kqrequest_state_strings, kqr.kqr_state))
-
-@lldb_command('showkqrequest')
-def ShowKqrequest(cmd_args=None):
-    """ Display information about a kqrequest object.
-
-        usage: showkqrequest <struct kqrequest *>
-    """
-    if len(cmd_args) < 1:
-        raise ArgumentError('missing struct kqrequest * argument')
-    kqr = kern.GetValueFromAddress(cmd_args[0], 'struct kqrequest *')
-    print GetKqrequestSummary.header
-    print GetKqrequestSummary(kqr)
-    print GetKnoteSummary.header
-    for kn in IterateTAILQ_HEAD(kqr.kqr_suppressed, 'kn_tqe'):
-        print GetKnoteSummary(kn)
+kqueue_summary_fmt = '{ptr: <#020x} {o.kq_p: <#020x} {dyn_id: <#020x} {servicer: <#20x} {owner: <#20x} {o.kq_count: <6d} {wqs: <#020x} {st_str: <10s}'
 
-kqueue_summary_fmt = '{ptr: <#020x} {o.kq_p: <#020x} {dyn_id: <#020x} {servicer: <#20x} {owner: <#20x} {o.kq_count: <6d} {wqs: <#020x} {kqr_state: <30s} {st_str: <10s}'
+def GetServicer(req):
+    if req.tr_state in [3, 4]: # [ BINDING , BOUND ]
+        return int(req.tr_thread)
+    return 0
 
 @lldb_type_summary(['struct kqueue *'])
-@header('{: <20s} {: <20s} {: <20s} {: <20s} {: <20s} {: <6s} {: <20s} {: <30s} {: <10s}'.format('kqueue', 'process', 'dynamic_id', 'servicer', 'owner', '#evts', 'wqs', 'request', 'state'))
+@header('{: <20s} {: <20s} {: <20s} {: <20s} {: <20s} {: <6s} {: <20s} {: <10s}'.format('kqueue', 'process', 'dynamic_id', 'servicer', 'owner', '#evts', 'wqs', 'state'))
 def GetKqueueSummary(kq):
     """ Summarize kqueue information
 
@@ -207,30 +186,29 @@ def GetKqfileSummary(kqf):
             o=kq,
             ptr=int(kq),
             wqs=int(kq.kq_wqs),
-            kqr_state='',
             dyn_id=0,
             st_str=xnudefines.GetStateString(xnudefines.kq_state_strings, state),
             servicer=0,
             owner=0)
 
-@lldb_command('showkqfile')
-def ShowKqfile(cmd_args=None):
+@lldb_command('showkqfile', fancy=True)
+def ShowKqfile(cmd_args=None, cmd_options={}, O=None):
     """ Display information about a kqfile object.
 
         usage: showkqfile <struct kqfile *>
     """
     if len(cmd_args) < 1:
-        raise ArgumentError('missing struct kqfile * argument')
+        return O.error('missing struct kqfile * argument')
 
     kqf = kern.GetValueFromAddress(cmd_args[0], 'kqfile *')
 
-    print GetKqfileSummary.header
-    print GetKqfileSummary(kqf)
-    print GetKnoteSummary.header
-    for kn in IterateKqueueKnotes(kqf.kqf_kqueue):
-        print GetKnoteSummary(kn)
-    for kn in IterateTAILQ_HEAD(kqf.kqf_suppressed, 'kn_tqe'):
-        print GetKnoteSummary(kn)
+    with O.table(GetKqfileSummary.header):
+        print GetKqfileSummary(kqf)
+    with O.table(GetKnoteSummary.header):
+        for kn in IterateKqueueKnotes(kqf.kqf_kqueue):
+            print GetKnoteSummary(kn)
+        for kn in IterateTAILQ_HEAD(kqf.kqf_suppressed, 'kn_tqe'):
+            print GetKnoteSummary(kn)
 
 @lldb_type_summary(['struct kqworkq *'])
 @header(GetKqueueSummary.header)
@@ -243,25 +221,30 @@ def GetKqworkqSummary(kqwq):
     """
     return GetKqfileSummary(kern.GetValueFromAddress(int(kqwq), 'struct kqfile *'))
 
-@lldb_command('showkqworkq')
-def ShowKqworkq(cmd_args=None):
+@lldb_command('showkqworkq', fancy=True)
+def ShowKqworkq(cmd_args=None, cmd_options={}, O=None):
     """ Display summary and knote information about a kqworkq.
 
         usage: showkqworkq <struct kqworkq *>
     """
     if len(cmd_args) < 1:
-        raise ArgumentError('missing struct kqworkq * argument')
+        return O.error('missing struct kqworkq * argument')
 
     kqwq = kern.GetValueFromAddress(cmd_args[0], 'struct kqworkq *')
     kq = kqwq.kqwq_kqueue
-    print GetKqueueSummary.header
-    print GetKqworkqSummary(kqwq)
-    print GetKnoteSummary.header
-    for kn in IterateKqueueKnotes(kq):
-        print GetKnoteSummary(kn)
-    for i in xrange(0, xnudefines.KQWQ_NBUCKETS):
-        for kn in IterateTAILQ_HEAD(kq.kq_queue[i], 'kn_tqe'):
+    with O.table(GetKqueueSummary.header):
+        print GetKqworkqSummary(kqwq)
+
+    with O.table(GetWorkqueueThreadRequestSummary.header):
+        for i in range(1, 8):
+            print GetWorkqueueThreadRequestSummary(kq.kq_p, kqwq.kqwq_request[i])
+
+    with O.table(GetKnoteSummary.header):
+        for kn in IterateKqueueKnotes(kq):
             print GetKnoteSummary(kn)
+        for i in xrange(0, xnudefines.KQWQ_NBUCKETS):
+            for kn in IterateTAILQ_HEAD(kq.kq_queue[i], 'kn_tqe'):
+                print GetKnoteSummary(kn)
 
 @lldb_type_summary(['struct kqworkloop *'])
 @header(GetKqueueSummary.header)
@@ -278,104 +261,98 @@ def GetKqworkloopSummary(kqwl):
             o=kqwl.kqwl_kqueue,
             wqs=int(kqwl.kqwl_kqueue.kq_wqs),
             dyn_id=kqwl.kqwl_dynamicid,
-            kqr_state=xnudefines.GetStateString(xnudefines.kqrequest_state_strings, kqwl.kqwl_request.kqr_state),
             st_str=xnudefines.GetStateString(xnudefines.kq_state_strings, state),
-            servicer=int(kqwl.kqwl_request.kqr_bound.kqrb_thread),
+            servicer=GetServicer(kqwl.kqwl_request),
             owner=int(kqwl.kqwl_owner)
             )
 
-@lldb_command('showkqworkloop')
-def ShowKqworkloop(cmd_args=None):
+@lldb_command('showkqworkloop', fancy=True)
+def ShowKqworkloop(cmd_args=None, cmd_options={}, O=None):
     """ Display information about a kqworkloop.
 
         usage: showkqworkloop <struct kqworkloop *>
     """
     if len(cmd_args) < 1:
-        raise ArgumentError('missing struct kqworkloop * argument')
+        return O.error('missing struct kqworkloop * argument')
 
     kqwl = kern.GetValueFromAddress(cmd_args[0], 'struct kqworkloop *')
 
-    print GetKqworkloopSummary.header
-    print GetKqworkloopSummary(kqwl)
+    with O.table(GetKqworkloopSummary.header):
+        print GetKqworkloopSummary(kqwl)
 
-    print GetKqrequestSummary.header
-    kqr = kern.GetValueFromAddress(unsigned(addressof(kqwl.kqwl_request)), 'struct kqrequest *')
-    print GetKqrequestSummary(kqr)
+    with O.table(GetWorkqueueThreadRequestSummary.header):
+        print GetWorkqueueThreadRequestSummary(kqwl.kqwl_kqueue.kq_p, kqwl.kqwl_request)
 
-    print GetKnoteSummary.header
-    for kn in IterateKqueueKnotes(kqwl.kqwl_kqueue):
-        print GetKnoteSummary(kn)
+    with O.table(GetKnoteSummary.header):
+        for kn in IterateKqueueKnotes(kqwl.kqwl_kqueue):
+            print GetKnoteSummary(kn)
 
-@lldb_command('showkqueue')
-def ShowKqueue(cmd_args=None):
+@lldb_command('showkqueue', fancy=True)
+def ShowKqueue(cmd_args=None, cmd_options={}, O=None):
     """ Given a struct kqueue pointer, display the summary of the kqueue
 
         usage: showkqueue <struct kqueue *>
     """
     if not cmd_args:
-        raise ArgumentError('missing struct kqueue * argument')
+        return O.error('missing struct kqueue * argument')
 
     kq = kern.GetValueFromAddress(cmd_args[0], 'struct kqueue *')
     if int(kq.kq_state) & xnudefines.KQ_WORKQ:
-        ShowKqworkq(cmd_args=[str(int(kq))])
+        ShowKqworkq(cmd_args, cmd_options, O)
     elif int(kq.kq_state) & xnudefines.KQ_WORKLOOP:
-        ShowKqworkloop(cmd_args=[str(int(kq))])
+        ShowKqworkloop(cmd_args, cmd_options, O)
     else:
-        print GetKqueueSummary.header
-        print GetKqueueSummary(kq)
-        print GetKnoteSummary.header
-        for kn in IterateKqueueKnotes(kq):
-            print GetKnoteSummary(kn)
+        ShowKqfile(cmd_args, cmd_options, O)
 
-@lldb_command('showprocworkqkqueue')
-def ShowProcWorkqKqueue(cmd_args=None):
+@lldb_command('showprocworkqkqueue', fancy=True)
+def ShowProcWorkqKqueue(cmd_args=None, cmd_options={}, O=None):
     """ Show the workqueue kqueue for a given process.
 
-        usage: showworkqkqueue <proc_t>
+        usage: showprocworkqkqueue <proc_t>
     """
     if not cmd_args:
-        raise ArgumentError('missing struct proc * argument')
+        return O.error('missing struct proc * argument')
 
     proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
     ShowKqworkq(cmd_args=[str(int(proc.p_fd.fd_wqkqueue))])
 
-@lldb_command('showprockqueues')
-def ShowProcKqueues(cmd_args=None):
+@lldb_command('showprockqueues', fancy=True)
+def ShowProcKqueues(cmd_args=None, cmd_options={}, O=None):
     """ Show the kqueues for a given process.
 
         usage: showprockqueues <proc_t>
     """
     if not cmd_args:
-        raise ArgumentError('missing struct proc * argument')
+        return O.error('missing struct proc * argument')
 
     proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
 
-    print GetKqueueSummary.header
-    for kq in IterateProcKqueues(proc):
-        print GetKqueueSummary(kq)
+    with O.table(GetKqueueSummary.header):
+        for kq in IterateProcKqueues(proc):
+            print GetKqueueSummary(kq)
 
-@lldb_command('showprocknotes')
-def ShowProcKnotes(cmd_args=None):
+@lldb_command('showprocknotes', fancy=True)
+def ShowProcKnotes(cmd_args=None, cmd_options={}, O=None):
     """ Show the knotes for a given process.
 
         usage: showprocknotes <proc_t>
     """
 
     if not cmd_args:
-        raise ArgumentError('missing struct proc * argument')
+        return O.error('missing struct proc * argument')
 
     proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
 
-    print GetKnoteSummary.header
-    for kn in IterateProcKnotes(proc):
-        print GetKnoteSummary(kn)
+    with O.table(GetKnoteSummary.header):
+        for kn in IterateProcKnotes(proc):
+            print GetKnoteSummary(kn)
 
-@lldb_command('showallkqueues')
-def ShowAllKqueues(cmd_args=[], cmd_options={}):
+@lldb_command('showallkqueues', fancy=True)
+def ShowAllKqueues(cmd_args=None, cmd_options={}, O=None):
     """ Display a summary of all the kqueues in the system
 
         usage: showallkqueues
     """
-    print GetKqueueSummary.header
-    for kq in IterateAllKqueues():
-        print GetKqueueSummary(kq)
+    with O.table(GetKqueueSummary.header):
+        for kq in IterateAllKqueues():
+            print GetKqueueSummary(kq)