]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/ktrace.py
xnu-4570.1.46.tar.gz
[apple/xnu.git] / tools / lldbmacros / ktrace.py
1 from xnu import *
2 from utils import *
3
4 # From the defines in bsd/sys/kdebug.h:
5
6 KdebugClassNames = {
7 1: "MACH",
8 2: "NETWORK",
9 3: "FSYSTEM",
10 4: "BSD",
11 5: "IOKIT",
12 6: "DRIVERS",
13 7: "TRACE",
14 8: "DLIL",
15 9: "WORKQUEUE",
16 10: "CORESTORAGE",
17 11: "CG",
18 20: "MISC",
19 30: "SECURITY",
20 31: "DYLD",
21 32: "QT",
22 33: "APPS",
23 34: "LAUNCHD",
24 36: "PPT",
25 37: "PERF",
26 38: "IMPORTANCE",
27 39: "PERFCTRL",
28 40: "BANK",
29 41: "XPC",
30 42: "ATM",
31 43: "ARIADNE",
32 44: "DAEMON",
33 45: "ENERGYTRACE",
34 49: "IMG",
35 50: "CLPC",
36 128: "ANS",
37 129: "SIO",
38 130: "SEP",
39 131: "ISP",
40 132: "OSCAR",
41 133: "EMBEDDEDGFX"
42 }
43
44 def GetKdebugClassName(class_num):
45 return (KdebugClassNames[class_num] + ' ({})'.format(class_num) if class_num in KdebugClassNames else 'unknown ({})'.format(class_num))
46
47 @lldb_type_summary(['typefilter_t'])
48 @header('{0: <20s}'.format("class") + ' '.join(map('{:02x}'.format, xrange(0, 255, 8))))
49 def GetKdebugTypefilter(typefilter):
50 """ Summarizes the provided typefilter.
51 """
52 classes = 256
53 subclasses_per_class = 256
54
55 # 8 bits at a time
56 subclasses_per_element = 64
57 cur_typefilter = cast(typefilter, 'uint64_t *')
58 subclasses_fmts = ' '.join(['{:02x}'] * 8)
59
60 elements_per_class = subclasses_per_class / subclasses_per_element
61
62 out_str = ''
63 for i in xrange(0, classes):
64 print_class = False
65 subclasses = [0] * elements_per_class
66
67 # check subclass ranges for set bits, remember those subclasses
68 for j in xrange(0, elements_per_class):
69 element = unsigned(cur_typefilter[i * elements_per_class + j])
70 if element != 0:
71 print_class = True
72 if print_class:
73 subclasses[j] = element
74
75 ## if any of the bits were set in a class, print the entire class
76 if print_class:
77 out_str += '{:<20s}'.format(GetKdebugClassName(i))
78 for element in subclasses:
79 # split up the 64-bit values into byte-sized pieces
80 bytes = [unsigned((element >> i) & 0xff) for i in (0, 8, 16, 24, 32, 40, 48, 56)]
81 out_str += subclasses_fmts.format(*bytes)
82 out_str += ' '
83
84 out_str += '\n'
85
86 return out_str
87
88 @lldb_command('showkdebugtypefilter')
89 def ShowKdebugTypefilter(cmd_args=None):
90 """ Show the current kdebug typefilter (or the typefilter at an address)
91
92 usage: showkdebugtypefilter [<address>]
93 """
94
95 if cmd_args:
96 typefilter = kern.GetValueFromAddress(cmd_args[0], 'typefilter_t')
97 if unsigned(typefilter) == 0:
98 raise ArgumentError('argument provided is NULL')
99
100 print GetKdebugTypefilter.header
101 print '-' * len(GetKdebugTypefilter.header)
102
103 print GetKdebugTypefilter(typefilter)
104 return
105
106 typefilter = kern.globals.kdbg_typefilter
107 if unsigned(typefilter) == 0:
108 raise ArgumentError('no argument provided and active typefilter is not set')
109
110 print GetKdebugTypefilter.header
111 print '-' * len(GetKdebugTypefilter.header)
112 print GetKdebugTypefilter(typefilter)
113
114 def GetKdebugStatus():
115 """ Get a string summary of the kdebug subsystem.
116 """
117 out = ''
118
119 kdebug_flags = kern.globals.kd_ctrl_page.kdebug_flags
120 out += 'kdebug flags: {}\n'.format(xnudefines.GetStateString(xnudefines.kdebug_flags_strings, kdebug_flags))
121 events = kern.globals.nkdbufs
122 buf_mb = events * (64 if kern.arch == 'x86_64' or kern.arch.startswith('arm64') else 32) / 1000000
123 out += 'events allocated: {:<d} ({:<d} MB)\n'.format(events, buf_mb)
124 out += 'enabled: {}\n'.format('yes' if kern.globals.kdebug_enable != 0 else 'no')
125 if kdebug_flags & xnudefines.kdebug_typefilter_check:
126 out += 'typefilter:\n'
127 out += GetKdebugTypefilter.header + '\n'
128 out += '-' * len(GetKdebugTypefilter.header) + '\n'
129 typefilter = kern.globals.kdbg_typefilter
130 if unsigned(typefilter) != 0:
131 out += GetKdebugTypefilter(typefilter)
132
133 return out
134
135 @lldb_command('showkdebug')
136 def ShowKdebug(cmd_args=None):
137 """ Show the current kdebug state.
138
139 usage: showkdebug
140 """
141
142 print GetKdebugStatus()
143
144 @lldb_type_summary(['kperf_timer'])
145 @header('{:<10s} {:<7s} {:<20s}'.format('period-ns', 'action', 'pending'))
146 def GetKperfTimerSummary(timer):
147 """ Get a string summary of a kperf timer.
148
149 params:
150 timer: the kperf_timer object to get a summary of
151 """
152 return '{:<10d} {:<7d} {:<20x}\n'.format(
153 kern.GetNanotimeFromAbstime(timer.period), timer.actionid, timer.pending_cpus)
154
155 @lldb_type_summary(['action'])
156 @header('{:<10s} {:<20s} {:<20s}'.format('pid-filter', 'user-data', 'samplers'))
157 def GetKperfActionSummary(action):
158 """ Get a string summary of a kperf action.
159
160 params:
161 action: the action object to get a summary of
162 """
163 samplers = xnudefines.GetStateString(xnudefines.kperf_samplers_strings, action.sample)
164 return '{:<10s} {:<20x} {:<20s}\n'.format(
165 '-' if action.pid_filter < 0 else str(action.pid_filter), action.userdata, samplers)
166
167 def GetKperfStatus():
168 """ Get a string summary of the kperf subsystem.
169 """
170 out = ''
171
172 kperf_status = kern.globals.sampling_status
173 out += 'sampling: '
174 if kperf_status == 0:
175 out += 'off\n'
176 elif kperf_status == 1:
177 out += 'on\n'
178 elif kperf_status == 2:
179 out += 'shutting down\n'
180 else:
181 out += 'unknown\n'
182
183 pet = 0# kern.globals.pet_running
184 pet_timer_id = kern.globals.pet_timer_id
185 if pet != 0:
186 pet_idle_rate = kern.globals.pet_idle_rate
187 out += 'legacy PET is active (timer = {:<d}, idle rate = {:<d})\n'.format(pet_timer_id, pet_idle_rate)
188 else:
189 out += 'legacy PET is off\n'
190
191 lw_pet = kern.globals.kperf_lightweight_pet_active
192 if lw_pet != 0:
193 lw_pet_gen = kern.globals.kperf_pet_gen
194 out += 'lightweight PET is active (timer = {:<d}, generation count = {:<d})\n'.format(pet_timer_id, lw_pet_gen)
195 else:
196 out += 'lightweight PET is off\n'
197
198 actions = kern.globals.actionc
199 actions_arr = kern.globals.actionv
200
201 out += 'actions:\n'
202 out += '{:<5s} '.format('id') + GetKperfActionSummary.header + '\n'
203 for i in xrange(0, actions):
204 out += '{:<5d} '.format(i) + GetKperfActionSummary(actions_arr[i])
205
206 timers = kern.globals.kperf_timerc
207 timers_arr = kern.globals.kperf_timerv
208
209 out += 'timers:\n'
210 out += '{:<5s} '.format('id') + GetKperfTimerSummary.header + '\n'
211 for i in xrange(0, timers):
212 out += '{:<5d} '.format(i) + GetKperfTimerSummary(timers_arr[i])
213
214 return out
215
216 def GetKtraceStatus():
217 """ Get a string summary of the ktrace subsystem.
218 """
219 out = ''
220
221 state = kern.globals.ktrace_state
222 if state == GetEnumValue('ktrace_state::KTRACE_STATE_OFF'):
223 out += 'ktrace is off\n'
224 else:
225 out += 'ktrace is active ('
226 if state == GetEnumValue('ktrace_state::KTRACE_STATE_FG'):
227 out += 'foreground)'
228 else:
229 out += 'background)'
230 out += '\n'
231 owner = kern.globals.ktrace_last_owner_execname
232 out += 'owned by: {0: <s}\n'.format(owner)
233 active_mask = kern.globals.ktrace_active_mask
234 out += 'active systems: {:<#x}\n'.format(active_mask)
235
236 return out
237
238 @lldb_command('showktrace')
239 def ShowKtrace(cmd_args=None):
240 """ Show the current ktrace state, including subsystems.
241
242 usage: showktrace
243 """
244
245 print GetKtraceStatus()
246 print ' '
247 print 'kdebug:'
248 print GetKdebugStatus()
249 print ' '
250 print 'kperf:'
251 print GetKperfStatus()