X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d9a64523371fa019c4575bb400cbbc3a50ac9903..94ff46dc2849db4d43eaaf144872decc522aafb4:/tools/lldbmacros/kevent.py diff --git a/tools/lldbmacros/kevent.py b/tools/lldbmacros/kevent.py index 1fb875628..4c4e7d7e8 100755 --- a/tools/lldbmacros/kevent.py +++ b/tools/lldbmacros/kevent.py @@ -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 @@ -102,36 +104,41 @@ def GetKnoteKqueue(kn): 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 """ 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,42 +154,15 @@ def IterateKqueueKnotes(kq): continue yield kn -@lldb_type_summary(['struct kqrequest *']) -@header('{:<20s} {:<20s} {:<5s} {:<5s} {:<5s} {:s}'.format('kqrequest', 'thread', 'qos', 'ovr_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_thread: <#020x} {qos: <5s} {ovr_qos: <5s} {sa_qos: <5s} {state_str: - """ - 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 @@ -206,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 """ 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) @@ -242,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 """ 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) @@ -277,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_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 """ 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 """ 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 + usage: showprocworkqkqueue """ 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 """ 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 """ 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)