]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | # |
2 | # Kernel gdb macros | |
3 | # | |
4 | # These gdb macros should be useful during kernel development in | |
5 | # determining what's going on in the kernel. | |
6 | # | |
7 | # All the convenience variables used by these macros begin with $kgm_ | |
8 | ||
0c530ab8 A |
9 | set print asm-demangle on |
10 | set cp-abi gnu-v2 | |
9bccf70c | 11 | |
1c79356b A |
12 | echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n |
13 | ||
14 | define kgm | |
55e303ae A |
15 | printf "" |
16 | echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n | |
1c79356b A |
17 | end |
18 | ||
19 | document kgm | |
20 | | These are the kernel gdb macros. These gdb macros are intended to be | |
21 | | used when debugging a remote kernel via the kdp protocol. Typically, you | |
22 | | would connect to your remote target like so: | |
23 | | (gdb) target remote-kdp | |
24 | | (gdb) attach <name-of-remote-host> | |
25 | | | |
26 | | The following macros are available in this package: | |
91447636 | 27 | | showversion Displays a string describing the remote kernel version |
1c79356b | 28 | | |
55e303ae A |
29 | | showalltasks Display a summary listing of all tasks |
30 | | showallthreads Display info about all threads in the system | |
31 | | showallstacks Display the stack for each thread in the system | |
32 | | showcurrentthreads Display info about the thread running on each cpu | |
33 | | showcurrentstacks Display the stack for the thread running on each cpu | |
1c79356b A |
34 | | showallvm Display a summary listing of all the vm maps |
35 | | showallvme Display a summary listing of all the vm map entries | |
36 | | showallipc Display a summary listing of all the ipc spaces | |
37 | | showallrights Display a summary listing of all the ipc rights | |
38 | | showallkmods Display a summary listing of all the kernel modules | |
0c530ab8 A |
39 | | |
40 | | showallclasses Display info about all OSObject subclasses in the system | |
41 | | showobject Show info about an OSObject - its vtable ptr and retain count, & more info for simple container classes. | |
42 | | showregistry Show info about all registry entries in the current plane | |
43 | | showregistryprops Show info about all registry entries in the current plane, and their properties | |
44 | | showregistryentry Show info about a registry entry; its properties and descendants in the current plane | |
45 | | setregistryplane Set the plane to be used for the iokit registry macros (pass zero for list) | |
1c79356b | 46 | | |
55e303ae A |
47 | | showtask Display info about the specified task |
48 | | showtaskthreads Display info about the threads in the task | |
49 | | showtaskstacks Display the stack for each thread in the task | |
50 | | showtaskvm Display info about the specified task's vm_map | |
51 | | showtaskvme Display info about the task's vm_map entries | |
52 | | showtaskipc Display info about the specified task's ipc space | |
53 | | showtaskrights Display info about the task's ipc space entries | |
1c79356b | 54 | | |
55e303ae A |
55 | | showact Display info about a thread specified by activation |
56 | | showactstack Display the stack for a thread specified by activation | |
1c79356b | 57 | | |
55e303ae | 58 | | showmap Display info about the specified vm_map |
1c79356b A |
59 | | showmapvme Display a summary list of the specified vm_map's entries |
60 | | | |
55e303ae | 61 | | showipc Display info about the specified ipc space |
1c79356b A |
62 | | showrights Display a summary list of all the rights in an ipc space |
63 | | | |
55e303ae A |
64 | | showpid Display info about the process identified by pid |
65 | | showproc Display info about the process identified by proc struct | |
1c79356b | 66 | | |
55e303ae | 67 | | showkmod Display info about a kernel module |
1c79356b A |
68 | | showkmodaddr Given an address, display the kernel module and offset |
69 | | | |
55e303ae A |
70 | | dumpcallqueue Dump out all the entries given a queue head |
71 | | | |
91447636 A |
72 | | showallmtx Display info about mutexes usage |
73 | | showallrwlck Display info about reader/writer locks usage | |
74 | | | |
55e303ae | 75 | | zprint Display info about the memory zones |
91447636 | 76 | | showioalloc Display info about iokit allocations |
55e303ae | 77 | | paniclog Display the panic log info |
9bccf70c | 78 | | |
55e303ae A |
79 | | switchtoact Switch to different context specified by activation |
80 | | switchtoctx Switch to different context | |
91447636 A |
81 | | showuserstack Display numeric backtrace of the user stack for an |
82 | | activation | |
83 | | | |
84 | | switchtouserthread Switch to the user context of the specified thread | |
85 | | resetstacks Return to the original kernel context | |
86 | | | |
9bccf70c | 87 | | resetctx Reset context |
55e303ae A |
88 | | resume_on Resume when detaching from gdb |
89 | | resume_off Don't resume when detaching from gdb | |
1c79356b | 90 | | |
91447636 A |
91 | | sendcore Configure kernel to send a coredump to the specified IP |
92 | | disablecore Configure the kernel to disable coredump transmission | |
93 | | switchtocorethread Corefile version of "switchtoact" | |
94 | | resetcorectx Corefile version of "resetctx" | |
0c530ab8 A |
95 | | |
96 | | readphys Reads the specified untranslated address | |
97 | | readphys64 Reads the specified untranslated 64-bit address | |
98 | | | |
91447636 A |
99 | | kdp-reboot Restart remote target |
100 | | | |
1c79356b A |
101 | | Type "help <macro>" for more specific help on a particular macro. |
102 | | Type "show user <macro>" to see what the macro is really doing. | |
103 | end | |
104 | ||
0c530ab8 A |
105 | # This macro should appear before any symbol references, to facilitate |
106 | # a gdb "source" without a loaded symbol file. | |
107 | define showversion | |
108 | printf "%s\n", *(char **)0x501C | |
109 | end | |
110 | ||
111 | document showversion | |
112 | Syntax: showversion | |
113 | | Read the kernel version string from a fixed address in low | |
114 | | memory. Useful if you don't know which kernel is on the other end, | |
115 | | and need to find the appropriate symbols. Beware that if you've | |
116 | | loaded a symbol file, but aren't connected to a remote target, | |
117 | | the version string from the symbol file will be displayed instead. | |
118 | | This macro expects to be connected to the remote kernel to function | |
119 | | correctly. | |
120 | end | |
121 | ||
122 | set $kgm_dummy = &proc0 | |
123 | set $kgm_dummy = &kmod | |
124 | set $kgm_mtype = ((struct mach_header)_mh_execute_header).cputype | |
125 | ||
126 | set $kgm_reg_depth = 0 | |
127 | set $kgm_reg_plane = (void **) gIOServicePlane | |
128 | set $kgm_namekey = (OSSymbol *) 0 | |
129 | set $kgm_childkey = (OSSymbol *) 0 | |
130 | ||
131 | set $kgm_show_object_addrs = 0 | |
132 | set $kgm_show_object_retain = 0 | |
133 | set $kgm_show_props = 0 | |
1c79356b A |
134 | |
135 | define showkmodheader | |
136 | printf "kmod address size " | |
137 | printf "id refs version name\n" | |
138 | end | |
139 | ||
140 | define showkmodint | |
141 | set $kgm_kmodp = (struct kmod_info *)$arg0 | |
142 | printf "0x%08x ", $arg0 | |
143 | printf "0x%08x ", $kgm_kmodp->address | |
144 | printf "0x%08x ", $kgm_kmodp->size | |
145 | printf "%3d ", $kgm_kmodp->id | |
146 | printf "%5d ", $kgm_kmodp->reference_count | |
147 | printf "%10s ", &$kgm_kmodp->version | |
148 | printf "%s\n", &$kgm_kmodp->name | |
149 | end | |
150 | ||
151 | set $kgm_kmodmin = 0xffffffff | |
152 | set $kgm_fkmodmin = 0x00000000 | |
153 | set $kgm_kmodmax = 0x00000000 | |
154 | set $kgm_fkmodmax = 0xffffffff | |
155 | set $kgm_pkmod = 0 | |
156 | set $kgm_pkmodst = 0 | |
157 | set $kgm_pkmoden = 0 | |
0c530ab8 | 158 | define showkmodaddrint |
1c79356b A |
159 | printf "0x%x" , $arg0 |
160 | if ((unsigned int)$arg0 >= (unsigned int)$kgm_pkmodst) && ((unsigned int)$arg0 <= (unsigned int)$kgm_pkmoden) | |
161 | set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_pkmodst) | |
162 | printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off | |
163 | else | |
164 | if ((unsigned int)$arg0 <= (unsigned int)$kgm_fkmodmax) && ((unsigned int)$arg0 >= (unsigned int)$kgm_fkmodmin) | |
165 | set $kgm_kmodp = (struct kmod_info *)kmod | |
166 | while $kgm_kmodp | |
167 | set $kgm_kmod = *$kgm_kmodp | |
168 | if $kgm_kmod.address && ($kgm_kmod.address < $kgm_kmodmin) | |
169 | set $kgm_kmodmin = $kgm_kmod.address | |
170 | end | |
171 | if ($kgm_kmod.address + $kgm_kmod.size) > $kgm_kmodmax | |
0c530ab8 | 172 | set $kgm_kmodmax = $kgm_kmod.address + $kgm_kmod.size |
1c79356b A |
173 | end |
174 | set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_kmod.address) | |
175 | if ($kgm_kmod.address <= $arg0) && ($kgm_off <= $kgm_kmod.size) | |
176 | printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off | |
177 | set $kgm_pkmod = $kgm_kmodp | |
178 | set $kgm_pkmodst = $kgm_kmod.address | |
179 | set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmod.size | |
180 | set $kgm_kmodp = 0 | |
181 | else | |
182 | set $kgm_kmodp = $kgm_kmod.next | |
183 | end | |
184 | end | |
185 | if !$kgm_pkmod | |
186 | set $kgm_fkmodmin = $kgm_kmodmin | |
187 | set $kgm_fkmodmax = $kgm_kmodmax | |
188 | end | |
189 | end | |
190 | end | |
191 | end | |
0c530ab8 A |
192 | |
193 | define showkmodaddr | |
194 | showkmodaddrint $arg0 | |
195 | printf "\n" | |
196 | end | |
197 | ||
1c79356b A |
198 | document showkmodaddr |
199 | | Given an address, print the offset and name for the kmod containing it | |
200 | | The following is the syntax: | |
201 | | (gdb) showkmodaddr <addr> | |
202 | end | |
203 | ||
204 | define showkmod | |
205 | showkmodheader | |
206 | showkmodint $arg0 | |
207 | end | |
208 | document showkmod | |
209 | | Routine to print info about a kernel module | |
210 | | The following is the syntax: | |
211 | | (gdb) showkmod <kmod> | |
212 | end | |
213 | ||
214 | define showallkmods | |
215 | showkmodheader | |
216 | set $kgm_kmodp = (struct kmod_info *)kmod | |
217 | while $kgm_kmodp | |
218 | showkmodint $kgm_kmodp | |
219 | set $kgm_kmodp = $kgm_kmodp->next | |
220 | end | |
221 | end | |
222 | document showallkmods | |
223 | | Routine to print a summary listing of all the kernel modules | |
224 | | The following is the syntax: | |
225 | | (gdb) showallkmods | |
226 | end | |
227 | ||
228 | define showactheader | |
229 | printf " activation " | |
230 | printf "thread pri state wait_queue wait_event\n" | |
231 | end | |
232 | ||
233 | ||
234 | define showactint | |
91447636 A |
235 | printf " 0x%08x ", $arg0 |
236 | set $kgm_thread = *(struct thread *)$arg0 | |
237 | printf "0x%08x ", $arg0 | |
1c79356b A |
238 | printf "%3d ", $kgm_thread.sched_pri |
239 | set $kgm_state = $kgm_thread.state | |
240 | if $kgm_state & 0x80 | |
241 | printf "I" | |
242 | end | |
243 | if $kgm_state & 0x40 | |
244 | printf "P" | |
245 | end | |
246 | if $kgm_state & 0x20 | |
247 | printf "A" | |
248 | end | |
249 | if $kgm_state & 0x10 | |
250 | printf "H" | |
251 | end | |
252 | if $kgm_state & 0x08 | |
253 | printf "U" | |
254 | end | |
255 | if $kgm_state & 0x04 | |
256 | printf "R" | |
257 | end | |
258 | if $kgm_state & 0x02 | |
259 | printf "S" | |
260 | end | |
261 | if $kgm_state & 0x01 | |
262 | printf "W\t" | |
263 | printf "0x%08x ", $kgm_thread.wait_queue | |
0c530ab8 A |
264 | if (((unsigned)$kgm_thread.wait_event > (unsigned)sectPRELINKB) \ |
265 | && ($arg1 != 2)) | |
266 | showkmodaddr $kgm_thread.wait_event | |
267 | else | |
91447636 A |
268 | output /a (unsigned) $kgm_thread.wait_event |
269 | end | |
1c79356b A |
270 | end |
271 | if $arg1 != 0 | |
272 | if ($kgm_thread.kernel_stack != 0) | |
55e303ae A |
273 | if ($kgm_thread.reserved_stack != 0) |
274 | printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack | |
1c79356b A |
275 | end |
276 | printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack | |
91447636 A |
277 | if ($kgm_mtype == 18) |
278 | set $mysp = $kgm_thread.machine.pcb->save_r1 | |
55e303ae | 279 | else |
0c530ab8 | 280 | set $kgm_statep = (struct x86_kernel_state32 *) \ |
91447636 | 281 | ($kgm_thread->kernel_stack + 0x4000 \ |
0c530ab8 | 282 | - sizeof(struct x86_kernel_state32)) |
55e303ae A |
283 | set $mysp = $kgm_statep->k_ebp |
284 | end | |
0c530ab8 | 285 | set $prevsp = $mysp - 16 |
1c79356b | 286 | printf "\n\t\tstacktop=0x%08x", $mysp |
91447636 A |
287 | if ($kgm_mtype == 18) |
288 | set $stkmask = 0xf | |
91447636 A |
289 | else |
290 | set $stkmask = 0x3 | |
91447636 | 291 | end |
0c530ab8 | 292 | set $kgm_return = 0 |
91447636 | 293 | while ($mysp != 0) && (($mysp & $stkmask) == 0) \ |
0c530ab8 A |
294 | && ($mysp != $prevsp) \ |
295 | && ((((unsigned) $mysp ^ (unsigned) $prevsp) < 0x2000) \ | |
296 | || (((unsigned)$mysp < ((unsigned) ($kgm_thread->kernel_stack+0x4000))) \ | |
297 | && ((unsigned)$mysp > (unsigned) ($kgm_thread->kernel_stack)))) | |
298 | ||
299 | if ((unsigned) $kgm_return > (unsigned) sectPRELINKB) | |
300 | showkmodaddr $kgm_return | |
301 | else | |
302 | if ((unsigned) $kgm_return > 0) | |
303 | output /a (unsigned) $kgm_return | |
304 | end | |
305 | end | |
91447636 A |
306 | printf "\n\t\t0x%08x ", $mysp |
307 | if ($kgm_mtype == 18) | |
308 | set $kgm_return = *($mysp + 8) | |
309 | else | |
310 | set $kgm_return = *($mysp + 4) | |
311 | end | |
91447636 A |
312 | set $prevsp = $mysp |
313 | set $mysp = * $mysp | |
1c79356b | 314 | end |
0c530ab8 A |
315 | if ((unsigned) $kgm_return > 0) |
316 | output/a $kgm_return | |
317 | end | |
318 | set $kgm_return = 0 | |
1c79356b A |
319 | printf "\n\t\tstackbottom=0x%08x", $prevsp |
320 | else | |
321 | printf "\n\t\t\tcontinuation=" | |
91447636 | 322 | output /a (unsigned) $kgm_thread.continuation |
1c79356b A |
323 | end |
324 | printf "\n" | |
325 | else | |
326 | printf "\n" | |
327 | end | |
1c79356b A |
328 | end |
329 | ||
330 | define showact | |
331 | showactheader | |
332 | showactint $arg0 0 | |
333 | end | |
334 | document showact | |
55e303ae | 335 | | Routine to print out the state of a specific thread. |
1c79356b A |
336 | | The following is the syntax: |
337 | | (gdb) showact <activation> | |
338 | end | |
339 | ||
340 | ||
341 | define showactstack | |
342 | showactheader | |
343 | showactint $arg0 1 | |
344 | end | |
345 | document showactstack | |
55e303ae | 346 | | Routine to print out the stack of a specific thread. |
1c79356b A |
347 | | The following is the syntax: |
348 | | (gdb) showactstack <activation> | |
349 | end | |
350 | ||
351 | ||
55e303ae | 352 | define showallthreads |
1c79356b | 353 | set $kgm_head_taskp = &default_pset.tasks |
9bccf70c | 354 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
355 | while $kgm_taskp != $kgm_head_taskp |
356 | showtaskheader | |
357 | showtaskint $kgm_taskp | |
358 | showactheader | |
55e303ae A |
359 | set $kgm_head_actp = &($kgm_taskp->threads) |
360 | set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) | |
1c79356b A |
361 | while $kgm_actp != $kgm_head_actp |
362 | showactint $kgm_actp 0 | |
55e303ae | 363 | set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) |
1c79356b A |
364 | end |
365 | printf "\n" | |
9bccf70c | 366 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
367 | end |
368 | end | |
55e303ae A |
369 | document showallthreads |
370 | | Routine to print out info about all threads in the system. | |
371 | | The following is the syntax: | |
372 | | (gdb) showallthreads | |
373 | end | |
374 | ||
375 | define showcurrentthreads | |
91447636 A |
376 | set $kgm_prp = processor_list |
377 | while $kgm_prp != 0 | |
378 | if ($kgm_prp)->active_thread != 0 | |
379 | set $kgm_actp = ($kgm_prp)->active_thread | |
55e303ae A |
380 | showtaskheader |
381 | showtaskint ($kgm_actp)->task | |
382 | showactheader | |
383 | showactint $kgm_actp 0 | |
384 | printf "\n" | |
385 | end | |
91447636 | 386 | set $kgm_prp = ($kgm_prp)->processor_list |
55e303ae A |
387 | end |
388 | end | |
389 | document showcurrentthreads | |
390 | | Routine to print out info about the thread running on each cpu. | |
1c79356b | 391 | | The following is the syntax: |
55e303ae | 392 | | (gdb) showcurrentthreads |
1c79356b A |
393 | end |
394 | ||
0c530ab8 | 395 | set $decode_wait_events = 0 |
1c79356b A |
396 | define showallstacks |
397 | set $kgm_head_taskp = &default_pset.tasks | |
9bccf70c | 398 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
399 | while $kgm_taskp != $kgm_head_taskp |
400 | showtaskheader | |
401 | showtaskint $kgm_taskp | |
55e303ae A |
402 | set $kgm_head_actp = &($kgm_taskp->threads) |
403 | set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) | |
1c79356b A |
404 | while $kgm_actp != $kgm_head_actp |
405 | showactheader | |
0c530ab8 A |
406 | if ($decode_wait_events > 0) |
407 | showactint $kgm_actp 1 | |
408 | else | |
409 | showactint $kgm_actp 2 | |
410 | end | |
55e303ae | 411 | set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) |
1c79356b A |
412 | end |
413 | printf "\n" | |
9bccf70c | 414 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
415 | end |
416 | end | |
0c530ab8 | 417 | |
1c79356b | 418 | document showallstacks |
55e303ae | 419 | | Routine to print out the stack for each thread in the system. |
1c79356b A |
420 | | The following is the syntax: |
421 | | (gdb) showallstacks | |
0c530ab8 A |
422 | | If the variable $decode_wait_events is non-zero, the routine attempts to |
423 | | interpret thread wait_events as kernel module offsets, which can add to | |
424 | | processing time. | |
1c79356b A |
425 | end |
426 | ||
55e303ae | 427 | define showcurrentstacks |
91447636 A |
428 | set $kgm_prp = processor_list |
429 | while $kgm_prp != 0 | |
430 | if ($kgm_prp)->active_thread != 0 | |
431 | set $kgm_actp = ($kgm_prp)->active_thread | |
55e303ae A |
432 | showtaskheader |
433 | showtaskint ($kgm_actp)->task | |
434 | showactheader | |
435 | showactint $kgm_actp 1 | |
436 | printf "\n" | |
437 | end | |
91447636 | 438 | set $kgm_prp = ($kgm_prp)->processor_list |
55e303ae A |
439 | end |
440 | end | |
0c530ab8 | 441 | |
55e303ae A |
442 | document showcurrentstacks |
443 | | Routine to print out the thread running on each cpu (incl. its stack) | |
444 | | The following is the syntax: | |
445 | | (gdb) showcurrentstacks | |
446 | end | |
447 | ||
9bccf70c A |
448 | define showwaiterheader |
449 | printf "waiters activation " | |
450 | printf "thread pri state wait_queue wait_event\n" | |
451 | end | |
452 | ||
453 | define showwaitqwaiters | |
454 | set $kgm_w_waitqp = (struct wait_queue *)$arg0 | |
455 | set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue) | |
456 | set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_linksp->next | |
457 | set $kgm_w_found = 0 | |
458 | while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp) | |
459 | if ($kgm_w_wqe->wqe_type != &_wait_queue_link) | |
460 | if !$kgm_w_found | |
461 | set $kgm_w_found = 1 | |
462 | showwaiterheader | |
463 | end | |
55e303ae | 464 | set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe |
91447636 | 465 | showactint $kgm_w_shuttle 0 |
9bccf70c A |
466 | end |
467 | set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_wqe->wqe_links.next | |
468 | end | |
469 | end | |
470 | ||
471 | define showwaitqwaitercount | |
472 | set $kgm_wc_waitqp = (struct wait_queue *)$arg0 | |
473 | set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue) | |
474 | set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_linksp->next | |
475 | set $kgm_wc_count = 0 | |
476 | while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp) | |
477 | if ($kgm_wc_wqe->wqe_type != &_wait_queue_link) | |
478 | set $kgm_wc_count = $kgm_wc_count + 1 | |
479 | end | |
480 | set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_wqe->wqe_links.next | |
481 | end | |
482 | printf "0x%08x ", $kgm_wc_count | |
483 | end | |
484 | ||
1c79356b | 485 | define showwaitqmembercount |
9bccf70c A |
486 | set $kgm_mc_waitqsetp = (struct wait_queue_set *)$arg0 |
487 | set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks) | |
488 | set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_setlinksp->next | |
489 | set $kgm_mc_count = 0 | |
490 | while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp) | |
491 | set $kgm_mc_count = $kgm_mc_count + 1 | |
492 | set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_wql->wql_setlinks.next | |
1c79356b | 493 | end |
9bccf70c | 494 | printf "0x%08x ", $kgm_mc_count |
1c79356b A |
495 | end |
496 | ||
497 | ||
9bccf70c A |
498 | define showwaitqmemberheader |
499 | printf "set-members wait_queue interlock " | |
500 | printf "pol type member_cnt waiter_cnt\n" | |
501 | end | |
502 | ||
1c79356b | 503 | define showwaitqmemberint |
9bccf70c A |
504 | set $kgm_m_waitqp = (struct wait_queue *)$arg0 |
505 | printf " 0x%08x ", $kgm_m_waitqp | |
506 | printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data | |
507 | if ($kgm_m_waitqp->wq_fifo) | |
508 | printf "Fifo " | |
1c79356b | 509 | else |
9bccf70c | 510 | printf "Prio " |
1c79356b | 511 | end |
9bccf70c A |
512 | if ($kgm_m_waitqp->wq_type == 0xf1d1) |
513 | printf "Set " | |
514 | showwaitqmembercount $kgm_m_waitqp | |
1c79356b | 515 | else |
9bccf70c | 516 | printf "Que 0x00000000 " |
1c79356b | 517 | end |
9bccf70c | 518 | showwaitqwaitercount $kgm_m_waitqp |
1c79356b A |
519 | printf "\n" |
520 | end | |
521 | ||
522 | ||
9bccf70c A |
523 | define showwaitqmemberofheader |
524 | printf "member-of wait_queue interlock " | |
525 | printf "pol type member_cnt waiter_cnt\n" | |
526 | end | |
527 | ||
528 | define showwaitqmemberof | |
529 | set $kgm_mo_waitqp = (struct wait_queue *)$arg0 | |
530 | set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue) | |
531 | set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_linksp->next | |
532 | set $kgm_mo_found = 0 | |
533 | while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp) | |
534 | if ($kgm_mo_wqe->wqe_type == &_wait_queue_link) | |
535 | if !$kgm_mo_found | |
536 | set $kgm_mo_found = 1 | |
537 | showwaitqmemberofheader | |
538 | end | |
539 | set $kgm_mo_wqlp = (struct wait_queue_link *)$kgm_mo_wqe | |
540 | set $kgm_mo_wqsetp = (struct wait_queue *)($kgm_mo_wqlp->wql_setqueue) | |
541 | showwaitqmemberint $kgm_mo_wqsetp | |
542 | end | |
543 | set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_wqe->wqe_links.next | |
544 | end | |
545 | end | |
546 | ||
1c79356b | 547 | define showwaitqmembers |
9bccf70c A |
548 | set $kgm_ms_waitqsetp = (struct wait_queue_set *)$arg0 |
549 | set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks) | |
550 | set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_setlinksp->next | |
551 | set $kgm_ms_found = 0 | |
552 | while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp) | |
553 | set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue | |
554 | if !$kgm_ms_found | |
1c79356b | 555 | showwaitqmemberheader |
9bccf70c | 556 | set $kgm_ms_found = 1 |
1c79356b | 557 | end |
9bccf70c A |
558 | showwaitqmemberint $kgm_ms_waitqp |
559 | set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_wql->wql_setlinks.next | |
1c79356b A |
560 | end |
561 | end | |
562 | ||
9bccf70c A |
563 | define showwaitqheader |
564 | printf "wait_queue ref_count interlock " | |
565 | printf "pol type member_cnt waiter_cnt\n" | |
566 | end | |
567 | ||
568 | define showwaitqint | |
569 | set $kgm_waitqp = (struct wait_queue *)$arg0 | |
570 | printf "0x%08x ", $kgm_waitqp | |
571 | if ($kgm_waitqp->wq_type == 0xf1d1) | |
572 | printf "0x%08x ", ((struct wait_queue_set *)$kgm_waitqp)->wqs_refcount | |
573 | else | |
574 | printf "0x00000000 " | |
575 | end | |
576 | printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data | |
577 | if ($kgm_waitqp->wq_fifo) | |
578 | printf "Fifo " | |
579 | else | |
580 | printf "Prio " | |
581 | end | |
582 | if ($kgm_waitqp->wq_type == 0xf1d1) | |
583 | printf "Set " | |
584 | showwaitqmembercount $kgm_waitqp | |
585 | else | |
586 | printf "Que 0x00000000 " | |
587 | end | |
588 | showwaitqwaitercount $kgm_waitqp | |
589 | printf "\n" | |
590 | end | |
591 | ||
1c79356b | 592 | define showwaitq |
9bccf70c | 593 | set $kgm_waitq1p = (wait_queue_t)$arg0 |
1c79356b | 594 | showwaitqheader |
9bccf70c A |
595 | showwaitqint $kgm_waitq1p |
596 | if ($kgm_waitq1p->wq_type == 0xf1d1) | |
597 | showwaitqmembers $kgm_waitq1p | |
598 | else | |
599 | showwaitqmemberof $kgm_waitq1p | |
1c79356b | 600 | end |
9bccf70c | 601 | showwaitqwaiters $kgm_waitq1p |
1c79356b A |
602 | end |
603 | ||
604 | define showmapheader | |
605 | printf "vm_map pmap vm_size " | |
606 | printf "#ents rpage hint first_free\n" | |
607 | end | |
608 | ||
609 | define showvmeheader | |
91447636 A |
610 | printf " entry start " |
611 | printf " prot #page object offset\n" | |
1c79356b A |
612 | end |
613 | ||
614 | define showvmint | |
615 | set $kgm_mapp = (vm_map_t)$arg0 | |
616 | set $kgm_map = *$kgm_mapp | |
617 | printf "0x%08x ", $arg0 | |
618 | printf "0x%08x ", $kgm_map.pmap | |
619 | printf "0x%08x ", $kgm_map.size | |
620 | printf "%3d ", $kgm_map.hdr.nentries | |
91447636 A |
621 | if $kgm_map.pmap |
622 | printf "%5d ", $kgm_map.pmap->stats.resident_count | |
623 | else | |
624 | printf "<n/a> " | |
625 | end | |
1c79356b A |
626 | printf "0x%08x ", $kgm_map.hint |
627 | printf "0x%08x\n", $kgm_map.first_free | |
628 | if $arg1 != 0 | |
629 | showvmeheader | |
630 | set $kgm_head_vmep = &($kgm_mapp->hdr.links) | |
631 | set $kgm_vmep = $kgm_map.hdr.links.next | |
632 | while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep)) | |
633 | set $kgm_vme = *$kgm_vmep | |
91447636 A |
634 | printf " 0x%08x ", $kgm_vmep |
635 | printf "0x%016llx ", $kgm_vme.links.start | |
1c79356b A |
636 | printf "%1x", $kgm_vme.protection |
637 | printf "%1x", $kgm_vme.max_protection | |
638 | if $kgm_vme.inheritance == 0x0 | |
639 | printf "S" | |
640 | end | |
641 | if $kgm_vme.inheritance == 0x1 | |
642 | printf "C" | |
643 | end | |
644 | if $kgm_vme.inheritance == 0x2 | |
645 | printf "-" | |
646 | end | |
647 | if $kgm_vme.inheritance == 0x3 | |
648 | printf "D" | |
649 | end | |
650 | if $kgm_vme.is_sub_map | |
651 | printf "s " | |
652 | else | |
653 | if $kgm_vme.needs_copy | |
654 | printf "n " | |
655 | else | |
656 | printf " " | |
657 | end | |
658 | end | |
659 | printf "%5d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12 | |
660 | printf "0x%08x ", $kgm_vme.object.vm_object | |
91447636 | 661 | printf "0x%016llx\n", $kgm_vme.offset |
1c79356b A |
662 | set $kgm_vmep = $kgm_vme.links.next |
663 | end | |
664 | end | |
665 | printf "\n" | |
666 | end | |
667 | ||
668 | ||
669 | define showmapvme | |
670 | showmapheader | |
671 | showvmint $arg0 1 | |
672 | end | |
673 | document showmapvme | |
674 | | Routine to print out a summary listing of all the entries in a vm_map | |
675 | | The following is the syntax: | |
676 | | (gdb) showmapvme <vm_map> | |
677 | end | |
678 | ||
679 | ||
680 | define showmap | |
681 | showmapheader | |
682 | showvmint $arg0 0 | |
683 | end | |
684 | document showmap | |
55e303ae | 685 | | Routine to print out info about the specified vm_map |
1c79356b A |
686 | | The following is the syntax: |
687 | | (gdb) showmap <vm_map> | |
688 | end | |
689 | ||
690 | define showallvm | |
691 | set $kgm_head_taskp = &default_pset.tasks | |
9bccf70c | 692 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
693 | while $kgm_taskp != $kgm_head_taskp |
694 | showtaskheader | |
695 | showmapheader | |
696 | showtaskint $kgm_taskp | |
697 | showvmint $kgm_taskp->map 0 | |
9bccf70c | 698 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
699 | end |
700 | end | |
701 | document showallvm | |
702 | | Routine to print a summary listing of all the vm maps | |
703 | | The following is the syntax: | |
704 | | (gdb) showallvm | |
705 | end | |
706 | ||
707 | ||
708 | define showallvme | |
709 | set $kgm_head_taskp = &default_pset.tasks | |
9bccf70c | 710 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
711 | while $kgm_taskp != $kgm_head_taskp |
712 | showtaskheader | |
713 | showmapheader | |
714 | showtaskint $kgm_taskp | |
715 | showvmint $kgm_taskp->map 1 | |
9bccf70c | 716 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
717 | end |
718 | end | |
719 | document showallvme | |
720 | | Routine to print a summary listing of all the vm map entries | |
721 | | The following is the syntax: | |
722 | | (gdb) showallvme | |
723 | end | |
724 | ||
725 | ||
726 | define showipcheader | |
727 | printf "ipc_space is_table table_next " | |
728 | printf "flags tsize splaytree splaybase\n" | |
729 | end | |
730 | ||
731 | define showipceheader | |
732 | printf " name object " | |
733 | printf "rite urefs destname destination\n" | |
734 | end | |
735 | ||
736 | define showipceint | |
737 | set $kgm_ie = *(ipc_entry_t)$arg0 | |
738 | printf " 0x%08x ", $arg1 | |
739 | printf "0x%08x ", $kgm_ie.ie_object | |
740 | if $kgm_ie.ie_bits & 0x00100000 | |
741 | printf "Dead " | |
742 | printf "%5d\n", $kgm_ie.ie_bits & 0xffff | |
743 | else | |
744 | if $kgm_ie.ie_bits & 0x00080000 | |
745 | printf "SET " | |
746 | printf "%5d\n", $kgm_ie.ie_bits & 0xffff | |
747 | else | |
748 | if $kgm_ie.ie_bits & 0x00010000 | |
749 | if $kgm_ie.ie_bits & 0x00020000 | |
750 | printf " SR" | |
751 | else | |
752 | printf " S" | |
753 | end | |
754 | else | |
755 | if $kgm_ie.ie_bits & 0x00020000 | |
756 | printf " R" | |
757 | end | |
758 | end | |
759 | if $kgm_ie.ie_bits & 0x00040000 | |
760 | printf " O" | |
761 | end | |
762 | if $kgm_ie.index.request | |
763 | printf "n" | |
764 | else | |
765 | printf " " | |
766 | end | |
767 | if $kgm_ie.ie_bits & 0x00800000 | |
768 | printf "c" | |
769 | else | |
770 | printf " " | |
771 | end | |
772 | printf "%5d ", $kgm_ie.ie_bits & 0xffff | |
773 | showportdest $kgm_ie.ie_object | |
774 | end | |
775 | end | |
776 | end | |
777 | ||
778 | define showipcint | |
779 | set $kgm_isp = (ipc_space_t)$arg0 | |
780 | set $kgm_is = *$kgm_isp | |
781 | printf "0x%08x ", $arg0 | |
782 | printf "0x%08x ", $kgm_is.is_table | |
783 | printf "0x%08x ", $kgm_is.is_table_next | |
784 | if $kgm_is.is_growing != 0 | |
785 | printf "G" | |
786 | else | |
787 | printf " " | |
788 | end | |
789 | if $kgm_is.is_fast != 0 | |
790 | printf "F" | |
791 | else | |
792 | printf " " | |
793 | end | |
794 | if $kgm_is.is_active != 0 | |
795 | printf "A " | |
796 | else | |
797 | printf " " | |
798 | end | |
799 | printf "%5d ", $kgm_is.is_table_size | |
800 | printf "0x%08x ", $kgm_is.is_tree_total | |
801 | printf "0x%08x\n", &$kgm_isp->is_tree | |
802 | if $arg1 != 0 | |
803 | showipceheader | |
804 | set $kgm_iindex = 0 | |
805 | set $kgm_iep = $kgm_is.is_table | |
806 | set $kgm_destspacep = (ipc_space_t)0 | |
807 | while ( $kgm_iindex < $kgm_is.is_table_size ) | |
808 | set $kgm_ie = *$kgm_iep | |
809 | if $kgm_ie.ie_bits & 0x001f0000 | |
810 | set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24)) | |
811 | showipceint $kgm_iep $kgm_name | |
812 | end | |
813 | set $kgm_iindex = $kgm_iindex + 1 | |
814 | set $kgm_iep = &($kgm_is.is_table[$kgm_iindex]) | |
815 | end | |
816 | if $kgm_is.is_tree_total | |
817 | printf "Still need to write tree traversal\n" | |
818 | end | |
819 | end | |
820 | printf "\n" | |
821 | end | |
822 | ||
823 | ||
824 | define showipc | |
825 | set $kgm_isp = (ipc_space_t)$arg0 | |
826 | showipcheader | |
827 | showipcint $kgm_isp 0 | |
828 | end | |
829 | document showipc | |
830 | | Routine to print the status of the specified ipc space | |
831 | | The following is the syntax: | |
832 | | (gdb) showipc <ipc_space> | |
833 | end | |
834 | ||
835 | define showrights | |
836 | set $kgm_isp = (ipc_space_t)$arg0 | |
837 | showipcheader | |
838 | showipcint $kgm_isp 1 | |
839 | end | |
840 | document showrights | |
841 | | Routine to print a summary list of all the rights in a specified ipc space | |
842 | | The following is the syntax: | |
843 | | (gdb) showrights <ipc_space> | |
844 | end | |
845 | ||
846 | ||
847 | define showtaskipc | |
848 | set $kgm_taskp = (task_t)$arg0 | |
849 | showtaskheader | |
850 | showipcheader | |
851 | showtaskint $kgm_taskp | |
852 | showipcint $kgm_taskp->itk_space 0 | |
853 | end | |
854 | document showtaskipc | |
55e303ae | 855 | | Routine to print info about the ipc space for a task |
1c79356b A |
856 | | The following is the syntax: |
857 | | (gdb) showtaskipc <task> | |
858 | end | |
859 | ||
860 | ||
861 | define showtaskrights | |
862 | set $kgm_taskp = (task_t)$arg0 | |
863 | showtaskheader | |
864 | showipcheader | |
865 | showtaskint $kgm_taskp | |
866 | showipcint $kgm_taskp->itk_space 1 | |
867 | end | |
868 | document showtaskrights | |
55e303ae | 869 | | Routine to print info about the ipc rights for a task |
1c79356b A |
870 | | The following is the syntax: |
871 | | (gdb) showtaskrights <task> | |
872 | end | |
873 | ||
874 | define showallipc | |
875 | set $kgm_head_taskp = &default_pset.tasks | |
91447636 A |
876 | set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) |
877 | while $kgm_cur_taskp != $kgm_head_taskp | |
1c79356b A |
878 | showtaskheader |
879 | showipcheader | |
91447636 A |
880 | showtaskint $kgm_cur_taskp |
881 | showipcint $kgm_cur_taskp->itk_space 0 | |
882 | set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->pset_tasks.next) | |
1c79356b A |
883 | end |
884 | end | |
885 | document showallipc | |
886 | | Routine to print a summary listing of all the ipc spaces | |
887 | | The following is the syntax: | |
888 | | (gdb) showallipc | |
889 | end | |
890 | ||
891 | ||
892 | define showallrights | |
893 | set $kgm_head_taskp = &default_pset.tasks | |
91447636 A |
894 | set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) |
895 | while $kgm_cur_taskp != $kgm_head_taskp | |
1c79356b A |
896 | showtaskheader |
897 | showipcheader | |
91447636 A |
898 | showtaskint $kgm_cur_taskp |
899 | showipcint $kgm_cur_taskp->itk_space 1 | |
900 | set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->pset_tasks.next) | |
1c79356b A |
901 | end |
902 | end | |
903 | document showallrights | |
904 | | Routine to print a summary listing of all the ipc rights | |
905 | | The following is the syntax: | |
906 | | (gdb) showallrights | |
907 | end | |
908 | ||
909 | ||
910 | define showtaskvm | |
911 | set $kgm_taskp = (task_t)$arg0 | |
912 | showtaskheader | |
913 | showmapheader | |
914 | showtaskint $kgm_taskp | |
915 | showvmint $kgm_taskp->map 0 | |
916 | end | |
917 | document showtaskvm | |
55e303ae | 918 | | Routine to print out info about a task's vm_map |
1c79356b A |
919 | | The following is the syntax: |
920 | | (gdb) showtaskvm <task> | |
921 | end | |
922 | ||
923 | define showtaskvme | |
924 | set $kgm_taskp = (task_t)$arg0 | |
925 | showtaskheader | |
926 | showmapheader | |
927 | showtaskint $kgm_taskp | |
928 | showvmint $kgm_taskp->map 1 | |
929 | end | |
930 | document showtaskvme | |
55e303ae | 931 | | Routine to print out info about a task's vm_map_entries |
1c79356b A |
932 | | The following is the syntax: |
933 | | (gdb) showtaskvme <task> | |
934 | end | |
935 | ||
936 | ||
937 | define showtaskheader | |
938 | printf "task vm_map ipc_space #acts " | |
939 | showprocheader | |
940 | end | |
941 | ||
942 | ||
943 | define showtaskint | |
9bccf70c | 944 | set $kgm_task = *(struct task *)$arg0 |
1c79356b A |
945 | printf "0x%08x ", $arg0 |
946 | printf "0x%08x ", $kgm_task.map | |
947 | printf "0x%08x ", $kgm_task.itk_space | |
55e303ae | 948 | printf "%3d ", $kgm_task.thread_count |
1c79356b A |
949 | showprocint $kgm_task.bsd_info |
950 | end | |
951 | ||
952 | define showtask | |
953 | showtaskheader | |
954 | showtaskint $arg0 | |
955 | end | |
956 | document showtask | |
957 | | Routine to print out info about a task. | |
958 | | The following is the syntax: | |
959 | | (gdb) showtask <task> | |
960 | end | |
961 | ||
962 | ||
55e303ae | 963 | define showtaskthreads |
1c79356b | 964 | showtaskheader |
9bccf70c | 965 | set $kgm_taskp = (struct task *)$arg0 |
1c79356b A |
966 | showtaskint $kgm_taskp |
967 | showactheader | |
55e303ae A |
968 | set $kgm_head_actp = &($kgm_taskp->threads) |
969 | set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) | |
1c79356b A |
970 | while $kgm_actp != $kgm_head_actp |
971 | showactint $kgm_actp 0 | |
55e303ae | 972 | set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) |
1c79356b A |
973 | end |
974 | end | |
55e303ae A |
975 | document showtaskthreads |
976 | | Routine to print info about the threads in a task. | |
1c79356b | 977 | | The following is the syntax: |
55e303ae | 978 | | (gdb) showtaskthreads <task> |
1c79356b A |
979 | end |
980 | ||
981 | ||
982 | define showtaskstacks | |
983 | showtaskheader | |
9bccf70c | 984 | set $kgm_taskp = (struct task *)$arg0 |
1c79356b | 985 | showtaskint $kgm_taskp |
55e303ae A |
986 | set $kgm_head_actp = &($kgm_taskp->threads) |
987 | set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) | |
1c79356b A |
988 | while $kgm_actp != $kgm_head_actp |
989 | showactheader | |
990 | showactint $kgm_actp 1 | |
55e303ae | 991 | set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) |
1c79356b A |
992 | end |
993 | end | |
994 | document showtaskstacks | |
55e303ae | 995 | | Routine to print out the stack for each thread in a task. |
1c79356b A |
996 | | The following is the syntax: |
997 | | (gdb) showtaskstacks <task> | |
998 | end | |
999 | ||
1000 | ||
1001 | define showalltasks | |
1002 | showtaskheader | |
1003 | set $kgm_head_taskp = &default_pset.tasks | |
9bccf70c | 1004 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
1005 | while $kgm_taskp != $kgm_head_taskp |
1006 | showtaskint $kgm_taskp | |
9bccf70c | 1007 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
1008 | end |
1009 | end | |
1010 | document showalltasks | |
1011 | | Routine to print a summary listing of all the tasks | |
1012 | | The following is the syntax: | |
1013 | | (gdb) showalltasks | |
1014 | end | |
1015 | ||
1016 | ||
1017 | define showprocheader | |
1018 | printf " pid proc command\n" | |
1019 | end | |
1020 | ||
1021 | define showprocint | |
1022 | set $kgm_procp = (struct proc *)$arg0 | |
1023 | if $kgm_procp != 0 | |
1024 | printf "%5d ", $kgm_procp->p_pid | |
1025 | printf "0x%08x ", $kgm_procp | |
1026 | printf "%s\n", $kgm_procp->p_comm | |
1027 | else | |
1028 | printf " *0* 0x00000000 --\n" | |
1029 | end | |
1030 | end | |
1031 | ||
1032 | define showpid | |
1033 | showtaskheader | |
1034 | set $kgm_head_taskp = &default_pset.tasks | |
9bccf70c | 1035 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) |
1c79356b A |
1036 | while $kgm_taskp != $kgm_head_taskp |
1037 | set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info | |
1038 | if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0)) | |
1039 | showtaskint $kgm_taskp | |
1040 | set $kgm_taskp = $kgm_head_taskp | |
1041 | else | |
9bccf70c | 1042 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) |
1c79356b A |
1043 | end |
1044 | end | |
1045 | end | |
1046 | document showpid | |
1047 | | Routine to print a single process by pid | |
1048 | | The following is the syntax: | |
1049 | | (gdb) showpid <pid> | |
1050 | end | |
1051 | ||
1052 | define showproc | |
1053 | showtaskheader | |
1054 | set $kgm_procp = (struct proc *)$arg0 | |
1055 | showtaskint $kgm_procp->task $arg1 $arg2 | |
1056 | end | |
1057 | ||
1058 | ||
1059 | define kdb | |
1060 | set switch_debugger=1 | |
1061 | continue | |
1062 | end | |
1063 | document kdb | |
1064 | | kdb - Switch to the inline kernel debugger | |
1065 | | | |
1066 | | usage: kdb | |
1067 | | | |
1068 | | The kdb macro allows you to invoke the inline kernel debugger. | |
1069 | end | |
1070 | ||
1071 | define showpsetheader | |
1072 | printf "portset waitqueue recvname " | |
1073 | printf "flags refs recvname process\n" | |
1074 | end | |
1075 | ||
1076 | define showportheader | |
1077 | printf "port mqueue recvname " | |
1078 | printf "flags refs recvname process\n" | |
1079 | end | |
1080 | ||
1081 | define showportmemberheader | |
9bccf70c | 1082 | printf "members port recvname " |
1c79356b A |
1083 | printf "flags refs mqueue msgcount\n" |
1084 | end | |
1085 | ||
1086 | define showkmsgheader | |
9bccf70c | 1087 | printf "messages kmsg size " |
1c79356b A |
1088 | printf "disp msgid remote-port local-port\n" |
1089 | end | |
1090 | ||
1091 | define showkmsgint | |
1092 | printf " 0x%08x ", $arg0 | |
1093 | set $kgm_kmsgh = ((ipc_kmsg_t)$arg0)->ikm_header | |
1094 | printf "0x%08x ", $kgm_kmsgh.msgh_size | |
1095 | if (($kgm_kmsgh.msgh_bits & 0xff) == 19) | |
1096 | printf "rC" | |
1097 | else | |
1098 | printf "rM" | |
1099 | end | |
1100 | if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 < 8)) | |
1101 | printf "lC" | |
1102 | else | |
1103 | printf "lM" | |
1104 | end | |
1105 | if ($kgm_kmsgh.msgh_bits & 0xf0000000) | |
1106 | printf "c" | |
1107 | else | |
1108 | printf "s" | |
1109 | end | |
9bccf70c | 1110 | printf "%5d ", $kgm_kmsgh.msgh_id |
1c79356b A |
1111 | printf "0x%08x ", $kgm_kmsgh.msgh_remote_port |
1112 | printf "0x%08x\n", $kgm_kmsgh.msgh_local_port | |
1113 | end | |
1114 | ||
1115 | ||
1116 | ||
1117 | define showkobject | |
9bccf70c | 1118 | set $kgm_portp = (struct ipc_port *)$arg0 |
1c79356b A |
1119 | printf "0x%08x kobject(", $kgm_portp->ip_kobject |
1120 | set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff) | |
1121 | if ($kgm_kotype == 1) | |
1122 | printf "THREAD" | |
1123 | end | |
1124 | if ($kgm_kotype == 2) | |
1125 | printf "TASK" | |
1126 | end | |
1127 | if ($kgm_kotype == 3) | |
1128 | printf "HOST" | |
1129 | end | |
1130 | if ($kgm_kotype == 4) | |
1131 | printf "HOST_PRIV" | |
1132 | end | |
1133 | if ($kgm_kotype == 5) | |
1134 | printf "PROCESSOR" | |
1135 | end | |
1136 | if ($kgm_kotype == 6) | |
1137 | printf "PSET" | |
1138 | end | |
1139 | if ($kgm_kotype == 7) | |
1140 | printf "PSET_NAME" | |
1141 | end | |
1142 | if ($kgm_kotype == 8) | |
1143 | printf "TIMER" | |
1144 | end | |
1145 | if ($kgm_kotype == 9) | |
1146 | printf "PAGER_REQ" | |
1147 | end | |
1148 | if ($kgm_kotype == 10) | |
1149 | printf "DEVICE" | |
1150 | end | |
1151 | if ($kgm_kotype == 11) | |
1152 | printf "XMM_OBJECT" | |
1153 | end | |
1154 | if ($kgm_kotype == 12) | |
1155 | printf "XMM_PAGER" | |
1156 | end | |
1157 | if ($kgm_kotype == 13) | |
1158 | printf "XMM_KERNEL" | |
1159 | end | |
1160 | if ($kgm_kotype == 14) | |
1161 | printf "XMM_REPLY" | |
1162 | end | |
1163 | if ($kgm_kotype == 15) | |
1164 | printf "NOTDEF 15" | |
1165 | end | |
1166 | if ($kgm_kotype == 16) | |
1167 | printf "NOTDEF 16" | |
1168 | end | |
1169 | if ($kgm_kotype == 17) | |
1170 | printf "HOST_SEC" | |
1171 | end | |
1172 | if ($kgm_kotype == 18) | |
1173 | printf "LEDGER" | |
1174 | end | |
1175 | if ($kgm_kotype == 19) | |
1176 | printf "MASTER_DEV" | |
1177 | end | |
1178 | if ($kgm_kotype == 20) | |
1179 | printf "ACTIVATION" | |
1180 | end | |
1181 | if ($kgm_kotype == 21) | |
1182 | printf "SUBSYSTEM" | |
1183 | end | |
1184 | if ($kgm_kotype == 22) | |
1185 | printf "IO_DONE_QUE" | |
1186 | end | |
1187 | if ($kgm_kotype == 23) | |
1188 | printf "SEMAPHORE" | |
1189 | end | |
1190 | if ($kgm_kotype == 24) | |
1191 | printf "LOCK_SET" | |
1192 | end | |
1193 | if ($kgm_kotype == 25) | |
1194 | printf "CLOCK" | |
1195 | end | |
1196 | if ($kgm_kotype == 26) | |
1197 | printf "CLOCK_CTRL" | |
1198 | end | |
1199 | if ($kgm_kotype == 27) | |
1200 | printf "IOKIT_SPARE" | |
1201 | end | |
1202 | if ($kgm_kotype == 28) | |
1203 | printf "NAMED_MEM" | |
1204 | end | |
1205 | if ($kgm_kotype == 29) | |
1206 | printf "IOKIT_CON" | |
1207 | end | |
1208 | if ($kgm_kotype == 30) | |
1209 | printf "IOKIT_OBJ" | |
1210 | end | |
1211 | if ($kgm_kotype == 31) | |
1212 | printf "UPL" | |
1213 | end | |
1214 | printf ")\n" | |
1215 | end | |
1216 | ||
1217 | define showportdestproc | |
9bccf70c | 1218 | set $kgm_portp = (struct ipc_port *)$arg0 |
1c79356b A |
1219 | set $kgm_spacep = $kgm_portp->data.receiver |
1220 | # check against the previous cached value - this is slow | |
1221 | if ($kgm_spacep != $kgm_destspacep) | |
1222 | set $kgm_destprocp = (struct proc *)0 | |
1223 | set $kgm_head_taskp = &default_pset.tasks | |
91447636 A |
1224 | set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next) |
1225 | while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp)) | |
1226 | set $kgm_destspacep = $kgm_desttaskp->itk_space | |
1c79356b | 1227 | if ($kgm_destspacep == $kgm_spacep) |
91447636 | 1228 | set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info |
1c79356b | 1229 | else |
91447636 | 1230 | set $kgm_desttaskp = (struct task *)($kgm_desttaskp->pset_tasks.next) |
1c79356b A |
1231 | end |
1232 | end | |
1233 | end | |
1234 | if $kgm_destprocp != 0 | |
1235 | printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid | |
1236 | else | |
91447636 | 1237 | printf "task 0x%08x\n", $kgm_desttaskp |
1c79356b A |
1238 | end |
1239 | end | |
1240 | ||
1241 | define showportdest | |
9bccf70c | 1242 | set $kgm_portp = (struct ipc_port *)$arg0 |
1c79356b A |
1243 | set $kgm_spacep = $kgm_portp->data.receiver |
1244 | if ($kgm_spacep == ipc_space_kernel) | |
1245 | showkobject $kgm_portp | |
1246 | else | |
1247 | if ($kgm_portp->ip_object.io_bits & 0x80000000) | |
1248 | printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name | |
1249 | showportdestproc $kgm_portp | |
1250 | else | |
1251 | printf "0x%08x inactive-port\n", $kgm_portp | |
1252 | end | |
1253 | end | |
1254 | end | |
1255 | ||
1256 | define showportmember | |
1257 | printf " 0x%08x ", $arg0 | |
9bccf70c | 1258 | set $kgm_portp = (struct ipc_port *)$arg0 |
1c79356b A |
1259 | printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name |
1260 | if ($kgm_portp->ip_object.io_bits & 0x80000000) | |
1261 | printf "A" | |
1262 | else | |
1263 | printf " " | |
1264 | end | |
1265 | if ($kgm_portp->ip_object.io_bits & 0x7fff0000) | |
1266 | printf "Set " | |
1267 | else | |
1268 | printf "Port" | |
1269 | end | |
1270 | printf "%5d ", $kgm_portp->ip_object.io_references | |
1271 | printf "0x%08x ", &($kgm_portp->ip_messages) | |
1272 | printf "0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount | |
1273 | end | |
1274 | ||
1275 | define showportint | |
1276 | printf "0x%08x ", $arg0 | |
9bccf70c | 1277 | set $kgm_portp = (struct ipc_port *)$arg0 |
1c79356b A |
1278 | printf "0x%08x ", &($kgm_portp->ip_messages) |
1279 | printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name | |
1280 | if ($kgm_portp->ip_object.io_bits & 0x80000000) | |
1281 | printf "A" | |
1282 | else | |
1283 | printf "D" | |
1284 | end | |
1285 | printf "Port" | |
1286 | printf "%5d ", $kgm_portp->ip_object.io_references | |
9bccf70c | 1287 | set $kgm_destspacep = (struct ipc_space *)0 |
1c79356b A |
1288 | showportdest $kgm_portp |
1289 | set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base | |
1290 | if $arg1 && $kgm_kmsgp | |
1291 | showkmsgheader | |
1292 | showkmsgint $kgm_kmsgp | |
1293 | set $kgm_kmsgheadp = $kgm_kmsgp | |
1294 | set $kgm_kmsgp = $kgm_kmsgp->ikm_next | |
1295 | while $kgm_kmsgp != $kgm_kmsgheadp | |
1296 | showkmsgint $kgm_kmsgp | |
1297 | set $kgm_kmsgp = $kgm_kmsgp->ikm_next | |
1298 | end | |
1299 | end | |
1300 | end | |
1301 | ||
1302 | define showpsetint | |
1303 | printf "0x%08x ", $arg0 | |
9bccf70c | 1304 | set $kgm_psetp = (struct ipc_pset *)$arg0 |
1c79356b A |
1305 | printf "0x%08x ", &($kgm_psetp->ips_messages) |
1306 | printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name | |
1307 | if ($kgm_psetp->ips_object.io_bits & 0x80000000) | |
1308 | printf "A" | |
1309 | else | |
1310 | printf "D" | |
1311 | end | |
1312 | printf "Set " | |
1313 | printf "%5d ", $kgm_psetp->ips_object.io_references | |
9bccf70c A |
1314 | printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name |
1315 | set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.set_queue.wqs_setlinks) | |
1316 | set $kgm_wql = (struct wait_queue_link *)$kgm_setlinksp->next | |
1c79356b | 1317 | set $kgm_found = 0 |
9bccf70c A |
1318 | while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp) |
1319 | set $kgm_portp = (struct ipc_port *)((int)($kgm_wql->wql_element->wqe_queue) - ((int)$kgm_portoff)) | |
1c79356b | 1320 | if !$kgm_found |
9bccf70c A |
1321 | set $kgm_destspacep = (struct ipc_space *)0 |
1322 | showportdestproc $kgm_portp | |
1c79356b A |
1323 | showportmemberheader |
1324 | set $kgm_found = 1 | |
1325 | end | |
1326 | showportmember $kgm_portp 0 | |
9bccf70c | 1327 | set $kgm_wql = (struct wait_queue_link *)$kgm_wql->wql_setlinks.next |
1c79356b | 1328 | end |
9bccf70c A |
1329 | if !$kgm_found |
1330 | printf "--n/e--\n" | |
1c79356b A |
1331 | end |
1332 | end | |
1333 | ||
1334 | define showpset | |
1335 | showpsetheader | |
1336 | showpsetint $arg0 1 | |
1337 | end | |
1338 | ||
1339 | define showport | |
1340 | showportheader | |
1341 | showportint $arg0 1 | |
1342 | end | |
1343 | ||
1344 | define showipcobject | |
1345 | set $kgm_object = (ipc_object_t)$arg0 | |
1346 | if ($kgm_objectp->io_bits & 0x7fff0000) | |
1347 | showpset $kgm_objectp | |
1348 | else | |
1349 | showport $kgm_objectp | |
1350 | end | |
1351 | end | |
1352 | ||
1353 | define showmqueue | |
9bccf70c A |
1354 | set $kgm_mqueue = *(struct ipc_mqueue *)$arg0 |
1355 | set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages) | |
1356 | set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages) | |
1357 | if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d1) | |
1c79356b A |
1358 | set $kgm_pset = (((int)$arg0) - ((int)$kgm_psetoff)) |
1359 | showpsetheader | |
1360 | showpsetint $kgm_pset 1 | |
9bccf70c A |
1361 | end |
1362 | if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d0) | |
1c79356b A |
1363 | showportheader |
1364 | set $kgm_port = (((int)$arg0) - ((int)$kgm_portoff)) | |
1365 | showportint $kgm_port 1 | |
1366 | end | |
1367 | end | |
1368 | ||
1369 | define zprint_one | |
1370 | set $kgm_zone = (struct zone *)$arg0 | |
1371 | ||
1372 | printf "0x%08x ", $kgm_zone | |
1373 | printf "%8d ",$kgm_zone->count | |
1374 | printf "%8x ",$kgm_zone->cur_size | |
1375 | printf "%8x ",$kgm_zone->max_size | |
1376 | printf "%6d ",$kgm_zone->elem_size | |
1377 | printf "%8x ",$kgm_zone->alloc_size | |
1378 | printf "%s ",$kgm_zone->zone_name | |
1379 | ||
1380 | if ($kgm_zone->exhaustible) | |
1381 | printf "H" | |
1382 | end | |
1383 | if ($kgm_zone->collectable) | |
1384 | printf "C" | |
1385 | end | |
1386 | if ($kgm_zone->expandable) | |
1387 | printf "X" | |
1388 | end | |
1389 | printf "\n" | |
1390 | end | |
1391 | ||
1392 | ||
1393 | define zprint | |
1394 | printf "ZONE COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n" | |
1395 | set $kgm_zone_ptr = (struct zone *)first_zone | |
1396 | while ($kgm_zone_ptr != 0) | |
1397 | zprint_one $kgm_zone_ptr | |
1398 | set $kgm_zone_ptr = $kgm_zone_ptr->next_zone | |
1399 | end | |
1400 | printf "\n" | |
1401 | end | |
1402 | document zprint | |
1403 | | Routine to print a summary listing of all the kernel zones | |
1404 | | The following is the syntax: | |
1405 | | (gdb) zprint | |
1406 | end | |
1407 | ||
91447636 A |
1408 | define showmtxgrp |
1409 | set $kgm_mtxgrp = (lck_grp_t *)$arg0 | |
1410 | ||
1411 | if ($kgm_mtxgrp->lck_grp_mtxcnt) | |
1412 | printf "0x%08x ", $kgm_mtxgrp | |
1413 | printf "%8d ",$kgm_mtxgrp->lck_grp_mtxcnt | |
1414 | printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt | |
1415 | printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt | |
1416 | printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt | |
1417 | printf "%s ",&$kgm_mtxgrp->lck_grp_name | |
1418 | printf "\n" | |
1419 | end | |
1420 | end | |
1421 | ||
1422 | ||
1423 | define showallmtx | |
1424 | printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" | |
1425 | set $kgm_mtxgrp_ptr = (lck_grp_t *)&lck_grp_queue | |
1426 | set $kgm_mtxgrp_ptr = (lck_grp_t *)$kgm_mtxgrp_ptr->lck_grp_link.next | |
1427 | while ($kgm_mtxgrp_ptr != (lck_grp_t *)&lck_grp_queue) | |
1428 | showmtxgrp $kgm_mtxgrp_ptr | |
1429 | set $kgm_mtxgrp_ptr = (lck_grp_t *)$kgm_mtxgrp_ptr->lck_grp_link.next | |
1430 | end | |
1431 | printf "\n" | |
1432 | end | |
1433 | document showallmtx | |
1434 | | Routine to print a summary listing of all mutexes | |
1435 | | The following is the syntax: | |
1436 | | (gdb) showallmtx | |
1437 | end | |
1438 | ||
1439 | define showrwlckgrp | |
1440 | set $kgm_rwlckgrp = (lck_grp_t *)$arg0 | |
1441 | ||
1442 | if ($kgm_rwlckgrp->lck_grp_rwcnt) | |
1443 | printf "0x%08x ", $kgm_rwlckgrp | |
1444 | printf "%8d ",$kgm_rwlckgrp->lck_grp_rwcnt | |
1445 | printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt | |
1446 | printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt | |
1447 | printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt | |
1448 | printf "%s ",&$kgm_rwlckgrp->lck_grp_name | |
1449 | printf "\n" | |
1450 | end | |
1451 | end | |
1452 | ||
1453 | ||
1454 | define showallrwlck | |
1455 | printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" | |
1456 | set $kgm_rwlckgrp_ptr = (lck_grp_t *)&lck_grp_queue | |
1457 | set $kgm_rwlckgrp_ptr = (lck_grp_t *)$kgm_rwlckgrp_ptr->lck_grp_link.next | |
1458 | while ($kgm_rwlckgrp_ptr != (lck_grp_t *)&lck_grp_queue) | |
1459 | showrwlckgrp $kgm_rwlckgrp_ptr | |
1460 | set $kgm_rwlckgrp_ptr = (lck_grp_t *)$kgm_rwlckgrp_ptr->lck_grp_link.next | |
1461 | end | |
1462 | printf "\n" | |
1463 | end | |
1464 | document showallrwlck | |
1465 | | Routine to print a summary listing of all read/writer locks | |
1466 | | The following is the syntax: | |
1467 | | (gdb) showallrwlck | |
1468 | end | |
1469 | ||
9bccf70c A |
1470 | set $kdp_act_counter = 0 |
1471 | ||
1472 | define switchtoact | |
0c530ab8 A |
1473 | set $newact = (struct thread *) $arg0 |
1474 | if ($newact->kernel_stack == 0) | |
1475 | echo This activation does not have a stack.\n | |
1476 | echo continuation: | |
1477 | output/a (unsigned) $newact.continuation | |
1478 | echo \n | |
1479 | else | |
91447636 | 1480 | if ($kgm_mtype == 18) |
9bccf70c | 1481 | if ($kdp_act_counter == 0) |
0c530ab8 | 1482 | set $kdpstate = (struct savearea *) kdp.saved_state |
9bccf70c A |
1483 | end |
1484 | set $kdp_act_counter = $kdp_act_counter + 1 | |
55e303ae | 1485 | set $newact = (struct thread *) $arg0 |
0c530ab8 A |
1486 | set (struct savearea *) kdp.saved_state=$newact->machine->pcb |
1487 | flushregs | |
1488 | flushstack | |
1489 | set $pc=$newact->machine->pcb.save_srr0 | |
1490 | update | |
9bccf70c | 1491 | else |
0c530ab8 A |
1492 | set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state |
1493 | if ($kdp_act_counter == 0) | |
1494 | set $kdpstate = *($kdpstatep) | |
1495 | end | |
1496 | set $kdp_act_counter = $kdp_act_counter + 1 | |
1497 | ||
1498 | set $kgm_statep = (struct x86_kernel_state32 *) \ | |
1499 | ($newact->kernel_stack + 0x4000 \ | |
1500 | - sizeof(struct x86_kernel_state32)) | |
1501 | set $kdpstatep->ebx = $kgm_statep->k_ebx | |
1502 | set $kdpstatep->ebp = $kgm_statep->k_ebp | |
1503 | set $kdpstatep->edi = $kgm_statep->k_edi | |
1504 | set $kdpstatep->esi = $kgm_statep->k_esi | |
1505 | set $kdpstatep->eip = $kgm_statep->k_eip | |
1506 | flushregs | |
1507 | flushstack | |
1508 | set $pc = $kgm_statep->k_eip | |
1509 | update | |
1510 | end | |
9bccf70c A |
1511 | end |
1512 | end | |
1513 | ||
1514 | document switchtoact | |
1515 | Syntax: switchtoact <address of activation> | |
1516 | | This command allows gdb to examine the execution context and call | |
1517 | | stack for the specified activation. For example, to view the backtrace | |
1518 | | for an activation issue "switchtoact <address>", followed by "bt". | |
1519 | | Before resuming execution, issue a "resetctx" command, to | |
1520 | | return to the original execution context. | |
1521 | end | |
1522 | ||
1523 | define switchtoctx | |
91447636 | 1524 | if ($kgm_mtype == 18) |
9bccf70c A |
1525 | if ($kdp_act_counter == 0) |
1526 | set $kdpstate = (struct savearea *) kdp.saved_state | |
1527 | end | |
1528 | set $kdp_act_counter = $kdp_act_counter + 1 | |
1529 | set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0 | |
0c530ab8 A |
1530 | flushregs |
1531 | flushstack | |
9bccf70c A |
1532 | set $pc=((struct savearea *) $arg0)->save_srr0 |
1533 | update | |
1534 | else | |
1535 | echo switchtoctx not implemented for this architecture.\n | |
1536 | end | |
1537 | end | |
1538 | ||
1539 | document switchtoctx | |
1540 | Syntax: switchtoctx <address of pcb> | |
1541 | | This command allows gdb to examine an execution context and dump the | |
1542 | | backtrace for this execution context. | |
1543 | | Before resuming execution, issue a "resetctx" command, to | |
1544 | | return to the original execution context. | |
1545 | end | |
1546 | ||
1547 | define resetctx | |
91447636 | 1548 | if ($kgm_mtype == 18) |
9bccf70c | 1549 | set (struct savearea *)kdp.saved_state=$kdpstate |
0c530ab8 A |
1550 | flushregs |
1551 | flushstack | |
9bccf70c A |
1552 | set $pc=((struct savearea *) kdp.saved_state)->save_srr0 |
1553 | update | |
1554 | set $kdp_act_counter = 0 | |
1555 | else | |
0c530ab8 A |
1556 | set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state |
1557 | set *($kdpstatep)=$kdpstate | |
1558 | flushregs | |
1559 | flushstack | |
1560 | set $pc=$kdpstatep->eip | |
1561 | update | |
1562 | set $kdp_act_counter = 0 | |
9bccf70c A |
1563 | end |
1564 | end | |
1565 | ||
1566 | document resetctx | |
1567 | | Syntax: resetctx | |
1568 | | Returns to the original execution context. This command should be | |
1569 | | issued if you wish to resume execution after using the "switchtoact" | |
1570 | | or "switchtoctx" commands. | |
1571 | end | |
1572 | ||
55e303ae A |
1573 | define resume_on |
1574 | set noresume_on_disconnect = 0 | |
1575 | end | |
1576 | ||
1577 | document resume_on | |
1578 | | Syntax: resume_on | |
1579 | | The target system will resume when detaching or exiting from gdb. | |
1580 | | This is the default behavior. | |
1581 | end | |
1582 | ||
1583 | define resume_off | |
1584 | set noresume_on_disconnect = 1 | |
1585 | end | |
1586 | ||
1587 | document resume_off | |
1588 | | Syntax: resume_off | |
1589 | | The target system won't resume after detaching from gdb and | |
1590 | | can be attached with a new gdb session | |
1591 | end | |
1592 | ||
9bccf70c A |
1593 | define paniclog |
1594 | set $kgm_panic_bufptr = debug_buf | |
55e303ae A |
1595 | set $kgm_panic_bufptr_max = debug_buf_ptr |
1596 | while $kgm_panic_bufptr < $kgm_panic_bufptr_max | |
9bccf70c A |
1597 | if *(char *)$kgm_panic_bufptr == 10 |
1598 | printf "\n" | |
1599 | else | |
1600 | printf "%c", *$kgm_panic_bufptr | |
1601 | end | |
1602 | set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1 | |
1603 | end | |
1604 | end | |
1605 | ||
1606 | document paniclog | |
1607 | | Syntax: paniclog | |
1608 | | Display the panic log information | |
1609 | | | |
1610 | end | |
55e303ae A |
1611 | |
1612 | define dumpcallqueue | |
1613 | set $kgm_callhead = (queue_t)&$arg0 | |
1614 | set $kgm_call = (struct call_entry *)$kgm_callhead.next | |
1615 | set $kgm_i = 0 | |
1616 | while $kgm_call != $kgm_callhead | |
1617 | printf "0x%08x ", $kgm_call | |
1618 | printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1 | |
1619 | output $kgm_call->state | |
1620 | printf "\t" | |
1621 | output $kgm_call->deadline | |
1622 | printf "\t" | |
1623 | output $kgm_call->func | |
1624 | printf "\n" | |
1625 | set $kgm_i = $kgm_i + 1 | |
1626 | set $kgm_call = (struct call_entry *)$kgm_call->q_link.next | |
1627 | end | |
1628 | printf "%d entries\n", $kgm_i | |
1629 | end | |
1630 | ||
1631 | document dumpcallqueue | |
1632 | | Syntax: dumpcallqueue <queue head> | |
1633 | | Displays the contents of the specified call_entry queue. | |
1634 | end | |
1635 | ||
1636 | define showtaskacts | |
1637 | showtaskthreads $arg0 | |
1638 | end | |
1639 | document showtaskacts | |
1640 | | See help showtaskthreads. | |
1641 | end | |
1642 | ||
1643 | define showallacts | |
1644 | showallthreads | |
1645 | end | |
1646 | document showallacts | |
1647 | | See help showallthreads. | |
1648 | end | |
91447636 A |
1649 | |
1650 | ||
1651 | define resetstacks | |
1652 | _kgm_flush_loop | |
1653 | set kdp_pmap = 0 | |
1654 | _kgm_flush_loop | |
1655 | resetctx | |
1656 | _kgm_flush_loop | |
1657 | _kgm_update_loop | |
1658 | resetctx | |
1659 | _kgm_update_loop | |
1660 | end | |
1661 | ||
1662 | document resetstacks | |
1663 | | Syntax: resetstacks | |
1664 | | Internal kgmacro routine used by the "showuserstack" macro | |
1665 | | to reset the target pmap to the kernel pmap. | |
1666 | end | |
1667 | ||
1668 | #Barely effective hacks to work around bugs in the "flush" and "update" | |
1669 | #gdb commands in Tiger (up to 219); these aren't necessary with Panther | |
1670 | #gdb, but do no harm. | |
1671 | define _kgm_flush_loop | |
1672 | set $kgm_flush_loop_ctr = 0 | |
1673 | while ($kgm_flush_loop_ctr < 30) | |
0c530ab8 A |
1674 | flushregs |
1675 | flushstack | |
91447636 A |
1676 | set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1 |
1677 | end | |
1678 | end | |
1679 | ||
1680 | define _kgm_update_loop | |
1681 | set $kgm_update_loop_ctr = 0 | |
1682 | while ($kgm_update_loop_ctr < 30) | |
1683 | update | |
1684 | set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1 | |
1685 | end | |
1686 | end | |
1687 | ||
0c530ab8 A |
1688 | #This is necessary since gdb often doesn't do backtraces on x86 correctly |
1689 | #in the absence of symbols.The code below in showuserstack and | |
1690 | #showx86backtrace also contains several workarouds for the gdb bug where | |
1691 | #gdb stops macro evaluation because of spurious "Cannot read memory" | |
1692 | #errors on x86. These errors appear on ppc as well, but they don't | |
1693 | #always stop macro evaluation. | |
1694 | ||
1695 | set $kgm_cur_ebp = 0 | |
1696 | set $kgm_cur_eip = 0 | |
1697 | ||
1698 | define showx86backtrace | |
1699 | if ($kgm_cur_ebp == 0) | |
1700 | set $kgm_cur_ebp = $ebp | |
1701 | end | |
1702 | if ($kgm_cur_eip == 0) | |
1703 | set $kgm_cur_eip = $eip | |
1704 | end | |
1705 | printf "0: EBP: 0x%08x EIP: 0x%08x\n", $kgm_cur_ebp, $kgm_cur_eip | |
1706 | x/i $kgm_cur_eip | |
1707 | set $kgm_prev_ebp = *((uint32_t *) $kgm_cur_ebp) | |
1708 | set $kgm_prev_eip = *((uint32_t *) ($kgm_cur_ebp + 4)) | |
1709 | set $kgm_frameno = 1 | |
1710 | while $kgm_prev_ebp != 0 | |
1711 | printf "%d: saved EBP: 0x%08x saved EIP: 0x%08x\n", $kgm_frameno, $kgm_prev_ebp, $kgm_prev_eip | |
1712 | x/i $kgm_prev_eip | |
1713 | set $kgm_cur_ebp = $kgm_prev_ebp | |
1714 | set $kgm_prev_ebp = *((uint32_t *) $kgm_cur_ebp) | |
1715 | set $kgm_prev_eip = *((uint32_t *) ($kgm_cur_ebp + 4)) | |
1716 | set $kgm_frameno = $kgm_frameno + 1 | |
1717 | end | |
1718 | set $kgm_cur_ebp = 0 | |
1719 | set $kgm_cur_eip = 0 | |
1720 | set kdp_pmap = 0 | |
1721 | end | |
1722 | ||
91447636 A |
1723 | define showuserstack |
1724 | if ($kgm_mtype == 18) | |
1725 | if ($kdp_act_counter == 0) | |
1726 | set $kdpstate = (struct savearea *) kdp.saved_state | |
1727 | end | |
1728 | set $kdp_act_counter = $kdp_act_counter + 1 | |
1729 | set $newact = (struct thread *) $arg0 | |
1730 | _kgm_flush_loop | |
1731 | set $checkpc = $newact->machine->upcb.save_srr0 | |
1732 | if ($checkpc == 0) | |
1733 | echo This activation does not appear to have | |
1734 | echo \20 a valid user context.\n | |
1735 | else | |
1736 | set (struct savearea *) kdp.saved_state=$newact->machine->upcb | |
1737 | set $pc = $checkpc | |
1738 | #flush and update seem to be executed lazily by gdb on Tiger, hence the | |
1739 | #repeated invocations - see 3743135 | |
1740 | _kgm_flush_loop | |
1741 | # This works because the new pmap is used only for reads | |
1742 | set kdp_pmap = $newact->task->map->pmap | |
1743 | _kgm_flush_loop | |
1744 | _kgm_update_loop | |
1745 | bt | |
1746 | resetstacks | |
1747 | _kgm_flush_loop | |
1748 | _kgm_update_loop | |
1749 | resetstacks | |
1750 | _kgm_flush_loop | |
1751 | _kgm_update_loop | |
1752 | end | |
1753 | else | |
0c530ab8 A |
1754 | set $newact = (struct thread *) $arg0 |
1755 | set $newiss = (x86_saved_state32_t *) ($newact->machine.pcb->iss) | |
1756 | set $checkpc = $newiss.eip | |
1757 | if ($checkpc == 0) | |
1758 | echo This activation does not appear to have | |
1759 | echo \20 a valid user context.\n | |
1760 | else | |
1761 | set $kgm_cur_ebp = $newiss.ebp | |
1762 | set $kgm_cur_eip = $checkpc | |
1763 | printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread (0x%08x); you can also examine memory locations in this address space (pmap 0x%08x) before issuing the backtrace. This two-step process is necessary to work around various bugs in x86 gdb, which cause it to stop memory evaluation on spurious memory read errors. Additionally, you may need to issue a set kdp_pmap = 0 command after the showx86backtrace completes, to resume reading from the kernel address space.\n", $arg0, $newact->task->map->pmap | |
1764 | set kdp_pmap = $newact->task->map->pmap | |
1765 | _kgm_flush_loop | |
1766 | _kgm_update_loop | |
1767 | end | |
1768 | end | |
91447636 | 1769 | end |
91447636 A |
1770 | document showuserstack |
1771 | Syntax: showuserstack <address of thread activation> | |
1772 | |This command displays a numeric backtrace for the user space stack of | |
1773 | |the given thread activation. It may, of course, fail to display a | |
1774 | |complete backtrace if portions of the user stack are not mapped in. | |
1775 | |Symbolic backtraces can be obtained either by running gdb on the | |
1776 | |user space binary, or a tool such as "symbolicate". | |
1777 | |Note that while this command works on Panther's gdb, an issue | |
1778 | |with Tiger gdb (3743135) appears to hamper the evaluation of this | |
1779 | |macro in some cases. | |
1780 | end | |
1781 | ||
1782 | #Stopgap until gdb can generate the HOSTREBOOT packet | |
1783 | define kdp-reboot | |
1784 | set flag_kdp_trigger_reboot = 1 | |
1785 | continue | |
1786 | end | |
1787 | ||
1788 | document kdp-reboot | |
1789 | Syntax: kdp-reboot | |
1790 | |Reboot the remote target machine; not guaranteed to succeed. Requires symbols | |
1791 | |until gdb support for the HOSTREBOOT packet is implemented. | |
1792 | end | |
1793 | ||
1794 | define sendcore | |
1795 | set kdp_trigger_core_dump = 1 | |
1796 | set kdp_flag |= 0x40 | |
1797 | set panicd_ip_str = "$arg0" | |
1798 | set panicd_specified = 1 | |
1799 | set disableDebugOuput = 0 | |
1800 | set disableConsoleOutput = 0 | |
1801 | set logPanicDataToScreen = 1 | |
1802 | set reattach_wait = 1 | |
1803 | resume_off | |
1804 | end | |
1805 | ||
1806 | document sendcore | |
1807 | Syntax: sendcore <IP address> | |
1808 | |Configure the kernel to transmit a kernel coredump to a server (kdumpd) | |
1809 | |at the specified IP address. This is useful when the remote target has | |
1810 | |not been previously configured to transmit coredumps, and you wish to | |
1811 | |preserve kernel state for later examination. NOTE: You must issue a "continue" | |
1812 | |command after using this macro to trigger the kernel coredump. The kernel | |
1813 | |will resume waiting in the debugger after completion of the coredump. You | |
1814 | |may disable coredumps by executing the "disablecore" macro. | |
1815 | end | |
1816 | ||
1817 | define disablecore | |
1818 | set kdp_trigger_core_dump = 0 | |
1819 | set kdp_flag |= 0x40 | |
1820 | set kdp_flag &= ~0x10 | |
1821 | set panicd_specified = 0 | |
1822 | end | |
1823 | ||
1824 | document disablecore | |
1825 | Syntax: disablecore | |
1826 | |Reconfigures the kernel so that it no longer transmits kernel coredumps. This | |
1827 | |complements the "sendcore" macro, but it may be used if the kernel has been | |
1828 | |configured to transmit coredumps through boot-args as well. | |
1829 | end | |
1830 | ||
1831 | #Use of this macro requires the gdb submission from 3401283 | |
1832 | define switchtocorethread | |
1833 | if ($kgm_mtype == 18) | |
1834 | if ($kdp_act_counter == 0) | |
1835 | set $kdpstate = (struct savearea *) kdp.saved_state | |
1836 | end | |
1837 | set $kdp_act_counter = $kdp_act_counter + 1 | |
1838 | set $newact = (struct thread *) $arg0 | |
1839 | if ($newact->kernel_stack == 0) | |
1840 | echo This thread does not have a stack.\n | |
1841 | echo continuation: | |
1842 | output/a (unsigned) $newact.continuation | |
1843 | echo \n | |
1844 | else | |
1845 | loadcontext $newact->machine->pcb | |
1846 | # flushstack will be introduced in a gdb version > gdb-357 | |
1847 | flushstack | |
1848 | set $pc = $newact->machine->pcb.save_srr0 | |
1849 | end | |
1850 | else | |
1851 | echo switchtocorethread not implemented for this architecture.\n | |
1852 | end | |
1853 | end | |
1854 | ||
1855 | document switchtocorethread | |
1856 | Syntax: switchtocorethread <address of activation> | |
1857 | | The corefile equivalent of "switchtoact". When debugging a kernel coredump | |
1858 | | file, this command can be used to examine the execution context and stack | |
1859 | | trace for a given thread activation. For example, to view the backtrace | |
1860 | | for a thread issue "switchtocorethread <address>", followed by "bt". | |
1861 | | Before resuming execution, issue a "resetcorectx" command, to | |
1862 | | return to the original execution context. Note that this command | |
1863 | | requires gdb support, as documented in Radar 3401283. | |
1864 | end | |
1865 | ||
1866 | define loadcontext | |
1867 | set $pc = $arg0.save_srr0 | |
1868 | set $r1 = $arg0.save_r1 | |
1869 | set $lr = $arg0.save_lr | |
1870 | ||
1871 | set $r2 = $arg0.save_r2 | |
1872 | set $r3 = $arg0.save_r3 | |
1873 | set $r4 = $arg0.save_r4 | |
1874 | set $r5 = $arg0.save_r5 | |
1875 | set $r6 = $arg0.save_r6 | |
1876 | set $r7 = $arg0.save_r7 | |
1877 | set $r8 = $arg0.save_r8 | |
1878 | set $r9 = $arg0.save_r9 | |
1879 | set $r10 = $arg0.save_r10 | |
1880 | set $r11 = $arg0.save_r11 | |
1881 | set $r12 = $arg0.save_r12 | |
1882 | set $r13 = $arg0.save_r13 | |
1883 | set $r14 = $arg0.save_r14 | |
1884 | set $r15 = $arg0.save_r15 | |
1885 | set $r16 = $arg0.save_r16 | |
1886 | set $r17 = $arg0.save_r17 | |
1887 | set $r18 = $arg0.save_r18 | |
1888 | set $r19 = $arg0.save_r19 | |
1889 | set $r20 = $arg0.save_r20 | |
1890 | set $r21 = $arg0.save_r21 | |
1891 | set $r22 = $arg0.save_r22 | |
1892 | set $r23 = $arg0.save_r23 | |
1893 | set $r24 = $arg0.save_r24 | |
1894 | set $r25 = $arg0.save_r25 | |
1895 | set $r26 = $arg0.save_r26 | |
1896 | set $r27 = $arg0.save_r27 | |
1897 | set $r28 = $arg0.save_r28 | |
1898 | set $r29 = $arg0.save_r29 | |
1899 | set $r30 = $arg0.save_r30 | |
1900 | set $r31 = $arg0.save_r31 | |
1901 | ||
1902 | set $cr = $arg0.save_cr | |
1903 | set $ctr = $arg0.save_ctr | |
1904 | end | |
1905 | ||
1906 | define resetcorectx | |
1907 | set $kgm_corecontext = (struct savearea *) kdp.saved_state | |
1908 | loadcontext $kgm_corecontext | |
1909 | # Maintaining this act counter wouldn't be necessary if we just initialized | |
1910 | # $kdpstate at the beginning of the macro.. | |
1911 | set $kdp_act_counter = 0 | |
1912 | end | |
1913 | ||
1914 | document resetcorectx | |
1915 | Syntax: resetcorectx | |
1916 | | The corefile equivalent of "resetctx". Returns to the original | |
1917 | | execution context (that of the active thread at the time of the NMI or | |
1918 | | panic). This command should be issued if you wish to resume | |
1919 | | execution after using the "switchtocorethread" command. | |
1920 | end | |
1921 | ||
1922 | #Helper function for "showallgdbstacks" | |
1923 | ||
1924 | define showgdbthread | |
1925 | printf " 0x%08x ", $arg0 | |
1926 | set $kgm_thread = *(struct thread *)$arg0 | |
1927 | printf "0x%08x ", $arg0 | |
1928 | printf "%3d ", $kgm_thread.sched_pri | |
1929 | set $kgm_state = $kgm_thread.state | |
1930 | if $kgm_state & 0x80 | |
1931 | printf "I" | |
1932 | end | |
1933 | if $kgm_state & 0x40 | |
1934 | printf "P" | |
1935 | end | |
1936 | if $kgm_state & 0x20 | |
1937 | printf "A" | |
1938 | end | |
1939 | if $kgm_state & 0x10 | |
1940 | printf "H" | |
1941 | end | |
1942 | if $kgm_state & 0x08 | |
1943 | printf "U" | |
1944 | end | |
1945 | if $kgm_state & 0x04 | |
1946 | printf "R" | |
1947 | end | |
1948 | if $kgm_state & 0x02 | |
1949 | printf "S" | |
1950 | end | |
1951 | if $kgm_state & 0x01 | |
1952 | printf "W\t" | |
1953 | printf "0x%08x ", $kgm_thread.wait_queue | |
1954 | output /a (unsigned) $kgm_thread.wait_event | |
1955 | end | |
1956 | if $arg1 != 0 | |
1957 | if ($kgm_thread.kernel_stack != 0) | |
1958 | if ($kgm_thread.reserved_stack != 0) | |
1959 | printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack | |
1960 | end | |
1961 | printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack | |
1962 | if ($kgm_mtype == 18) | |
1963 | set $mysp = $kgm_thread.machine.pcb->save_r1 | |
1964 | else | |
0c530ab8 | 1965 | set $kgm_statep = (struct x86_kernel_state32 *) \ |
91447636 | 1966 | ($kgm_thread->kernel_stack + 0x4000 \ |
0c530ab8 | 1967 | - sizeof(struct x86_kernel_state32)) |
91447636 A |
1968 | set $mysp = $kgm_statep->k_ebp |
1969 | end | |
1970 | set $prevsp = 0 | |
1971 | printf "\n\t\tstacktop=0x%08x", $mysp | |
1972 | switchtoact $arg0 | |
1973 | bt | |
1974 | else | |
1975 | printf "\n\t\t\tcontinuation=" | |
1976 | output /a (unsigned) $kgm_thread.continuation | |
1977 | end | |
1978 | printf "\n" | |
1979 | else | |
1980 | printf "\n" | |
1981 | end | |
1982 | end | |
1983 | ||
1984 | #Use of this macro is currently (8/04) blocked by the fact that gdb | |
1985 | #stops evaluating macros when encountering an error, such as a failure | |
1986 | #to read memory from a certain location. Until this issue (described in | |
1987 | #3758949) is addressed, evaluation of this macro may stop upon | |
1988 | #encountering such an error. | |
1989 | ||
1990 | define showallgdbstacks | |
1991 | set $kgm_head_taskp = &default_pset.tasks | |
1992 | set $kgm_taskp = (struct task *)($kgm_head_taskp->next) | |
1993 | while $kgm_taskp != $kgm_head_taskp | |
1994 | showtaskheader | |
1995 | showtaskint $kgm_taskp | |
1996 | set $kgm_head_actp = &($kgm_taskp->threads) | |
1997 | set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) | |
1998 | while $kgm_actp != $kgm_head_actp | |
1999 | showactheader | |
2000 | showgdbthread $kgm_actp 1 | |
2001 | set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) | |
2002 | end | |
2003 | printf "\n" | |
2004 | set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) | |
2005 | end | |
2006 | resetctx | |
2007 | end | |
2008 | ||
2009 | document showallgdbstacks | |
2010 | Syntax: showallgdbstacks | |
2011 | | An alternative to "showallstacks". Iterates through the task list and | |
2012 | | displays a gdb generated backtrace for each kernel thread. It is | |
2013 | | advantageous in that it is much faster than "showallstacks", and | |
2014 | | decodes function call arguments and displays source level traces, but | |
2015 | | it has the drawback that it doesn't determine if frames belong to | |
2016 | | functions from kernel extensions, as with "showallstacks". | |
2017 | | This command may terminate prematurely because of a gdb bug | |
2018 | | (Radar 3758949), which stops macro evaluation on memory read | |
2019 | | errors. | |
2020 | end | |
2021 | ||
2022 | define switchtouserthread | |
2023 | if ($kgm_mtype == 18) | |
2024 | if ($kdp_act_counter == 0) | |
2025 | set $kdpstate = (struct savearea *) kdp.saved_state | |
2026 | end | |
2027 | set $kdp_act_counter = $kdp_act_counter + 1 | |
2028 | set $newact = (struct thread *) $arg0 | |
2029 | _kgm_flush_loop | |
2030 | set $checkpc = $newact->machine->upcb.save_srr0 | |
2031 | if ($checkpc == 0) | |
2032 | echo This activation does not appear to have | |
2033 | echo \20 a valid user context.\n | |
2034 | else | |
2035 | set (struct savearea *) kdp.saved_state=$newact->machine->upcb | |
2036 | set $pc = $checkpc | |
2037 | #flush and update seem to be executed lazily by gdb on Tiger, hence the | |
2038 | #repeated invocations - see 3743135 | |
2039 | _kgm_flush_loop | |
2040 | # This works because the new pmap is used only for reads | |
2041 | set kdp_pmap = $newact->task->map->pmap | |
2042 | _kgm_flush_loop | |
2043 | _kgm_update_loop | |
2044 | end | |
2045 | else | |
2046 | echo switchtouserthread not implemented for this architecture.\n | |
2047 | end | |
2048 | end | |
2049 | ||
2050 | document switchtouserthread | |
2051 | Syntax: switchtouserthread <address of thread> | |
2052 | | Analogous to switchtoact, but switches to the user context of a | |
2053 | | specified thread address. Similar to the "showuserstack" | |
2054 | | command, but this command does not return gdb to the kernel context | |
2055 | | immediately. This is to assist with the following (rather risky) | |
2056 | | manoeuvre - upon switching to the user context and virtual address | |
2057 | | space, the user may choose to call remove-symbol-file on the | |
2058 | | mach_kernel symbol file, and then add-symbol-file on the user space | |
2059 | | binary's symfile. gdb can then generate symbolic backtraces | |
2060 | | for the user space thread. To return to the | |
2061 | | kernel context and virtual address space, the process must be | |
2062 | | reversed, i.e. call remove-symbol-file on the user space symbols, and | |
2063 | | then add-symbol-file on the appropriate mach_kernel, and issue the | |
2064 | | "resetstacks" command. Note that gdb may not react kindly to all these | |
2065 | | symbol file switches. The same restrictions that apply to "showuserstack" | |
2066 | | apply here - pages that have been paged out cannot be read while in the | |
2067 | | debugger context, so backtraces may terminate early. | |
2068 | | If the virtual addresses in the stack trace do not conflict with those | |
2069 | | of symbols in the kernel's address space, it may be sufficient to | |
2070 | | just do an add-symbol-file on the user space binary's symbol file. | |
2071 | | Note that while this command works on Panther's gdb, an issue | |
2072 | | with Tiger gdb (3743135) appears to hamper the evaluation of this | |
2073 | | macro in some cases. | |
2074 | end | |
2075 | ||
2076 | define showmetaclass | |
91447636 A |
2077 | set $kgm_metaclassp = (OSMetaClass *)$arg0 |
2078 | printf "%-5d", $kgm_metaclassp->instanceCount | |
2079 | printf "x %5d bytes", $kgm_metaclassp->classSize | |
2080 | printf " %s\n", $kgm_metaclassp->className->string | |
2081 | end | |
2082 | ||
0c530ab8 A |
2083 | define showstring |
2084 | printf "\"%s\"", ((OSString *)$arg0)->string | |
2085 | end | |
2086 | ||
2087 | define shownumber | |
2088 | printf "%lld", ((OSNumber *)$arg0)->value | |
2089 | end | |
2090 | ||
2091 | define showboolean | |
2092 | if ($arg0 == gOSBooleanFalse) | |
2093 | printf "No" | |
2094 | else | |
2095 | printf "Yes" | |
2096 | end | |
2097 | end | |
2098 | ||
2099 | define showdata | |
2100 | set $kgm_data = (OSData *)$arg0 | |
2101 | ||
2102 | printf "<" | |
2103 | set $kgm_datap = (const unsigned char *) $kgm_data->data | |
2104 | ||
2105 | set $kgm_printstr = 0 | |
2106 | if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3)) | |
2107 | set $kgm_bytes = *(unsigned int *) $kgm_datap | |
2108 | if (0xffff0000 & $kgm_bytes) | |
2109 | set $kgm_idx = 0 | |
2110 | set $kgm_printstr = 1 | |
2111 | while ($kgm_idx++ < 4) | |
2112 | set $kgm_bytes = $kgm_bytes >> 8 | |
2113 | set $kgm_char = 0xff & $kgm_bytes | |
2114 | if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e))) | |
2115 | set $kgm_printstr = 0 | |
2116 | end | |
2117 | end | |
2118 | end | |
2119 | end | |
2120 | ||
2121 | set $kgm_idx = 0 | |
2122 | if ($kgm_printstr) | |
2123 | set $kgm_quoted = 0 | |
2124 | while ($kgm_idx < $kgm_data->length) | |
2125 | set $kgm_char = $kgm_datap[$kgm_idx++] | |
2126 | if ($kgm_char) | |
2127 | if (0 == $kgm_quoted) | |
2128 | set $kgm_quoted = 1 | |
2129 | if ($kgm_idx > 1) | |
2130 | printf ",\"" | |
2131 | else | |
2132 | printf "\"" | |
2133 | end | |
2134 | end | |
2135 | printf "%c", $kgm_char | |
2136 | else | |
2137 | if ($kgm_quoted) | |
2138 | set $kgm_quoted = 0 | |
2139 | printf "\"" | |
2140 | end | |
2141 | end | |
2142 | end | |
2143 | if ($kgm_quoted) | |
2144 | printf "\"" | |
2145 | end | |
2146 | else | |
2147 | if (0 == (3 & (unsigned int)$kgm_datap)) | |
2148 | while (($kgm_idx + 3) <= $kgm_data->length) | |
2149 | printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx] | |
2150 | set $kgm_idx = $kgm_idx + 4 | |
2151 | end | |
2152 | end | |
2153 | while ($kgm_idx < $kgm_data->length) | |
2154 | printf "%02x", $kgm_datap[$kgm_idx++] | |
2155 | end | |
2156 | end | |
2157 | printf ">" | |
2158 | end | |
2159 | ||
2160 | define showdictionaryint | |
2161 | set $kgm$arg0_dict = (OSDictionary *)$arg1 | |
2162 | ||
2163 | printf "{" | |
2164 | set $kgm$arg0_idx = 0 | |
2165 | while ($kgm$arg0_idx < $kgm$arg0_dict->count) | |
2166 | set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key | |
2167 | showobjectint _$arg0 $kgm_obj | |
2168 | printf "=" | |
2169 | set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value | |
2170 | showobjectint _$arg0 $kgm_obj | |
2171 | if ($kgm$arg0_idx < $kgm$arg0_dict->count) | |
2172 | printf "," | |
2173 | end | |
2174 | end | |
2175 | printf "}" | |
2176 | end | |
2177 | ||
2178 | define indent | |
2179 | set $kgm_idx = 0 | |
2180 | while ($kgm_idx < $arg0) | |
2181 | if ($arg1 & (1 << $kgm_idx++)) | |
2182 | printf "| " | |
2183 | else | |
2184 | printf " " | |
2185 | end | |
2186 | end | |
2187 | end | |
2188 | ||
2189 | define showregdictionary | |
2190 | indent $kgm_reg_depth+2 $arg1 | |
2191 | printf "{\n" | |
2192 | ||
2193 | set $kgm_reg_idx = 0 | |
2194 | while ($kgm_reg_idx < $arg0->count) | |
2195 | indent $kgm_reg_depth+2 $arg1 | |
2196 | printf " " | |
2197 | set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key | |
2198 | showobjectint _ $kgm_obj | |
2199 | printf " = " | |
2200 | ||
2201 | set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value | |
2202 | showobjectint _ $kgm_obj | |
2203 | printf "\n" | |
2204 | end | |
2205 | indent $kgm_reg_depth+2 $arg1 | |
2206 | printf "}\n" | |
2207 | end | |
2208 | ||
2209 | ||
2210 | define showarraysetint | |
2211 | set $kgm$arg0_array = (OSArray *)$arg1 | |
2212 | ||
2213 | set $kgm$arg0_idx = 0 | |
2214 | while ($kgm$arg0_idx < $kgm$arg0_array->count) | |
2215 | set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++] | |
2216 | showobjectint _$arg0 $kgm_obj | |
2217 | if ($kgm$arg0_idx < $kgm$arg0_array->count) | |
2218 | printf "," | |
2219 | end | |
2220 | end | |
2221 | end | |
2222 | ||
2223 | define showarrayint | |
2224 | printf "(" | |
2225 | showarraysetint $arg0 $arg1 | |
2226 | printf ")" | |
2227 | end | |
2228 | ||
2229 | define showsetint | |
2230 | set $kgm_array = ((OSSet *)$arg1)->members | |
2231 | printf "[" | |
2232 | showarraysetint $arg0 $kgm_array | |
2233 | printf "]" | |
2234 | end | |
2235 | ||
2236 | ||
2237 | define showobjectint | |
2238 | set $kgm_obj = (OSObject *) $arg1 | |
2239 | set $kgm_vt = *((void **) $arg1) | |
2240 | ||
2241 | if ($kgm_show_object_addrs) | |
2242 | printf "`object %p, vt ", $arg1 | |
2243 | output /a (unsigned) $kgm_vt | |
2244 | if ($kgm_show_object_retain) | |
2245 | printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16 | |
2246 | end | |
2247 | printf "` " | |
2248 | end | |
2249 | ||
2250 | if ($kgm_vt == _ZTV8OSString) | |
2251 | showstring $arg1 | |
2252 | else | |
2253 | if ($kgm_vt == _ZTV8OSSymbol) | |
2254 | showstring $arg1 | |
2255 | else | |
2256 | if ($kgm_vt == _ZTV8OSNumber) | |
2257 | shownumber $arg1 | |
2258 | else | |
2259 | if ($kgm_vt == _ZTV6OSData) | |
2260 | showdata $arg1 | |
2261 | else | |
2262 | if ($kgm_vt == _ZTV9OSBoolean) | |
2263 | showboolean $arg1 | |
2264 | else | |
2265 | if ($kgm_vt == _ZTV12OSDictionary) | |
2266 | showdictionaryint _$arg0 $arg1 | |
2267 | else | |
2268 | if ($kgm_vt == _ZTV7OSArray) | |
2269 | showarrayint _$arg0 $arg1 | |
2270 | else | |
2271 | if ($kgm_vt == _ZTV5OSSet) | |
2272 | showsetint _$arg0 $arg1 | |
2273 | else | |
2274 | if ($kgm_show_object_addrs == 0) | |
2275 | printf "`object %p, vt ", $arg1 | |
2276 | output /a (unsigned) $kgm_vt | |
2277 | printf "`" | |
2278 | end | |
2279 | end | |
2280 | end | |
2281 | end | |
2282 | end | |
2283 | end | |
2284 | end | |
2285 | end | |
2286 | end | |
2287 | end | |
2288 | ||
2289 | define showobject | |
2290 | set $kgm_save = $kgm_show_object_addrs | |
2291 | set $kgm_show_object_addrs = 1 | |
2292 | set $kgm_show_object_retain = 1 | |
2293 | showobjectint _ $arg0 | |
2294 | set $kgm_show_object_addrs = $kgm_save | |
2295 | set $kgm_show_object_retain = 0 | |
2296 | printf "\n" | |
2297 | end | |
2298 | document showobject | |
2299 | | Show info about an OSObject - its vtable ptr and retain count. | |
2300 | | If the object is a simple container class, more info will be shown. | |
2301 | | The following is the syntax: | |
2302 | | (gdb) showobject <object address> | |
2303 | end | |
2304 | ||
2305 | define dictget | |
2306 | set $kgm_dictp = (OSDictionary *)$arg0 | |
2307 | set $kgm_keyp = (const OSSymbol *)$arg1 | |
2308 | set $kgm_idx = 0 | |
2309 | set $kgm_result = 0 | |
2310 | while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0)) | |
2311 | if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key) | |
2312 | set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value | |
2313 | end | |
2314 | set $kgm_idx = $kgm_idx + 1 | |
2315 | end | |
2316 | end | |
2317 | ||
2318 | ||
2319 | define showregistryentryrecurse | |
2320 | set $kgm_re = (IOService *)$arg1 | |
2321 | set $kgm$arg0_stack = (unsigned long long) $arg2 | |
2322 | ||
2323 | if ($arg3) | |
2324 | set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth) | |
2325 | else | |
2326 | set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth) | |
2327 | end | |
2328 | ||
2329 | dictget $kgm_re->fRegistryTable $kgm_childkey | |
2330 | set $kgm$arg0_child_array = (OSArray *) $kgm_result | |
2331 | ||
2332 | if ($kgm$arg0_child_array) | |
2333 | set $kgm$arg0_child_count = $kgm$arg0_child_array->count | |
2334 | else | |
2335 | set $kgm$arg0_child_count = 0 | |
2336 | end | |
2337 | ||
2338 | if ($kgm$arg0_child_count) | |
2339 | set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth) | |
2340 | else | |
2341 | set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth) | |
2342 | end | |
2343 | ||
2344 | indent $kgm_reg_depth $kgm$arg0_stack | |
2345 | printf "+-o " | |
2346 | ||
2347 | dictget $kgm_re->fRegistryTable $kgm_namekey | |
2348 | if ($kgm_result == 0) | |
2349 | dictget $kgm_re->fRegistryTable gIONameKey | |
2350 | end | |
2351 | if ($kgm_result == 0) | |
2352 | dictget $kgm_re->fPropertyTable gIOClassKey | |
2353 | end | |
2354 | ||
2355 | if ($kgm_result != 0) | |
2356 | printf "%s", ((OSString *)$kgm_result)->string | |
2357 | else | |
2358 | if (((IOService*)$kgm_re)->pm_vars && ((IOService*)$kgm_re)->pm_vars->ourName) | |
2359 | printf "%s", ((IOService*)$kgm_re)->pm_vars->ourName | |
2360 | else | |
2361 | # printf ", guessclass " | |
2362 | # guessclass $kgm_re | |
2363 | printf "??" | |
2364 | end | |
2365 | end | |
2366 | ||
2367 | ||
2368 | printf " <object %p, ", $kgm_re | |
2369 | printf "vtable " | |
2370 | set $kgm_vt = (unsigned) *(void**) $kgm_re | |
2371 | output /a $kgm_vt | |
2372 | ||
2373 | if ($kgm_vt != _ZTV15IORegistryEntry) | |
2374 | printf ", " | |
2375 | set $kgm_state = $kgm_re->__state[0] | |
2376 | # kIOServiceRegisteredState | |
2377 | if (0 == ($kgm_state & 2)) | |
2378 | printf "!" | |
2379 | end | |
2380 | printf "registered, " | |
2381 | # kIOServiceMatchedState | |
2382 | if (0 == ($kgm_state & 4)) | |
2383 | printf "!" | |
2384 | end | |
2385 | printf "matched, " | |
2386 | # kIOServiceInactiveState | |
2387 | if ($kgm_state & 1) | |
2388 | printf "in" | |
2389 | end | |
2390 | printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount) | |
2391 | end | |
2392 | printf ">\n" | |
2393 | ||
2394 | if ($kgm_show_props) | |
2395 | set $kgm_props = $kgm_re->fPropertyTable | |
2396 | showregdictionary $kgm_props $kgm$arg0_stack | |
2397 | end | |
2398 | ||
2399 | # recurse | |
2400 | if ($kgm$arg0_child_count != 0) | |
2401 | ||
2402 | set $kgm_reg_depth = $kgm_reg_depth + 1 | |
2403 | set $kgm$arg0_child_idx = 0 | |
2404 | ||
2405 | while ($kgm$arg0_child_idx < $kgm$arg0_child_count) | |
2406 | set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++] | |
2407 | set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count) | |
2408 | showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib | |
2409 | end | |
2410 | ||
2411 | set $kgm_reg_depth = $kgm_reg_depth - 1 | |
2412 | end | |
2413 | end | |
2414 | ||
2415 | define showregistryentryint | |
2416 | set $kgm_namekey = (OSSymbol *) $kgm_reg_plane[2] | |
2417 | set $kgm_childkey = (OSSymbol *) $kgm_reg_plane[4] | |
2418 | ||
2419 | showregistryentryrecurse _ $arg0 0 0 | |
2420 | end | |
2421 | ||
2422 | define showregistry | |
2423 | set $kgm_reg_depth = 0 | |
2424 | set $kgm_show_props = 0 | |
2425 | showregistryentryint gRegistryRoot | |
2426 | end | |
2427 | document showregistry | |
2428 | | Show info about all registry entries in the current plane. | |
2429 | | The following is the syntax: | |
2430 | | (gdb) showregistry | |
2431 | end | |
2432 | ||
2433 | define showregistryprops | |
2434 | set $kgm_reg_depth = 0 | |
2435 | set $kgm_show_props = 1 | |
2436 | showregistryentryint gRegistryRoot | |
2437 | end | |
2438 | document showregistryprops | |
2439 | | Show info about all registry entries in the current plane, and their properties. | |
2440 | | set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display | |
2441 | | more verbose information | |
2442 | | The following is the syntax: | |
2443 | | (gdb) showregistryprops | |
2444 | end | |
2445 | ||
2446 | define showregistryentry | |
2447 | set $kgm_reg_depth = 0 | |
2448 | set $kgm_show_props = 1 | |
2449 | showregistryentryint $arg0 | |
2450 | end | |
2451 | document showregistryentry | |
2452 | | Show info about a registry entry; its properties and descendants in the current plane. | |
2453 | | The following is the syntax: | |
2454 | | (gdb) showregistryentry <object address> | |
2455 | end | |
2456 | ||
2457 | define setregistryplane | |
2458 | if ($arg0) | |
2459 | set $kgm_reg_plane = (void **) $arg0 | |
2460 | else | |
2461 | showobjectint _ gIORegistryPlanes | |
2462 | printf "\n" | |
2463 | end | |
2464 | end | |
2465 | document setregistryplane | |
2466 | | Set the plane to be used for the iokit registry macros. An argument of zero will | |
2467 | | display known planes. | |
2468 | | The following is the syntax: | |
2469 | | (gdb) setregistryplane <plane object address> | |
2470 | end | |
2471 | ||
2472 | define guessclass | |
4452a7af | 2473 | set $kgm_classidx = 0 |
0c530ab8 A |
2474 | set $kgm_lookvt = *((void **) $arg0) |
2475 | set $kgm_bestvt = (void *) 0 | |
2476 | set $kgm_bestidx = 0 | |
2477 | ||
4452a7af | 2478 | while $kgm_classidx < sAllClassesDict->count |
6601e61a | 2479 | set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value |
0c530ab8 A |
2480 | |
2481 | set $kgm_vt = *((void **) $kgm_meta) | |
2482 | ||
2483 | if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt)) | |
2484 | set $kgm_bestvt = $kgm_vt | |
2485 | set $kgm_bestidx = $kgm_classidx | |
2486 | end | |
6601e61a | 2487 | set $kgm_classidx = $kgm_classidx + 1 |
4452a7af | 2488 | end |
0c530ab8 | 2489 | printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string |
4452a7af | 2490 | end |
0c530ab8 A |
2491 | |
2492 | define showallclasses | |
2493 | set $kgm_classidx = 0 | |
2494 | while $kgm_classidx < sAllClassesDict->count | |
2495 | set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value | |
2496 | showmetaclass $kgm_meta | |
2497 | end | |
2498 | end | |
2499 | ||
91447636 A |
2500 | document showallclasses |
2501 | | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details. | |
2502 | | The following is the syntax: | |
2503 | | (gdb) showallclasses | |
2504 | end | |
2505 | ||
2506 | define showioalloc | |
2507 | printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024 | |
2508 | printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024 | |
2509 | printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024 | |
2510 | printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024 | |
2511 | end | |
2512 | ||
2513 | document showioalloc | |
2514 | | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details. | |
2515 | | The following is the syntax: | |
2516 | | (gdb) showioalloc | |
2517 | end | |
0c530ab8 A |
2518 | |
2519 | define readphys | |
2520 | set kdp_trans_off = 1 | |
2521 | x/x $arg0 | |
2522 | set kdp_trans_off = 0 | |
2523 | end | |
2524 | ||
2525 | define readphys64 | |
2526 | if ($kgm_mtype == 18) | |
2527 | set kdp_src_high32 = ((uint32_t) ($arg0)) >> 32 | |
2528 | x/x (uint32_t) (($arg0) & 0x00000000ffffffffUL) | |
2529 | set kdp_src_high32 = 0 | |
2530 | else | |
2531 | echo readphys64 not available on this architecture.\n | |
2532 | end | |
2533 | end | |
2534 | ||
2535 | document readphys | |
2536 | | The argument is interpreted as a physical address, and the word addressed is | |
2537 | | displayed. While this fails if no physical page exists at the given address, | |
2538 | | it must be used with caution. | |
2539 | end | |
2540 | ||
2541 | document readphys64 | |
2542 | | The argument is interpreted as a 64-bit physical address, and the word | |
2543 | | addressed is displayed. While this fails if no physical page exists at the | |
2544 | | given address, it must be used with caution. | |
2545 | end |