2 from workqueue
import GetWorkqueueThreadRequestSummary
3 from memory
import vm_unpack_pointer
5 def IterateProcKqueues(proc
):
6 """ Iterate through all kqueues in the given process
10 returns: nothing, this is meant to be used as a generator function
11 kq - yields each kqueue in the process
13 for kqf
in IterateProcKqfiles(proc
):
14 yield kern
.GetValueFromAddress(int(kqf
), 'struct kqueue *')
15 if int(proc
.p_fd
.fd_wqkqueue
) != 0:
16 yield kern
.GetValueFromAddress(int(proc
.p_fd
.fd_wqkqueue
), 'struct kqueue *')
17 for kqwl
in IterateProcKqworkloops(proc
):
18 yield kern
.GetValueFromAddress(int(kqwl
), 'struct kqueue *')
20 def IterateProcKqfiles(proc
):
21 """ Iterate through all kqfiles in the given process
24 proc - the proc object
25 returns: nothing, this is meant to be used as a generator function
26 kqf - yields each kqfile in the process
30 proc_filedesc
= proc
.p_fd
31 proc_lastfile
= unsigned(proc_filedesc
.fd_lastfile
)
32 proc_ofiles
= proc_filedesc
.fd_ofiles
36 if unsigned(proc_ofiles
) == 0:
39 while count
<= proc_lastfile
:
40 if unsigned(proc_ofiles
[count
]) != 0:
41 proc_fd_flags
= proc_ofiles
[count
].fp_flags
42 proc_fd_fglob
= proc_ofiles
[count
].fp_glob
43 proc_fd_ftype
= unsigned(proc_fd_fglob
.fg_ops
.fo_type
)
44 if proc_fd_ftype
== xnudefines
.DTYPE_KQUEUE
:
45 yield kern
.GetValueFromAddress(int(proc_fd_fglob
.fg_data
), 'struct kqfile *')
48 def IterateProcKqworkloops(proc
):
49 """ Iterate through all kqworkloops in the given process
52 proc - the proc object
53 returns: nothing, this is meant to be used as a generator function
54 kqwl - yields each kqworkloop in the process
56 proc_filedesc
= proc
.p_fd
57 if int(proc_filedesc
.fd_kqhash
) == 0:
60 hash_mask
= proc_filedesc
.fd_kqhashmask
61 for i
in xrange(hash_mask
+ 1):
62 for kqwl
in IterateListEntry(proc_filedesc
.fd_kqhash
[i
], 'struct kqworkloop *', 'kqwl_hashlink'):
65 def IterateAllKqueues():
66 """ Iterate through all kqueues in the system
68 returns: nothing, this is meant to be used as a generator function
69 kq - yields each kqueue in the system
72 proc
= unsigned(t
.bsd_info
)
75 proc
= kern
.GetValueFromAddress(proc
, 'proc_t')
76 for kq
in IterateProcKqueues(proc
):
79 def IterateProcKnotes(proc
):
80 """ Iterate through all knotes in the given process
83 proc - the proc object
84 returns: nothing, this is meant to be used as a generator function
85 kn - yields each knote in the process
87 proc_filedesc
= proc
.p_fd
89 if int(proc
.p_fd
.fd_knlist
) != 0:
90 for i
in xrange(proc
.p_fd
.fd_knlistsize
):
91 for kn
in IterateListEntry(proc
.p_fd
.fd_knlist
[i
], 'struct knote *', 'kn_link', list_prefix
='s'):
93 if int(proc
.p_fd
.fd_knhash
) != 0:
94 for i
in xrange(proc
.p_fd
.fd_knhashmask
+ 1):
95 for kn
in IterateListEntry(proc
.p_fd
.fd_knhash
[i
], 'struct knote *', 'kn_link', list_prefix
='s'):
98 def GetKnoteKqueue(kn
):
99 """ Get the kqueue corresponding to a given knote
102 kn - the knote object
103 returns: kq - the kqueue corresponding to the knote
106 return vm_unpack_pointer(kn
.kn_kq_packed
, kern
.globals.kn_kq_packing_params
, 'struct kqueue *')
109 @lldb_type_summary(['knote *'])
110 @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'))
111 def GetKnoteSummary(kn
):
112 """ Summarizes a knote and related information
114 returns: str - summary of knote
116 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}'
117 state
= unsigned(kn
.kn_status
)
118 fops_str
= kern
.Symbolicate(kern
.globals.sysfilt_ops
[unsigned(kn
.kn_kevent
.kei_filtid
)])
119 qos_index
= int(kn
.kn_qos_index
)
123 qos_req
= int((kn
.kn_kevent
.kei_qos
& 0x003fff00) >> 8).bit_length()
124 return format_string
.format(
126 qos_req
=xnudefines
.thread_qos_short_strings
[qos_req
],
127 qos_use
=xnudefines
.thread_qos_short_strings
[qos_index
],
128 qos_ovr
=xnudefines
.thread_qos_short_strings
[int(kn
.kn_qos_override
)],
129 st_str
=xnudefines
.GetStateString(xnudefines
.kn_state_strings
, state
),
130 kq_ptr
=int(GetKnoteKqueue(kn
)),
133 @lldb_command('showknote', fancy
=True)
134 def ShowKnote(cmd_args
=None, cmd_options
={}, O
=None):
135 """ Show information about a knote
137 usage: showknote <struct knote *>
140 return O
.error('missing struct knote * argument')
142 kn
= kern
.GetValueFromAddress(cmd_args
[0], 'struct knote *')
143 with O
.table(GetKnoteSummary
.header
):
144 print GetKnoteSummary(kn
)
146 def IterateKqueueKnotes(kq
):
147 """ Iterate through all knotes of a given kqueue
150 kq - the kqueue to iterate the knotes of
151 returns: nothing, this is meant to be used as a generator function
152 kn - yields each knote in the kqueue
155 for kn
in IterateProcKnotes(proc
):
156 if unsigned(GetKnoteKqueue(kn
)) != unsigned(addressof(kq
)):
160 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}'
162 def GetServicer(req
):
163 if req
.tr_state
in [3, 4]: # [ BINDING , BOUND ]
164 return int(req
.tr_thread
)
167 @lldb_type_summary(['struct kqueue *'])
168 @header('{: <20s} {: <20s} {: <20s} {: <20s} {: <20s} {: <6s} {: <20s} {: <10s}'.format('kqueue', 'process', 'dynamic_id', 'servicer', 'owner', '#evts', 'wqs', 'state'))
169 def GetKqueueSummary(kq
):
170 """ Summarize kqueue information
173 kq - the kqueue object
174 returns: str - summary of kqueue
176 if kq
.kq_state
& xnudefines
.KQ_WORKLOOP
:
177 return GetKqworkloopSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqworkloop *'))
178 elif kq
.kq_state
& xnudefines
.KQ_WORKQ
:
179 return GetKqworkqSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqworkq *'))
181 return GetKqfileSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqfile *'))
183 @lldb_type_summary(['struct kqfile *'])
184 @header(GetKqueueSummary
.header
)
185 def GetKqfileSummary(kqf
):
186 kq
= kern
.GetValueFromAddress(int(kqf
), 'struct kqueue *')
187 state
= int(kq
.kq_state
)
188 return kqueue_summary_fmt
.format(
193 st_str
=xnudefines
.GetStateString(xnudefines
.kq_state_strings
, state
),
197 @lldb_command('showkqfile', fancy
=True)
198 def ShowKqfile(cmd_args
=None, cmd_options
={}, O
=None):
199 """ Display information about a kqfile object.
201 usage: showkqfile <struct kqfile *>
203 if len(cmd_args
) < 1:
204 return O
.error('missing struct kqfile * argument')
206 kqf
= kern
.GetValueFromAddress(cmd_args
[0], 'kqfile *')
208 with O
.table(GetKqfileSummary
.header
):
209 print GetKqfileSummary(kqf
)
210 with O
.table(GetKnoteSummary
.header
):
211 for kn
in IterateKqueueKnotes(kqf
.kqf_kqueue
):
212 print GetKnoteSummary(kn
)
213 for kn
in IterateTAILQ_HEAD(kqf
.kqf_suppressed
, 'kn_tqe'):
214 print GetKnoteSummary(kn
)
216 @lldb_type_summary(['struct kqworkq *'])
217 @header(GetKqueueSummary
.header
)
218 def GetKqworkqSummary(kqwq
):
219 """ Summarize workqueue kqueue information
222 kqwq - the kqworkq object
223 returns: str - summary of workqueue kqueue
225 return GetKqfileSummary(kern
.GetValueFromAddress(int(kqwq
), 'struct kqfile *'))
227 @lldb_command('showkqworkq', fancy
=True)
228 def ShowKqworkq(cmd_args
=None, cmd_options
={}, O
=None):
229 """ Display summary and knote information about a kqworkq.
231 usage: showkqworkq <struct kqworkq *>
233 if len(cmd_args
) < 1:
234 return O
.error('missing struct kqworkq * argument')
236 kqwq
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqworkq *')
237 kq
= kqwq
.kqwq_kqueue
238 with O
.table(GetKqueueSummary
.header
):
239 print GetKqworkqSummary(kqwq
)
241 with O
.table(GetWorkqueueThreadRequestSummary
.header
):
242 for i
in range(1, 8):
243 print GetWorkqueueThreadRequestSummary(kq
.kq_p
, kqwq
.kqwq_request
[i
])
245 with O
.table(GetKnoteSummary
.header
):
246 for kn
in IterateKqueueKnotes(kq
):
247 print GetKnoteSummary(kn
)
248 for i
in xrange(0, xnudefines
.KQWQ_NBUCKETS
):
249 for kn
in IterateTAILQ_HEAD(kq
.kq_queue
[i
], 'kn_tqe'):
250 print GetKnoteSummary(kn
)
252 @lldb_type_summary(['struct kqworkloop *'])
253 @header(GetKqueueSummary
.header
)
254 def GetKqworkloopSummary(kqwl
):
255 """ Summarize workloop kqueue information
258 kqwl - the kqworkloop object
259 returns: str - summary of workloop kqueue
261 state
= int(kqwl
.kqwl_kqueue
.kq_state
)
262 return kqueue_summary_fmt
.format(
265 wqs
=int(kqwl
.kqwl_kqueue
.kq_wqs
),
266 dyn_id
=kqwl
.kqwl_dynamicid
,
267 st_str
=xnudefines
.GetStateString(xnudefines
.kq_state_strings
, state
),
268 servicer
=GetServicer(kqwl
.kqwl_request
),
269 owner
=int(kqwl
.kqwl_owner
)
272 @lldb_command('showkqworkloop', fancy
=True)
273 def ShowKqworkloop(cmd_args
=None, cmd_options
={}, O
=None):
274 """ Display information about a kqworkloop.
276 usage: showkqworkloop <struct kqworkloop *>
278 if len(cmd_args
) < 1:
279 return O
.error('missing struct kqworkloop * argument')
281 kqwl
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqworkloop *')
283 with O
.table(GetKqworkloopSummary
.header
):
284 print GetKqworkloopSummary(kqwl
)
286 with O
.table(GetWorkqueueThreadRequestSummary
.header
):
287 print GetWorkqueueThreadRequestSummary(kqwl
.kqwl_kqueue
.kq_p
, kqwl
.kqwl_request
)
289 with O
.table(GetKnoteSummary
.header
):
290 for kn
in IterateKqueueKnotes(kqwl
.kqwl_kqueue
):
291 print GetKnoteSummary(kn
)
293 @lldb_command('showkqueue', fancy
=True)
294 def ShowKqueue(cmd_args
=None, cmd_options
={}, O
=None):
295 """ Given a struct kqueue pointer, display the summary of the kqueue
297 usage: showkqueue <struct kqueue *>
300 return O
.error('missing struct kqueue * argument')
302 kq
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqueue *')
303 if int(kq
.kq_state
) & xnudefines
.KQ_WORKQ
:
304 ShowKqworkq(cmd_args
, cmd_options
, O
)
305 elif int(kq
.kq_state
) & xnudefines
.KQ_WORKLOOP
:
306 ShowKqworkloop(cmd_args
, cmd_options
, O
)
308 ShowKqfile(cmd_args
, cmd_options
, O
)
310 @lldb_command('showprocworkqkqueue', fancy
=True)
311 def ShowProcWorkqKqueue(cmd_args
=None, cmd_options
={}, O
=None):
312 """ Show the workqueue kqueue for a given process.
314 usage: showprocworkqkqueue <proc_t>
317 return O
.error('missing struct proc * argument')
319 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
320 ShowKqworkq(cmd_args
=[str(int(proc
.p_fd
.fd_wqkqueue
))])
322 @lldb_command('showprockqueues', fancy
=True)
323 def ShowProcKqueues(cmd_args
=None, cmd_options
={}, O
=None):
324 """ Show the kqueues for a given process.
326 usage: showprockqueues <proc_t>
329 return O
.error('missing struct proc * argument')
331 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
333 with O
.table(GetKqueueSummary
.header
):
334 for kq
in IterateProcKqueues(proc
):
335 print GetKqueueSummary(kq
)
337 @lldb_command('showprocknotes', fancy
=True)
338 def ShowProcKnotes(cmd_args
=None, cmd_options
={}, O
=None):
339 """ Show the knotes for a given process.
341 usage: showprocknotes <proc_t>
345 return O
.error('missing struct proc * argument')
347 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
349 with O
.table(GetKnoteSummary
.header
):
350 for kn
in IterateProcKnotes(proc
):
351 print GetKnoteSummary(kn
)
353 @lldb_command('showallkqueues', fancy
=True)
354 def ShowAllKqueues(cmd_args
=None, cmd_options
={}, O
=None):
355 """ Display a summary of all the kqueues in the system
357 usage: showallkqueues
359 with O
.table(GetKqueueSummary
.header
):
360 for kq
in IterateAllKqueues():
361 print GetKqueueSummary(kq
)