]> git.saurik.com Git - apple/xnu.git/blame - tools/lldbmacros/kevent.py
xnu-4903.270.47.tar.gz
[apple/xnu.git] / tools / lldbmacros / kevent.py
CommitLineData
5ba3f43e
A
1from xnu import *
2
3def IterateProcKqueues(proc):
4 """ Iterate through all kqueues in the given process
5
6 params:
7 proc - the proc object
8 returns: nothing, this is meant to be used as a generator function
9 kq - yields each kqueue in the process
10 """
11 for kqf in IterateProcKqfiles(proc):
12 yield kern.GetValueFromAddress(int(kqf), 'struct kqueue *')
13 if int(proc.p_fd.fd_wqkqueue) != 0:
14 yield kern.GetValueFromAddress(int(proc.p_fd.fd_wqkqueue), 'struct kqueue *')
15 for kqwl in IterateProcKqworkloops(proc):
16 yield kern.GetValueFromAddress(int(kqwl), 'struct kqueue *')
17
18def IterateProcKqfiles(proc):
19 """ Iterate through all kqfiles in the given process
20
21 params:
22 proc - the proc object
23 returns: nothing, this is meant to be used as a generator function
24 kqf - yields each kqfile in the process
25 """
26 filetype_KQUEUE = 5
27
28 proc_filedesc = proc.p_fd
29 proc_lastfile = unsigned(proc_filedesc.fd_lastfile)
30 proc_ofiles = proc_filedesc.fd_ofiles
31 queues = list()
32 count = 0
33
34 if unsigned(proc_ofiles) == 0:
35 return
36
37 while count <= proc_lastfile:
38 if unsigned(proc_ofiles[count]) != 0:
39 proc_fd_flags = proc_ofiles[count].f_flags
40 proc_fd_fglob = proc_ofiles[count].f_fglob
41 proc_fd_ftype = unsigned(proc_fd_fglob.fg_ops.fo_type)
42 if proc_fd_ftype == xnudefines.DTYPE_KQUEUE:
43 yield kern.GetValueFromAddress(int(proc_fd_fglob.fg_data), 'struct kqfile *')
44 count += 1
45
46def IterateProcKqworkloops(proc):
47 """ Iterate through all kqworkloops in the given process
48
49 params:
50 proc - the proc object
51 returns: nothing, this is meant to be used as a generator function
52 kqwl - yields each kqworkloop in the process
53 """
54 proc_filedesc = proc.p_fd
55 if int(proc_filedesc.fd_kqhash) == 0:
56 return
57
58 hash_mask = proc_filedesc.fd_kqhashmask
59 for i in xrange(hash_mask + 1):
60 for kqwl in IterateListEntry(proc_filedesc.fd_kqhash[i], 'struct kqworkloop *', 'kqwl_hashlink', list_prefix='s'):
61 yield kqwl
62
63def IterateAllKqueues():
64 """ Iterate through all kqueues in the system
65
66 returns: nothing, this is meant to be used as a generator function
67 kq - yields each kqueue in the system
68 """
69 for t in kern.tasks:
70 if unsigned(t.bsd_info) == 0:
71 continue
72 proc = kern.GetValueFromAddress(t.bsd_info, 'proc_t')
73 for kq in IterateProcKqueues(proc):
74 yield kq
75
76def IterateProcKnotes(proc):
77 """ Iterate through all knotes in the given process
78
79 params:
80 proc - the proc object
81 returns: nothing, this is meant to be used as a generator function
82 kn - yields each knote in the process
83 """
84 proc_filedesc = proc.p_fd
85
86 if int(proc.p_fd.fd_knlist) != 0:
87 for i in xrange(proc.p_fd.fd_knlistsize):
88 for kn in IterateListEntry(proc.p_fd.fd_knlist[i], 'struct knote *', 'kn_link', list_prefix='s'):
89 yield kn
90 if int(proc.p_fd.fd_knhash) != 0:
91 for i in xrange(proc.p_fd.fd_knhashmask + 1):
92 for kn in IterateListEntry(proc.p_fd.fd_knhash[i], 'struct knote *', 'kn_link', list_prefix='s'):
93 yield kn
94
95def GetKnoteKqueue(kn):
96 """ Get the kqueue corresponding to a given knote
97
98 params:
99 kn - the knote object
100 returns: kq - the kqueue corresponding to the knote
101 """
d9a64523 102 return kern.GetValueFromAddress(int(kn.kn_kq_packed), 'struct kqueue *')
5ba3f43e
A
103
104@lldb_type_summary(['knote *'])
105@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'))
106def GetKnoteSummary(kn):
107 """ Summarizes a knote and related information
108
109 returns: str - summary of knote
110 """
111 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}'
112 state = unsigned(kn.kn_status)
113 fops_str = kern.Symbolicate(kern.globals.sysfilt_ops[unsigned(kn.kn_filtid)])
114 return format_string.format(
115 o=kn,
116 qos_use=xnudefines.thread_qos_short_strings[int(kn.kn_qos_index)],
117 qos_req=xnudefines.thread_qos_short_strings[int(kn.kn_req_index)],
118 qos_ovr=xnudefines.thread_qos_short_strings[int(kn.kn_qos_override)],
119 st_str=xnudefines.GetStateString(xnudefines.kn_state_strings, state),
120 kq_ptr=int(GetKnoteKqueue(kn)),
121 ops_str=fops_str)
122
123@lldb_command('showknote')
124def ShowKnote(cmd_args=None):
125 """ Show information about a knote
126
127 usage: showknote <struct knote *>
128 """
129 if not cmd_args:
130 raise ArgumentError('missing struct knote * argument')
131
132 kn = kern.GetValueFromAddress(cmd_args[0], 'struct knote *')
133 print GetKnoteSummary.header
134 print GetKnoteSummary(kn)
135
136def IterateKqueueKnotes(kq):
137 """ Iterate through all knotes of a given kqueue
138
139 params:
140 kq - the kqueue to iterate the knotes of
141 returns: nothing, this is meant to be used as a generator function
142 kn - yields each knote in the kqueue
143 """
144 proc = kq.kq_p
145 for kn in IterateProcKnotes(proc):
146 if unsigned(GetKnoteKqueue(kn)) != unsigned(addressof(kq)):
147 continue
148 yield kn
149
150@lldb_type_summary(['struct kqrequest *'])
d9a64523 151@header('{:<20s} {:<20s} {:<5s} {:<5s} {:<5s} {:s}'.format('kqrequest', 'thread', 'qos', 'ovr_qos', 'sa_qos', 'state'))
5ba3f43e
A
152def GetKqrequestSummary(kqr):
153 """ Summarize kqrequest information
154
155 params:
156 kqr - the kqrequest object
157 returns: str - summary of kqrequest
158 """
d9a64523 159 fmt = '{kqrp: <#020x} {kqr.kqr_thread: <#020x} {qos: <5s} {ovr_qos: <5s} {sa_qos: <5s} {state_str:<s}'
5ba3f43e
A
160 return fmt.format(kqrp=int(kqr),
161 kqr=kqr,
162 qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_qos_index)],
163 ovr_qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_override_index)],
5ba3f43e
A
164 sa_qos=xnudefines.thread_qos_short_strings[int(kqr.kqr_stayactive_qos)],
165 state_str=xnudefines.GetStateString(xnudefines.kqrequest_state_strings, kqr.kqr_state))
166
167@lldb_command('showkqrequest')
168def ShowKqrequest(cmd_args=None):
169 """ Display information about a kqrequest object.
170
171 usage: showkqrequest <struct kqrequest *>
172 """
173 if len(cmd_args) < 1:
174 raise ArgumentError('missing struct kqrequest * argument')
175 kqr = kern.GetValueFromAddress(cmd_args[0], 'struct kqrequest *')
176 print GetKqrequestSummary.header
177 print GetKqrequestSummary(kqr)
178 print GetKnoteSummary.header
179 for kn in IterateTAILQ_HEAD(kqr.kqr_suppressed, 'kn_tqe'):
180 print GetKnoteSummary(kn)
181
182kqueue_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}'
183
184@lldb_type_summary(['struct kqueue *'])
185@header('{: <20s} {: <20s} {: <20s} {: <20s} {: <20s} {: <6s} {: <20s} {: <30s} {: <10s}'.format('kqueue', 'process', 'dynamic_id', 'servicer', 'owner', '#evts', 'wqs', 'request', 'state'))
186def GetKqueueSummary(kq):
187 """ Summarize kqueue information
188
189 params:
190 kq - the kqueue object
191 returns: str - summary of kqueue
192 """
193 if kq.kq_state & xnudefines.KQ_WORKLOOP:
194 return GetKqworkloopSummary(kern.GetValueFromAddress(int(kq), 'struct kqworkloop *'))
195 elif kq.kq_state & xnudefines.KQ_WORKQ:
196 return GetKqworkqSummary(kern.GetValueFromAddress(int(kq), 'struct kqworkq *'))
197 else:
198 return GetKqfileSummary(kern.GetValueFromAddress(int(kq), 'struct kqfile *'))
199
200@lldb_type_summary(['struct kqfile *'])
201@header(GetKqueueSummary.header)
202def GetKqfileSummary(kqf):
203 kq = kern.GetValueFromAddress(int(kqf), 'struct kqueue *')
204 state = int(kq.kq_state)
205 return kqueue_summary_fmt.format(
206 o=kq,
207 ptr=int(kq),
208 wqs=int(kq.kq_wqs),
209 kqr_state='',
210 dyn_id=0,
211 st_str=xnudefines.GetStateString(xnudefines.kq_state_strings, state),
212 servicer=0,
213 owner=0)
214
215@lldb_command('showkqfile')
216def ShowKqfile(cmd_args=None):
217 """ Display information about a kqfile object.
218
219 usage: showkqfile <struct kqfile *>
220 """
221 if len(cmd_args) < 1:
222 raise ArgumentError('missing struct kqfile * argument')
223
224 kqf = kern.GetValueFromAddress(cmd_args[0], 'kqfile *')
225
226 print GetKqfileSummary.header
227 print GetKqfileSummary(kqf)
228 print GetKnoteSummary.header
229 for kn in IterateKqueueKnotes(kqf.kqf_kqueue):
230 print GetKnoteSummary(kn)
231 for kn in IterateTAILQ_HEAD(kqf.kqf_suppressed, 'kn_tqe'):
232 print GetKnoteSummary(kn)
233
234@lldb_type_summary(['struct kqworkq *'])
235@header(GetKqueueSummary.header)
236def GetKqworkqSummary(kqwq):
237 """ Summarize workqueue kqueue information
238
239 params:
240 kqwq - the kqworkq object
241 returns: str - summary of workqueue kqueue
242 """
243 return GetKqfileSummary(kern.GetValueFromAddress(int(kqwq), 'struct kqfile *'))
244
245@lldb_command('showkqworkq')
246def ShowKqworkq(cmd_args=None):
247 """ Display summary and knote information about a kqworkq.
248
249 usage: showkqworkq <struct kqworkq *>
250 """
251 if len(cmd_args) < 1:
252 raise ArgumentError('missing struct kqworkq * argument')
253
254 kqwq = kern.GetValueFromAddress(cmd_args[0], 'struct kqworkq *')
255 kq = kqwq.kqwq_kqueue
256 print GetKqueueSummary.header
257 print GetKqworkqSummary(kqwq)
258 print GetKnoteSummary.header
259 for kn in IterateKqueueKnotes(kq):
260 print GetKnoteSummary(kn)
261 for i in xrange(0, xnudefines.KQWQ_NBUCKETS):
262 for kn in IterateTAILQ_HEAD(kq.kq_queue[i], 'kn_tqe'):
263 print GetKnoteSummary(kn)
264
265@lldb_type_summary(['struct kqworkloop *'])
266@header(GetKqueueSummary.header)
267def GetKqworkloopSummary(kqwl):
268 """ Summarize workloop kqueue information
269
270 params:
271 kqwl - the kqworkloop object
272 returns: str - summary of workloop kqueue
273 """
274 state = int(kqwl.kqwl_kqueue.kq_state)
275 return kqueue_summary_fmt.format(
276 ptr=int(kqwl),
277 o=kqwl.kqwl_kqueue,
278 wqs=int(kqwl.kqwl_kqueue.kq_wqs),
279 dyn_id=kqwl.kqwl_dynamicid,
280 kqr_state=xnudefines.GetStateString(xnudefines.kqrequest_state_strings, kqwl.kqwl_request.kqr_state),
281 st_str=xnudefines.GetStateString(xnudefines.kq_state_strings, state),
d9a64523 282 servicer=int(kqwl.kqwl_request.kqr_thread),
5ba3f43e
A
283 owner=int(kqwl.kqwl_owner)
284 )
285
286@lldb_command('showkqworkloop')
287def ShowKqworkloop(cmd_args=None):
288 """ Display information about a kqworkloop.
289
290 usage: showkqworkloop <struct kqworkloop *>
291 """
292 if len(cmd_args) < 1:
293 raise ArgumentError('missing struct kqworkloop * argument')
294
295 kqwl = kern.GetValueFromAddress(cmd_args[0], 'struct kqworkloop *')
296
297 print GetKqworkloopSummary.header
298 print GetKqworkloopSummary(kqwl)
299
300 print GetKqrequestSummary.header
301 kqr = kern.GetValueFromAddress(unsigned(addressof(kqwl.kqwl_request)), 'struct kqrequest *')
302 print GetKqrequestSummary(kqr)
303
304 print GetKnoteSummary.header
305 for kn in IterateKqueueKnotes(kqwl.kqwl_kqueue):
306 print GetKnoteSummary(kn)
307
308@lldb_command('showkqueue')
309def ShowKqueue(cmd_args=None):
310 """ Given a struct kqueue pointer, display the summary of the kqueue
311
312 usage: showkqueue <struct kqueue *>
313 """
314 if not cmd_args:
315 raise ArgumentError('missing struct kqueue * argument')
316
317 kq = kern.GetValueFromAddress(cmd_args[0], 'struct kqueue *')
318 if int(kq.kq_state) & xnudefines.KQ_WORKQ:
319 ShowKqworkq(cmd_args=[str(int(kq))])
320 elif int(kq.kq_state) & xnudefines.KQ_WORKLOOP:
321 ShowKqworkloop(cmd_args=[str(int(kq))])
322 else:
323 print GetKqueueSummary.header
324 print GetKqueueSummary(kq)
325 print GetKnoteSummary.header
326 for kn in IterateKqueueKnotes(kq):
327 print GetKnoteSummary(kn)
328
329@lldb_command('showprocworkqkqueue')
330def ShowProcWorkqKqueue(cmd_args=None):
331 """ Show the workqueue kqueue for a given process.
332
333 usage: showworkqkqueue <proc_t>
334 """
335 if not cmd_args:
336 raise ArgumentError('missing struct proc * argument')
337
338 proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
339 ShowKqworkq(cmd_args=[str(int(proc.p_fd.fd_wqkqueue))])
340
341@lldb_command('showprockqueues')
342def ShowProcKqueues(cmd_args=None):
343 """ Show the kqueues for a given process.
344
345 usage: showprockqueues <proc_t>
346 """
347 if not cmd_args:
348 raise ArgumentError('missing struct proc * argument')
349
350 proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
351
352 print GetKqueueSummary.header
353 for kq in IterateProcKqueues(proc):
354 print GetKqueueSummary(kq)
355
356@lldb_command('showprocknotes')
357def ShowProcKnotes(cmd_args=None):
358 """ Show the knotes for a given process.
359
360 usage: showprocknotes <proc_t>
361 """
362
363 if not cmd_args:
364 raise ArgumentError('missing struct proc * argument')
365
366 proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t')
367
368 print GetKnoteSummary.header
369 for kn in IterateProcKnotes(proc):
370 print GetKnoteSummary(kn)
371
372@lldb_command('showallkqueues')
373def ShowAllKqueues(cmd_args=[], cmd_options={}):
374 """ Display a summary of all the kqueues in the system
375
376 usage: showallkqueues
377 """
378 print GetKqueueSummary.header
379 for kq in IterateAllKqueues():
380 print GetKqueueSummary(kq)