2 from workqueue
import GetWorkqueueThreadRequestSummary
4 def IterateProcKqueues(proc
):
5 """ Iterate through all kqueues in the given process
9 returns: nothing, this is meant to be used as a generator function
10 kq - yields each kqueue in the process
12 for kqf
in IterateProcKqfiles(proc
):
13 yield kern
.GetValueFromAddress(int(kqf
), 'struct kqueue *')
14 if int(proc
.p_fd
.fd_wqkqueue
) != 0:
15 yield kern
.GetValueFromAddress(int(proc
.p_fd
.fd_wqkqueue
), 'struct kqueue *')
16 for kqwl
in IterateProcKqworkloops(proc
):
17 yield kern
.GetValueFromAddress(int(kqwl
), 'struct kqueue *')
19 def IterateProcKqfiles(proc
):
20 """ Iterate through all kqfiles in the given process
23 proc - the proc object
24 returns: nothing, this is meant to be used as a generator function
25 kqf - yields each kqfile in the process
29 proc_filedesc
= proc
.p_fd
30 proc_lastfile
= unsigned(proc_filedesc
.fd_lastfile
)
31 proc_ofiles
= proc_filedesc
.fd_ofiles
35 if unsigned(proc_ofiles
) == 0:
38 while count
<= proc_lastfile
:
39 if unsigned(proc_ofiles
[count
]) != 0:
40 proc_fd_flags
= proc_ofiles
[count
].f_flags
41 proc_fd_fglob
= proc_ofiles
[count
].f_fglob
42 proc_fd_ftype
= unsigned(proc_fd_fglob
.fg_ops
.fo_type
)
43 if proc_fd_ftype
== xnudefines
.DTYPE_KQUEUE
:
44 yield kern
.GetValueFromAddress(int(proc_fd_fglob
.fg_data
), 'struct kqfile *')
47 def IterateProcKqworkloops(proc
):
48 """ Iterate through all kqworkloops in the given process
51 proc - the proc object
52 returns: nothing, this is meant to be used as a generator function
53 kqwl - yields each kqworkloop in the process
55 proc_filedesc
= proc
.p_fd
56 if int(proc_filedesc
.fd_kqhash
) == 0:
59 hash_mask
= proc_filedesc
.fd_kqhashmask
60 for i
in xrange(hash_mask
+ 1):
61 for kqwl
in IterateListEntry(proc_filedesc
.fd_kqhash
[i
], 'struct kqworkloop *', 'kqwl_hashlink'):
64 def IterateAllKqueues():
65 """ Iterate through all kqueues in the system
67 returns: nothing, this is meant to be used as a generator function
68 kq - yields each kqueue in the system
71 proc
= unsigned(t
.bsd_info
)
74 proc
= kern
.GetValueFromAddress(proc
, 'proc_t')
75 for kq
in IterateProcKqueues(proc
):
78 def IterateProcKnotes(proc
):
79 """ Iterate through all knotes in the given process
82 proc - the proc object
83 returns: nothing, this is meant to be used as a generator function
84 kn - yields each knote in the process
86 proc_filedesc
= proc
.p_fd
88 if int(proc
.p_fd
.fd_knlist
) != 0:
89 for i
in xrange(proc
.p_fd
.fd_knlistsize
):
90 for kn
in IterateListEntry(proc
.p_fd
.fd_knlist
[i
], 'struct knote *', 'kn_link', list_prefix
='s'):
92 if int(proc
.p_fd
.fd_knhash
) != 0:
93 for i
in xrange(proc
.p_fd
.fd_knhashmask
+ 1):
94 for kn
in IterateListEntry(proc
.p_fd
.fd_knhash
[i
], 'struct knote *', 'kn_link', list_prefix
='s'):
97 def GetKnoteKqueue(kn
):
98 """ Get the kqueue corresponding to a given knote
101 kn - the knote object
102 returns: kq - the kqueue corresponding to the knote
104 return kern
.GetValueFromAddress(int(kn
.kn_kq_packed
), 'struct kqueue *')
106 @lldb_type_summary(['knote *'])
107 @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'))
108 def GetKnoteSummary(kn
):
109 """ Summarizes a knote and related information
111 returns: str - summary of knote
113 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}'
114 state
= unsigned(kn
.kn_status
)
115 fops_str
= kern
.Symbolicate(kern
.globals.sysfilt_ops
[unsigned(kn
.kn_kevent
.kei_filtid
)])
116 qos_index
= int(kn
.kn_qos_index
)
120 qos_req
= int((kn
.kn_kevent
.kei_qos
& 0x003fff00) >> 8).bit_length()
121 return format_string
.format(
123 qos_req
=xnudefines
.thread_qos_short_strings
[qos_req
],
124 qos_use
=xnudefines
.thread_qos_short_strings
[qos_index
],
125 qos_ovr
=xnudefines
.thread_qos_short_strings
[int(kn
.kn_qos_override
)],
126 st_str
=xnudefines
.GetStateString(xnudefines
.kn_state_strings
, state
),
127 kq_ptr
=int(GetKnoteKqueue(kn
)),
130 @lldb_command('showknote', fancy
=True)
131 def ShowKnote(cmd_args
=None, cmd_options
={}, O
=None):
132 """ Show information about a knote
134 usage: showknote <struct knote *>
137 return O
.error('missing struct knote * argument')
139 kn
= kern
.GetValueFromAddress(cmd_args
[0], 'struct knote *')
140 with O
.table(GetKnoteSummary
.header
):
141 print GetKnoteSummary(kn
)
143 def IterateKqueueKnotes(kq
):
144 """ Iterate through all knotes of a given kqueue
147 kq - the kqueue to iterate the knotes of
148 returns: nothing, this is meant to be used as a generator function
149 kn - yields each knote in the kqueue
152 for kn
in IterateProcKnotes(proc
):
153 if unsigned(GetKnoteKqueue(kn
)) != unsigned(addressof(kq
)):
157 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}'
159 def GetServicer(req
):
160 if req
.tr_state
in [3, 4]: # [ BINDING , BOUND ]
161 return int(req
.tr_thread
)
164 @lldb_type_summary(['struct kqueue *'])
165 @header('{: <20s} {: <20s} {: <20s} {: <20s} {: <20s} {: <6s} {: <20s} {: <10s}'.format('kqueue', 'process', 'dynamic_id', 'servicer', 'owner', '#evts', 'wqs', 'state'))
166 def GetKqueueSummary(kq
):
167 """ Summarize kqueue information
170 kq - the kqueue object
171 returns: str - summary of kqueue
173 if kq
.kq_state
& xnudefines
.KQ_WORKLOOP
:
174 return GetKqworkloopSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqworkloop *'))
175 elif kq
.kq_state
& xnudefines
.KQ_WORKQ
:
176 return GetKqworkqSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqworkq *'))
178 return GetKqfileSummary(kern
.GetValueFromAddress(int(kq
), 'struct kqfile *'))
180 @lldb_type_summary(['struct kqfile *'])
181 @header(GetKqueueSummary
.header
)
182 def GetKqfileSummary(kqf
):
183 kq
= kern
.GetValueFromAddress(int(kqf
), 'struct kqueue *')
184 state
= int(kq
.kq_state
)
185 return kqueue_summary_fmt
.format(
190 st_str
=xnudefines
.GetStateString(xnudefines
.kq_state_strings
, state
),
194 @lldb_command('showkqfile', fancy
=True)
195 def ShowKqfile(cmd_args
=None, cmd_options
={}, O
=None):
196 """ Display information about a kqfile object.
198 usage: showkqfile <struct kqfile *>
200 if len(cmd_args
) < 1:
201 return O
.error('missing struct kqfile * argument')
203 kqf
= kern
.GetValueFromAddress(cmd_args
[0], 'kqfile *')
205 with O
.table(GetKqfileSummary
.header
):
206 print GetKqfileSummary(kqf
)
207 with O
.table(GetKnoteSummary
.header
):
208 for kn
in IterateKqueueKnotes(kqf
.kqf_kqueue
):
209 print GetKnoteSummary(kn
)
210 for kn
in IterateTAILQ_HEAD(kqf
.kqf_suppressed
, 'kn_tqe'):
211 print GetKnoteSummary(kn
)
213 @lldb_type_summary(['struct kqworkq *'])
214 @header(GetKqueueSummary
.header
)
215 def GetKqworkqSummary(kqwq
):
216 """ Summarize workqueue kqueue information
219 kqwq - the kqworkq object
220 returns: str - summary of workqueue kqueue
222 return GetKqfileSummary(kern
.GetValueFromAddress(int(kqwq
), 'struct kqfile *'))
224 @lldb_command('showkqworkq', fancy
=True)
225 def ShowKqworkq(cmd_args
=None, cmd_options
={}, O
=None):
226 """ Display summary and knote information about a kqworkq.
228 usage: showkqworkq <struct kqworkq *>
230 if len(cmd_args
) < 1:
231 return O
.error('missing struct kqworkq * argument')
233 kqwq
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqworkq *')
234 kq
= kqwq
.kqwq_kqueue
235 with O
.table(GetKqueueSummary
.header
):
236 print GetKqworkqSummary(kqwq
)
238 with O
.table(GetWorkqueueThreadRequestSummary
.header
):
239 for i
in range(1, 8):
240 print GetWorkqueueThreadRequestSummary(kq
.kq_p
, kqwq
.kqwq_request
[i
])
242 with O
.table(GetKnoteSummary
.header
):
243 for kn
in IterateKqueueKnotes(kq
):
244 print GetKnoteSummary(kn
)
245 for i
in xrange(0, xnudefines
.KQWQ_NBUCKETS
):
246 for kn
in IterateTAILQ_HEAD(kq
.kq_queue
[i
], 'kn_tqe'):
247 print GetKnoteSummary(kn
)
249 @lldb_type_summary(['struct kqworkloop *'])
250 @header(GetKqueueSummary
.header
)
251 def GetKqworkloopSummary(kqwl
):
252 """ Summarize workloop kqueue information
255 kqwl - the kqworkloop object
256 returns: str - summary of workloop kqueue
258 state
= int(kqwl
.kqwl_kqueue
.kq_state
)
259 return kqueue_summary_fmt
.format(
262 wqs
=int(kqwl
.kqwl_kqueue
.kq_wqs
),
263 dyn_id
=kqwl
.kqwl_dynamicid
,
264 st_str
=xnudefines
.GetStateString(xnudefines
.kq_state_strings
, state
),
265 servicer
=GetServicer(kqwl
.kqwl_request
),
266 owner
=int(kqwl
.kqwl_owner
)
269 @lldb_command('showkqworkloop', fancy
=True)
270 def ShowKqworkloop(cmd_args
=None, cmd_options
={}, O
=None):
271 """ Display information about a kqworkloop.
273 usage: showkqworkloop <struct kqworkloop *>
275 if len(cmd_args
) < 1:
276 return O
.error('missing struct kqworkloop * argument')
278 kqwl
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqworkloop *')
280 with O
.table(GetKqworkloopSummary
.header
):
281 print GetKqworkloopSummary(kqwl
)
283 with O
.table(GetWorkqueueThreadRequestSummary
.header
):
284 print GetWorkqueueThreadRequestSummary(kqwl
.kqwl_kqueue
.kq_p
, kqwl
.kqwl_request
)
286 with O
.table(GetKnoteSummary
.header
):
287 for kn
in IterateKqueueKnotes(kqwl
.kqwl_kqueue
):
288 print GetKnoteSummary(kn
)
290 @lldb_command('showkqueue', fancy
=True)
291 def ShowKqueue(cmd_args
=None, cmd_options
={}, O
=None):
292 """ Given a struct kqueue pointer, display the summary of the kqueue
294 usage: showkqueue <struct kqueue *>
297 return O
.error('missing struct kqueue * argument')
299 kq
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqueue *')
300 if int(kq
.kq_state
) & xnudefines
.KQ_WORKQ
:
301 ShowKqworkq(cmd_args
, cmd_options
, O
)
302 elif int(kq
.kq_state
) & xnudefines
.KQ_WORKLOOP
:
303 ShowKqworkloop(cmd_args
, cmd_options
, O
)
305 ShowKqfile(cmd_args
, cmd_options
, O
)
307 @lldb_command('showprocworkqkqueue', fancy
=True)
308 def ShowProcWorkqKqueue(cmd_args
=None, cmd_options
={}, O
=None):
309 """ Show the workqueue kqueue for a given process.
311 usage: showprocworkqkqueue <proc_t>
314 return O
.error('missing struct proc * argument')
316 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
317 ShowKqworkq(cmd_args
=[str(int(proc
.p_fd
.fd_wqkqueue
))])
319 @lldb_command('showprockqueues', fancy
=True)
320 def ShowProcKqueues(cmd_args
=None, cmd_options
={}, O
=None):
321 """ Show the kqueues for a given process.
323 usage: showprockqueues <proc_t>
326 return O
.error('missing struct proc * argument')
328 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
330 with O
.table(GetKqueueSummary
.header
):
331 for kq
in IterateProcKqueues(proc
):
332 print GetKqueueSummary(kq
)
334 @lldb_command('showprocknotes', fancy
=True)
335 def ShowProcKnotes(cmd_args
=None, cmd_options
={}, O
=None):
336 """ Show the knotes for a given process.
338 usage: showprocknotes <proc_t>
342 return O
.error('missing struct proc * argument')
344 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
346 with O
.table(GetKnoteSummary
.header
):
347 for kn
in IterateProcKnotes(proc
):
348 print GetKnoteSummary(kn
)
350 @lldb_command('showallkqueues', fancy
=True)
351 def ShowAllKqueues(cmd_args
=None, cmd_options
={}, O
=None):
352 """ Display a summary of all the kqueues in the system
354 usage: showallkqueues
356 with O
.table(GetKqueueSummary
.header
):
357 for kq
in IterateAllKqueues():
358 print GetKqueueSummary(kq
)