]> git.saurik.com Git - apple/xnu.git/blame - tools/trace/kqtrace.lua
xnu-4570.41.2.tar.gz
[apple/xnu.git] / tools / trace / kqtrace.lua
CommitLineData
5ba3f43e
A
1#!/usr/local/bin/luatrace -s
2
3trace_eventname = function(codename, callback)
4 local debugid = trace.debugid(codename)
5 if debugid ~= 0 then
6 trace.single(debugid,callback)
7 else
8 printf("WARNING: Cannot locate debugid for '%s'\n", codename)
9 end
10end
11
12initial_timestamp = 0
13
14function event_prefix_string(buf, workq)
15 if initial_timestamp == 0 then
16 initial_timestamp = buf.timestamp
17 end
18 local secs = trace.convert_timestamp_to_nanoseconds(buf.timestamp - initial_timestamp) / 1000000000
19
20 local type
21 if trace.debugid_is_start(buf.debugid) then
22 type = "→"
23 elseif trace.debugid_is_end(buf.debugid) then
24 type = "←"
25 else
26 type = "↔"
27 end
28
29 proc = buf.command
30
31 local prefix = string.format("%s %6.9f %-17s [%05d.%06x] %-28s\t",
32 type, secs, proc, buf.pid, buf.threadid, buf.debugname)
33 if not workq then
34 prefix = prefix .. string.format(" 0x%16x", buf.arg1)
35 end
36
37 return prefix
38end
39
40function qos_string(qos)
41 if qos == 0 then
42 return "--"
43 elseif qos == 1 then
44 return "MT"
45 elseif qos == 2 then
46 return "BG"
47 elseif qos == 3 then
48 return "UT"
49 elseif qos == 4 then
50 return "DF"
51 elseif qos == 5 then
52 return "IN"
53 elseif qos == 6 then
54 return "UI"
55 elseif qos == 7 then
56 return "MG"
57 else
58 return string.format("??[0x%x]", qos)
59 end
60end
61
62function state_string(strings, state)
63 local str = ''
64 local first = true
65 for name, bit in pairs(strings) do
66 if (state & bit) == bit then
67 if not first then
68 str = str .. ' '
69 end
70 str = str .. name
71 first = false
72 end
73 end
74 return str
75end
76
77kqrequest_state_strings = {
78 ['PROCESSING'] = 0x1,
79 ['THREQUESTED'] = 0x2,
80 ['WAKEUP'] = 0x4
81}
82
83kqueue_state_strings = {
84 ['SEL'] = 0x001,
85 ['SLEEP'] = 0x002,
86 ['PROCWAIT'] = 0x004,
87 ['KEV32'] = 0x008,
88 ['KEV64'] = 0x010,
89 ['KEV_QOS'] = 0x020,
90 ['WORKQ'] = 0x040,
91 ['WORKLOOP'] = 0x080,
92 ['PROCESSING'] = 0x100,
93 ['DRAIN'] = 0x200,
94 ['WAKEUP'] = 0x400,
95 ['DYNAMIC'] = 0x800,
96}
97
98knote_state_strings = {
99 ['ACTIVE'] = 0x0001,
100 ['QUEUED'] = 0x0002,
101 ['DISABLED'] = 0x0004,
102 ['DROPPING'] = 0x0008,
103 ['USEWAIT'] = 0x0010,
104 ['ATTACHING'] = 0x0020,
105 ['STAYACTIVE'] = 0x0040,
106 ['DEFERDELETE'] = 0x0080,
107 ['ATTACHED'] = 0x0100,
108 ['DISPATCH'] = 0x0200,
109 ['UDATA_SPECIFIC'] = 0x0400,
110 ['SUPPRESSED'] = 0x0800,
111 ['STOLENDROP'] = 0x1000,
112 ['REQVANISH'] = 0x2000,
113 ['VANISHED'] = 0x4000,
114}
115knote_state_strings = {
116 ['ACTIVE'] = 0x0001,
117 ['QUEUED'] = 0x0002,
118 ['DISABLED'] = 0x0004,
119 ['DROPPING'] = 0x0008,
120 ['USEWAIT'] = 0x0010,
121 ['ATTACHING'] = 0x0020,
122 ['STAYACTIVE'] = 0x0040,
123 ['DEFERDELETE'] = 0x0080,
124 ['ATTACHED'] = 0x0100,
125 ['DISPATCH'] = 0x0200,
126 ['UDATA_SPECIFIC'] = 0x0400,
127 ['SUPPRESSED'] = 0x0800,
128 ['STOLENDROP'] = 0x1000,
129 ['REQVANISH'] = 0x2000,
130 ['VANISHED'] = 0x4000,
131}
132
133
134kevent_flags_strings = {
135 ['ADD'] = 0x0001,
136 ['DELETE'] = 0x0002,
137 ['ENABLE'] = 0x0004,
138 ['DISABLE'] = 0x0008,
139 ['ONESHOT'] = 0x0010,
140 ['CLEAR'] = 0x0020,
141 ['RECEIPT'] = 0x0040,
142 ['DISPATCH'] = 0x0080,
143 ['UDATA_SPECIFIC'] = 0x0100,
144 ['VANISHED'] = 0x0200,
145 ['FLAG0'] = 0x1000,
146 ['FLAG1'] = 0x2000,
147 ['EOF'] = 0x8000,
148 ['ERROR'] = 0x4000,
149}
150
151function kevent_filter_string(filt)
152 if filt == -1 then
153 return 'READ'
154 elseif filt == -2 then
155 return 'WRITE'
156 elseif filt == -3 then
157 return 'AIO'
158 elseif filt == -4 then
159 return 'VNODE'
160 elseif filt == -5 then
161 return 'PROC'
162 elseif filt == -6 then
163 return 'SIGNAL'
164 elseif filt == -7 then
165 return 'TIMER'
166 elseif filt == -8 then
167 return 'MACHPORT'
168 elseif filt == -9 then
169 return 'FS'
170 elseif filt == -10 then
171 return 'USER'
172 -- -11 unused
173 elseif filt == -12 then
174 return 'VM'
175 elseif filt == -13 then
176 return 'SOCK'
177 elseif filt == -14 then
178 return 'MEMORYSTATUS'
179 elseif filt == 15 then
180 return 'KQREAD'
181 elseif filt == 16 then
182 return 'PIPE_R'
183 elseif filt == 17 then
184 return 'PIPE_W'
185 elseif filt == 18 then
186 return 'PTSD'
187 elseif filt == 19 then
188 return 'SOWRITE'
189 elseif filt == 20 then
190 return 'SOEXCEPT'
191 elseif filt == 21 then
192 return 'SPEC'
193 elseif filt == 22 then
194 return 'BPFREAD'
195 elseif filt == 23 then
196 return 'NECP_FD'
197 elseif filt == 24 then
198 return 'SKYWALK_CHANNEL_W'
199 elseif filt == 25 then
200 return 'SKYWALK_CHANNEL_R'
201 elseif filt == 26 then
202 return 'FSEVENT'
203 elseif filt == 27 then
204 return 'VN'
205 elseif filt == 28 then
206 return 'SKYWALK_CHANNEL_E'
207 elseif filt == 29 then
208 return 'TTY'
209 else
210 return string.format('[%d]', filt)
211 end
212end
213
214-- kqueue lifecycle
215
216function processing_begin(workq)
217 return function(buf)
218 local prefix = event_prefix_string(buf, workq)
219 if trace.debugid_is_start(buf.debugid) then
220 local qos
221 if workq then
222 qos = buf.arg2
223 else
224 qos = buf.arg3
225 end
226 printf("%s QoS = %s\n", prefix, qos_string(qos))
227 else
228 printf("%s request thread = 0x%x, kqrequest state = %s\n", prefix,
229 buf.arg1, state_string(kqrequest_state_strings, buf.arg2))
230 end
231 end
232end
233
234trace_eventname("KEVENT_kq_processing_begin", processing_begin(false))
235trace_eventname("KEVENT_kqwq_processing_begin", processing_begin(true))
236trace_eventname("KEVENT_kqwl_processing_begin", processing_begin(false))
237
238function processing_end(workq)
239 return function(buf)
240 local qos
241 if workq then
242 qos = buf.arg2
243 else
244 qos = buf.arg3
245 end
246 printf("%s QoS = %s\n", event_prefix_string(buf, workq), qos_string(qos))
247 end
248end
249
250trace_eventname("KEVENT_kq_processing_end", processing_end(false))
251trace_eventname("KEVENT_kqwq_processing_end", processing_end(true))
252trace_eventname("KEVENT_kqwl_processing_end", processing_end(false))
253
254trace_eventname("KEVENT_kqwq_bind", function(buf)
255 printf("%s thread = 0x%x, QoS = %s, kqrequest state = %s\n",
256 event_prefix_string(buf, true), buf.arg1, qos_string(buf.arg3),
257 state_string(kqrequest_state_strings, buf.arg4))
258end)
259
260trace_eventname("KEVENT_kqwq_unbind", function(buf)
261 printf("%s thread = 0x%x, QoS = %s\n", event_prefix_string(buf, true),
262 buf.arg1, qos_string(buf.arg3))
263end)
264
265trace_eventname("KEVENT_kqwl_bind", function(buf)
266 qos = buf.arg3 & 0xff
267 duplicate = buf.arg3 & (1 << 8)
268 kqr_override_qos_delta = buf.arg4 >> 8
269 kqr_state = buf.arg4 & 0xff
270
271 printf("%s thread = 0x%x, QoS = %s, override QoS delta = %d, kqrequest state = %s%s\n",
272 event_prefix_string(buf, false), buf.arg2, qos_string(qos),
273 kqr_override_qos_delta,
274 state_string(kqrequest_state_strings, kqr_state),
275 duplicate ? ", duplicate" : "")
276end)
277
278trace_eventname("KEVENT_kqwl_unbind", function(buf)
279 flags = buf.arg3
280 qos = buf.arg4
281
282 printf("%s thread = 0x%x, QoS = %s, flags = 0x%x\n", event_prefix_string(buf, false),
283 buf.arg2, qos_string(qos), flags)
284end)
285
286function thread_request(workq)
287 return function(buf)
288 printf("%s QoS = %s, kqrequest state = %s, override QoS delta = %d\n",
289 event_prefix_string(buf, workq), qos_string(buf.arg2),
290 state_string(kqrequest_state_strings, buf.arg3), buf.arg3 >> 8)
291 end
292end
293
294function thread_adjust(buf)
295 tid = buf.arg2
296 kqr_qos = buf.arg3 >> 8
297 new_qos = buf.arg3 & 0xff
298 kqr_qos_override = buf.arg4 >> 8
299 kqr_state = buf.arg4 & 0xff
300
301 printf("%s thread = 0x%x, old/new QoS = %s/%s, old/new override QoS delta = %d/%d, kqrequest state = %s\n",
302 event_prefix_string(buf, false),
303 tid,
304 qos_string(kqr_qos),
305 qos_string(new_qos),
306 kqr_qos_override,
307 new_qos - kqr_qos,
308 state_string(kqrequest_state_strings, kqr_state))
309end
310
311trace_eventname("KEVENT_kqwq_thread_request", thread_request(true))
312trace_eventname("KEVENT_kqwl_thread_request", thread_request(false))
313trace_eventname("KEVENT_kqwl_thread_adjust", thread_adjust)
314
315function kevent_register(workq)
316 return function(buf)
317 printf("%s kevent udata = 0x%x, kevent filter = %s, kevent flags = %s\n",
318 event_prefix_string(buf, workq), buf.arg2,
319 kevent_filter_string(buf.arg4),
320 state_string(kevent_flags_strings, buf.arg3))
321 end
322end
323
324trace_eventname("KEVENT_kq_register", kevent_register(false))
325trace_eventname("KEVENT_kqwq_register", kevent_register(true))
326trace_eventname("KEVENT_kqwl_register", kevent_register(false))
327
328function kevent_process(workq)
329 return function(buf)
330 printf("%s kevent ident = 0x%x, udata = 0x%x, kevent filter = %s, knote status = %s\n",
331 event_prefix_string(buf, workq), buf.arg3 >> 32, buf.arg2,
332 kevent_filter_string(buf.arg4),
333 state_string(knote_state_strings, buf.arg3 & 0xffffffff))
334 end
335end
336
337trace_eventname("KEVENT_kq_process", kevent_process(false))
338trace_eventname("KEVENT_kqwq_process", kevent_process(true))
339trace_eventname("KEVENT_kqwl_process", kevent_process(false))