]> git.saurik.com Git - apple/xnu.git/blame_incremental - kgmacros
xnu-792.13.8.tar.gz
[apple/xnu.git] / kgmacros
... / ...
CommitLineData
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
9set print asm-demangle on
10set cp-abi gnu-v2
11
12echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n
13
14define kgm
15printf ""
16echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n
17end
18
19document 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:
27| showversion Displays a string describing the remote kernel version
28|
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
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
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)
46|
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
54|
55| showact Display info about a thread specified by activation
56| showactstack Display the stack for a thread specified by activation
57|
58| showmap Display info about the specified vm_map
59| showmapvme Display a summary list of the specified vm_map's entries
60|
61| showipc Display info about the specified ipc space
62| showrights Display a summary list of all the rights in an ipc space
63|
64| showpid Display info about the process identified by pid
65| showproc Display info about the process identified by proc struct
66|
67| showkmod Display info about a kernel module
68| showkmodaddr Given an address, display the kernel module and offset
69|
70| dumpcallqueue Dump out all the entries given a queue head
71|
72| showallmtx Display info about mutexes usage
73| showallrwlck Display info about reader/writer locks usage
74|
75| zprint Display info about the memory zones
76| showioalloc Display info about iokit allocations
77| paniclog Display the panic log info
78|
79| switchtoact Switch to different context specified by activation
80| switchtoctx Switch to different context
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|
87| resetctx Reset context
88| resume_on Resume when detaching from gdb
89| resume_off Don't resume when detaching from gdb
90|
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"
95|
96| readphys Reads the specified untranslated address
97| readphys64 Reads the specified untranslated 64-bit address
98|
99| kdp-reboot Restart remote target
100|
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.
103end
104
105# This macro should appear before any symbol references, to facilitate
106# a gdb "source" without a loaded symbol file.
107define showversion
108 printf "%s\n", *(char **)0x501C
109end
110
111document showversion
112Syntax: 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.
120end
121
122set $kgm_dummy = &proc0
123set $kgm_dummy = &kmod
124set $kgm_mtype = ((struct mach_header)_mh_execute_header).cputype
125
126set $kgm_reg_depth = 0
127set $kgm_reg_plane = (void **) gIOServicePlane
128set $kgm_namekey = (OSSymbol *) 0
129set $kgm_childkey = (OSSymbol *) 0
130
131set $kgm_show_object_addrs = 0
132set $kgm_show_object_retain = 0
133set $kgm_show_props = 0
134
135define showkmodheader
136 printf "kmod address size "
137 printf "id refs version name\n"
138end
139
140define 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
149end
150
151set $kgm_kmodmin = 0xffffffff
152set $kgm_fkmodmin = 0x00000000
153set $kgm_kmodmax = 0x00000000
154set $kgm_fkmodmax = 0xffffffff
155set $kgm_pkmod = 0
156set $kgm_pkmodst = 0
157set $kgm_pkmoden = 0
158define showkmodaddrint
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
172 set $kgm_kmodmax = $kgm_kmod.address + $kgm_kmod.size
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
191end
192
193define showkmodaddr
194 showkmodaddrint $arg0
195 printf "\n"
196end
197
198document 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>
202end
203
204define showkmod
205 showkmodheader
206 showkmodint $arg0
207end
208document showkmod
209| Routine to print info about a kernel module
210| The following is the syntax:
211| (gdb) showkmod <kmod>
212end
213
214define 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
221end
222document showallkmods
223| Routine to print a summary listing of all the kernel modules
224| The following is the syntax:
225| (gdb) showallkmods
226end
227
228define showactheader
229 printf " activation "
230 printf "thread pri state wait_queue wait_event\n"
231end
232
233
234define showactint
235 printf " 0x%08x ", $arg0
236 set $kgm_thread = *(struct thread *)$arg0
237 printf "0x%08x ", $arg0
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
264 if (((unsigned)$kgm_thread.wait_event > (unsigned)sectPRELINKB) \
265 && ($arg1 != 2))
266 showkmodaddr $kgm_thread.wait_event
267 else
268 output /a (unsigned) $kgm_thread.wait_event
269 end
270 end
271 if $arg1 != 0
272 if ($kgm_thread.kernel_stack != 0)
273 if ($kgm_thread.reserved_stack != 0)
274 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack
275 end
276 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack
277 if ($kgm_mtype == 18)
278 set $mysp = $kgm_thread.machine.pcb->save_r1
279 else
280 set $kgm_statep = (struct x86_kernel_state32 *) \
281 ($kgm_thread->kernel_stack + 0x4000 \
282 - sizeof(struct x86_kernel_state32))
283 set $mysp = $kgm_statep->k_ebp
284 end
285 set $prevsp = $mysp - 16
286 printf "\n\t\tstacktop=0x%08x", $mysp
287 if ($kgm_mtype == 18)
288 set $stkmask = 0xf
289 else
290 set $stkmask = 0x3
291 end
292 set $kgm_return = 0
293 while ($mysp != 0) && (($mysp & $stkmask) == 0) \
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
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
312 set $prevsp = $mysp
313 set $mysp = * $mysp
314 end
315 if ((unsigned) $kgm_return > 0)
316 output/a $kgm_return
317 end
318 set $kgm_return = 0
319 printf "\n\t\tstackbottom=0x%08x", $prevsp
320 else
321 printf "\n\t\t\tcontinuation="
322 output /a (unsigned) $kgm_thread.continuation
323 end
324 printf "\n"
325 else
326 printf "\n"
327 end
328end
329
330define showact
331 showactheader
332 showactint $arg0 0
333end
334document showact
335| Routine to print out the state of a specific thread.
336| The following is the syntax:
337| (gdb) showact <activation>
338end
339
340
341define showactstack
342 showactheader
343 showactint $arg0 1
344end
345document showactstack
346| Routine to print out the stack of a specific thread.
347| The following is the syntax:
348| (gdb) showactstack <activation>
349end
350
351
352define showallthreads
353 set $kgm_head_taskp = &default_pset.tasks
354 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
355 while $kgm_taskp != $kgm_head_taskp
356 showtaskheader
357 showtaskint $kgm_taskp
358 showactheader
359 set $kgm_head_actp = &($kgm_taskp->threads)
360 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
361 while $kgm_actp != $kgm_head_actp
362 showactint $kgm_actp 0
363 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
364 end
365 printf "\n"
366 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
367 end
368end
369document showallthreads
370| Routine to print out info about all threads in the system.
371| The following is the syntax:
372| (gdb) showallthreads
373end
374
375define showcurrentthreads
376set $kgm_prp = processor_list
377 while $kgm_prp != 0
378 if ($kgm_prp)->active_thread != 0
379 set $kgm_actp = ($kgm_prp)->active_thread
380 showtaskheader
381 showtaskint ($kgm_actp)->task
382 showactheader
383 showactint $kgm_actp 0
384 printf "\n"
385 end
386 set $kgm_prp = ($kgm_prp)->processor_list
387 end
388end
389document showcurrentthreads
390| Routine to print out info about the thread running on each cpu.
391| The following is the syntax:
392| (gdb) showcurrentthreads
393end
394
395set $decode_wait_events = 0
396define showallstacks
397 set $kgm_head_taskp = &default_pset.tasks
398 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
399 while $kgm_taskp != $kgm_head_taskp
400 showtaskheader
401 showtaskint $kgm_taskp
402 set $kgm_head_actp = &($kgm_taskp->threads)
403 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
404 while $kgm_actp != $kgm_head_actp
405 showactheader
406 if ($decode_wait_events > 0)
407 showactint $kgm_actp 1
408 else
409 showactint $kgm_actp 2
410 end
411 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
412 end
413 printf "\n"
414 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
415 end
416end
417
418document showallstacks
419| Routine to print out the stack for each thread in the system.
420| The following is the syntax:
421| (gdb) showallstacks
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.
425end
426
427define showcurrentstacks
428set $kgm_prp = processor_list
429 while $kgm_prp != 0
430 if ($kgm_prp)->active_thread != 0
431 set $kgm_actp = ($kgm_prp)->active_thread
432 showtaskheader
433 showtaskint ($kgm_actp)->task
434 showactheader
435 showactint $kgm_actp 1
436 printf "\n"
437 end
438 set $kgm_prp = ($kgm_prp)->processor_list
439 end
440end
441
442document showcurrentstacks
443| Routine to print out the thread running on each cpu (incl. its stack)
444| The following is the syntax:
445| (gdb) showcurrentstacks
446end
447
448define showwaiterheader
449 printf "waiters activation "
450 printf "thread pri state wait_queue wait_event\n"
451end
452
453define 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
464 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe
465 showactint $kgm_w_shuttle 0
466 end
467 set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_wqe->wqe_links.next
468 end
469end
470
471define 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
483end
484
485define showwaitqmembercount
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
493 end
494 printf "0x%08x ", $kgm_mc_count
495end
496
497
498define showwaitqmemberheader
499 printf "set-members wait_queue interlock "
500 printf "pol type member_cnt waiter_cnt\n"
501end
502
503define showwaitqmemberint
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 "
509 else
510 printf "Prio "
511 end
512 if ($kgm_m_waitqp->wq_type == 0xf1d1)
513 printf "Set "
514 showwaitqmembercount $kgm_m_waitqp
515 else
516 printf "Que 0x00000000 "
517 end
518 showwaitqwaitercount $kgm_m_waitqp
519 printf "\n"
520end
521
522
523define showwaitqmemberofheader
524 printf "member-of wait_queue interlock "
525 printf "pol type member_cnt waiter_cnt\n"
526end
527
528define 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
545end
546
547define showwaitqmembers
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
555 showwaitqmemberheader
556 set $kgm_ms_found = 1
557 end
558 showwaitqmemberint $kgm_ms_waitqp
559 set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_wql->wql_setlinks.next
560 end
561end
562
563define showwaitqheader
564 printf "wait_queue ref_count interlock "
565 printf "pol type member_cnt waiter_cnt\n"
566end
567
568define 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"
590end
591
592define showwaitq
593 set $kgm_waitq1p = (wait_queue_t)$arg0
594 showwaitqheader
595 showwaitqint $kgm_waitq1p
596 if ($kgm_waitq1p->wq_type == 0xf1d1)
597 showwaitqmembers $kgm_waitq1p
598 else
599 showwaitqmemberof $kgm_waitq1p
600 end
601 showwaitqwaiters $kgm_waitq1p
602end
603
604define showmapheader
605 printf "vm_map pmap vm_size "
606 printf "#ents rpage hint first_free\n"
607end
608
609define showvmeheader
610 printf " entry start "
611 printf " prot #page object offset\n"
612end
613
614define 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
621 if $kgm_map.pmap
622 printf "%5d ", $kgm_map.pmap->stats.resident_count
623 else
624 printf "<n/a> "
625 end
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
634 printf " 0x%08x ", $kgm_vmep
635 printf "0x%016llx ", $kgm_vme.links.start
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
661 printf "0x%016llx\n", $kgm_vme.offset
662 set $kgm_vmep = $kgm_vme.links.next
663 end
664 end
665 printf "\n"
666end
667
668
669define showmapvme
670 showmapheader
671 showvmint $arg0 1
672end
673document 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>
677end
678
679
680define showmap
681 showmapheader
682 showvmint $arg0 0
683end
684document showmap
685| Routine to print out info about the specified vm_map
686| The following is the syntax:
687| (gdb) showmap <vm_map>
688end
689
690define showallvm
691 set $kgm_head_taskp = &default_pset.tasks
692 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
693 while $kgm_taskp != $kgm_head_taskp
694 showtaskheader
695 showmapheader
696 showtaskint $kgm_taskp
697 showvmint $kgm_taskp->map 0
698 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
699 end
700end
701document showallvm
702| Routine to print a summary listing of all the vm maps
703| The following is the syntax:
704| (gdb) showallvm
705end
706
707
708define showallvme
709 set $kgm_head_taskp = &default_pset.tasks
710 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
711 while $kgm_taskp != $kgm_head_taskp
712 showtaskheader
713 showmapheader
714 showtaskint $kgm_taskp
715 showvmint $kgm_taskp->map 1
716 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
717 end
718end
719document showallvme
720| Routine to print a summary listing of all the vm map entries
721| The following is the syntax:
722| (gdb) showallvme
723end
724
725
726define showipcheader
727 printf "ipc_space is_table table_next "
728 printf "flags tsize splaytree splaybase\n"
729end
730
731define showipceheader
732 printf " name object "
733 printf "rite urefs destname destination\n"
734end
735
736define 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
776end
777
778define 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"
821end
822
823
824define showipc
825 set $kgm_isp = (ipc_space_t)$arg0
826 showipcheader
827 showipcint $kgm_isp 0
828end
829document showipc
830| Routine to print the status of the specified ipc space
831| The following is the syntax:
832| (gdb) showipc <ipc_space>
833end
834
835define showrights
836 set $kgm_isp = (ipc_space_t)$arg0
837 showipcheader
838 showipcint $kgm_isp 1
839end
840document 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>
844end
845
846
847define showtaskipc
848 set $kgm_taskp = (task_t)$arg0
849 showtaskheader
850 showipcheader
851 showtaskint $kgm_taskp
852 showipcint $kgm_taskp->itk_space 0
853end
854document showtaskipc
855| Routine to print info about the ipc space for a task
856| The following is the syntax:
857| (gdb) showtaskipc <task>
858end
859
860
861define showtaskrights
862 set $kgm_taskp = (task_t)$arg0
863 showtaskheader
864 showipcheader
865 showtaskint $kgm_taskp
866 showipcint $kgm_taskp->itk_space 1
867end
868document showtaskrights
869| Routine to print info about the ipc rights for a task
870| The following is the syntax:
871| (gdb) showtaskrights <task>
872end
873
874define showallipc
875 set $kgm_head_taskp = &default_pset.tasks
876 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
877 while $kgm_cur_taskp != $kgm_head_taskp
878 showtaskheader
879 showipcheader
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)
883 end
884end
885document showallipc
886| Routine to print a summary listing of all the ipc spaces
887| The following is the syntax:
888| (gdb) showallipc
889end
890
891
892define showallrights
893 set $kgm_head_taskp = &default_pset.tasks
894 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
895 while $kgm_cur_taskp != $kgm_head_taskp
896 showtaskheader
897 showipcheader
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)
901 end
902end
903document showallrights
904| Routine to print a summary listing of all the ipc rights
905| The following is the syntax:
906| (gdb) showallrights
907end
908
909
910define showtaskvm
911 set $kgm_taskp = (task_t)$arg0
912 showtaskheader
913 showmapheader
914 showtaskint $kgm_taskp
915 showvmint $kgm_taskp->map 0
916end
917document showtaskvm
918| Routine to print out info about a task's vm_map
919| The following is the syntax:
920| (gdb) showtaskvm <task>
921end
922
923define showtaskvme
924 set $kgm_taskp = (task_t)$arg0
925 showtaskheader
926 showmapheader
927 showtaskint $kgm_taskp
928 showvmint $kgm_taskp->map 1
929end
930document showtaskvme
931| Routine to print out info about a task's vm_map_entries
932| The following is the syntax:
933| (gdb) showtaskvme <task>
934end
935
936
937define showtaskheader
938 printf "task vm_map ipc_space #acts "
939 showprocheader
940end
941
942
943define showtaskint
944 set $kgm_task = *(struct task *)$arg0
945 printf "0x%08x ", $arg0
946 printf "0x%08x ", $kgm_task.map
947 printf "0x%08x ", $kgm_task.itk_space
948 printf "%3d ", $kgm_task.thread_count
949 showprocint $kgm_task.bsd_info
950end
951
952define showtask
953 showtaskheader
954 showtaskint $arg0
955end
956document showtask
957| Routine to print out info about a task.
958| The following is the syntax:
959| (gdb) showtask <task>
960end
961
962
963define showtaskthreads
964 showtaskheader
965 set $kgm_taskp = (struct task *)$arg0
966 showtaskint $kgm_taskp
967 showactheader
968 set $kgm_head_actp = &($kgm_taskp->threads)
969 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
970 while $kgm_actp != $kgm_head_actp
971 showactint $kgm_actp 0
972 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
973 end
974end
975document showtaskthreads
976| Routine to print info about the threads in a task.
977| The following is the syntax:
978| (gdb) showtaskthreads <task>
979end
980
981
982define showtaskstacks
983 showtaskheader
984 set $kgm_taskp = (struct task *)$arg0
985 showtaskint $kgm_taskp
986 set $kgm_head_actp = &($kgm_taskp->threads)
987 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
988 while $kgm_actp != $kgm_head_actp
989 showactheader
990 showactint $kgm_actp 1
991 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
992 end
993end
994document showtaskstacks
995| Routine to print out the stack for each thread in a task.
996| The following is the syntax:
997| (gdb) showtaskstacks <task>
998end
999
1000
1001define showalltasks
1002 showtaskheader
1003 set $kgm_head_taskp = &default_pset.tasks
1004 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1005 while $kgm_taskp != $kgm_head_taskp
1006 showtaskint $kgm_taskp
1007 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
1008 end
1009end
1010document showalltasks
1011| Routine to print a summary listing of all the tasks
1012| The following is the syntax:
1013| (gdb) showalltasks
1014end
1015
1016
1017define showprocheader
1018 printf " pid proc command\n"
1019end
1020
1021define 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
1030end
1031
1032define showpid
1033 showtaskheader
1034 set $kgm_head_taskp = &default_pset.tasks
1035 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
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
1042 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
1043 end
1044 end
1045end
1046document showpid
1047| Routine to print a single process by pid
1048| The following is the syntax:
1049| (gdb) showpid <pid>
1050end
1051
1052define showproc
1053 showtaskheader
1054 set $kgm_procp = (struct proc *)$arg0
1055 showtaskint $kgm_procp->task $arg1 $arg2
1056end
1057
1058
1059define kdb
1060 set switch_debugger=1
1061 continue
1062end
1063document 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.
1069end
1070
1071define showpsetheader
1072 printf "portset waitqueue recvname "
1073 printf "flags refs recvname process\n"
1074end
1075
1076define showportheader
1077 printf "port mqueue recvname "
1078 printf "flags refs recvname process\n"
1079end
1080
1081define showportmemberheader
1082 printf "members port recvname "
1083 printf "flags refs mqueue msgcount\n"
1084end
1085
1086define showkmsgheader
1087 printf "messages kmsg size "
1088 printf "disp msgid remote-port local-port\n"
1089end
1090
1091define 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
1110 printf "%5d ", $kgm_kmsgh.msgh_id
1111 printf "0x%08x ", $kgm_kmsgh.msgh_remote_port
1112 printf "0x%08x\n", $kgm_kmsgh.msgh_local_port
1113end
1114
1115
1116
1117define showkobject
1118 set $kgm_portp = (struct ipc_port *)$arg0
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"
1215end
1216
1217define showportdestproc
1218 set $kgm_portp = (struct ipc_port *)$arg0
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
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
1227 if ($kgm_destspacep == $kgm_spacep)
1228 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info
1229 else
1230 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->pset_tasks.next)
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
1237 printf "task 0x%08x\n", $kgm_desttaskp
1238 end
1239end
1240
1241define showportdest
1242 set $kgm_portp = (struct ipc_port *)$arg0
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
1254end
1255
1256define showportmember
1257 printf " 0x%08x ", $arg0
1258 set $kgm_portp = (struct ipc_port *)$arg0
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
1273end
1274
1275define showportint
1276 printf "0x%08x ", $arg0
1277 set $kgm_portp = (struct ipc_port *)$arg0
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
1287 set $kgm_destspacep = (struct ipc_space *)0
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
1300end
1301
1302define showpsetint
1303 printf "0x%08x ", $arg0
1304 set $kgm_psetp = (struct ipc_pset *)$arg0
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
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
1317 set $kgm_found = 0
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))
1320 if !$kgm_found
1321 set $kgm_destspacep = (struct ipc_space *)0
1322 showportdestproc $kgm_portp
1323 showportmemberheader
1324 set $kgm_found = 1
1325 end
1326 showportmember $kgm_portp 0
1327 set $kgm_wql = (struct wait_queue_link *)$kgm_wql->wql_setlinks.next
1328 end
1329 if !$kgm_found
1330 printf "--n/e--\n"
1331 end
1332end
1333
1334define showpset
1335 showpsetheader
1336 showpsetint $arg0 1
1337end
1338
1339define showport
1340 showportheader
1341 showportint $arg0 1
1342end
1343
1344define 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
1351end
1352
1353define showmqueue
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)
1358 set $kgm_pset = (((int)$arg0) - ((int)$kgm_psetoff))
1359 showpsetheader
1360 showpsetint $kgm_pset 1
1361 end
1362 if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d0)
1363 showportheader
1364 set $kgm_port = (((int)$arg0) - ((int)$kgm_portoff))
1365 showportint $kgm_port 1
1366 end
1367end
1368
1369define zprint_one
1370set $kgm_zone = (struct zone *)$arg0
1371
1372printf "0x%08x ", $kgm_zone
1373printf "%8d ",$kgm_zone->count
1374printf "%8x ",$kgm_zone->cur_size
1375printf "%8x ",$kgm_zone->max_size
1376printf "%6d ",$kgm_zone->elem_size
1377printf "%8x ",$kgm_zone->alloc_size
1378printf "%s ",$kgm_zone->zone_name
1379
1380if ($kgm_zone->exhaustible)
1381 printf "H"
1382end
1383if ($kgm_zone->collectable)
1384 printf "C"
1385end
1386if ($kgm_zone->expandable)
1387 printf "X"
1388end
1389printf "\n"
1390end
1391
1392
1393define zprint
1394printf "ZONE COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n"
1395set $kgm_zone_ptr = (struct zone *)first_zone
1396while ($kgm_zone_ptr != 0)
1397 zprint_one $kgm_zone_ptr
1398 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
1399end
1400printf "\n"
1401end
1402document zprint
1403| Routine to print a summary listing of all the kernel zones
1404| The following is the syntax:
1405| (gdb) zprint
1406end
1407
1408define showmtxgrp
1409set $kgm_mtxgrp = (lck_grp_t *)$arg0
1410
1411if ($kgm_mtxgrp->lck_grp_mtxcnt)
1412printf "0x%08x ", $kgm_mtxgrp
1413printf "%8d ",$kgm_mtxgrp->lck_grp_mtxcnt
1414printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
1415printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
1416printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
1417printf "%s ",&$kgm_mtxgrp->lck_grp_name
1418printf "\n"
1419end
1420end
1421
1422
1423define showallmtx
1424printf "LCK GROUP CNT UTIL MISS WAIT NAME\n"
1425set $kgm_mtxgrp_ptr = (lck_grp_t *)&lck_grp_queue
1426set $kgm_mtxgrp_ptr = (lck_grp_t *)$kgm_mtxgrp_ptr->lck_grp_link.next
1427while ($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
1430end
1431printf "\n"
1432end
1433document showallmtx
1434| Routine to print a summary listing of all mutexes
1435| The following is the syntax:
1436| (gdb) showallmtx
1437end
1438
1439define showrwlckgrp
1440set $kgm_rwlckgrp = (lck_grp_t *)$arg0
1441
1442if ($kgm_rwlckgrp->lck_grp_rwcnt)
1443printf "0x%08x ", $kgm_rwlckgrp
1444printf "%8d ",$kgm_rwlckgrp->lck_grp_rwcnt
1445printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
1446printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
1447printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
1448printf "%s ",&$kgm_rwlckgrp->lck_grp_name
1449printf "\n"
1450end
1451end
1452
1453
1454define showallrwlck
1455printf "LCK GROUP CNT UTIL MISS WAIT NAME\n"
1456set $kgm_rwlckgrp_ptr = (lck_grp_t *)&lck_grp_queue
1457set $kgm_rwlckgrp_ptr = (lck_grp_t *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1458while ($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
1461end
1462printf "\n"
1463end
1464document showallrwlck
1465| Routine to print a summary listing of all read/writer locks
1466| The following is the syntax:
1467| (gdb) showallrwlck
1468end
1469
1470set $kdp_act_counter = 0
1471
1472define switchtoact
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
1480 if ($kgm_mtype == 18)
1481 if ($kdp_act_counter == 0)
1482 set $kdpstate = (struct savearea *) kdp.saved_state
1483 end
1484 set $kdp_act_counter = $kdp_act_counter + 1
1485 set $newact = (struct thread *) $arg0
1486 set (struct savearea *) kdp.saved_state=$newact->machine->pcb
1487 flushregs
1488 flushstack
1489 set $pc=$newact->machine->pcb.save_srr0
1490 update
1491 else
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
1511 end
1512end
1513
1514document switchtoact
1515Syntax: 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.
1521end
1522
1523define switchtoctx
1524 if ($kgm_mtype == 18)
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
1530 flushregs
1531 flushstack
1532 set $pc=((struct savearea *) $arg0)->save_srr0
1533 update
1534 else
1535 echo switchtoctx not implemented for this architecture.\n
1536 end
1537end
1538
1539document switchtoctx
1540Syntax: 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.
1545end
1546
1547define resetctx
1548 if ($kgm_mtype == 18)
1549 set (struct savearea *)kdp.saved_state=$kdpstate
1550 flushregs
1551 flushstack
1552 set $pc=((struct savearea *) kdp.saved_state)->save_srr0
1553 update
1554 set $kdp_act_counter = 0
1555 else
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
1563 end
1564end
1565
1566document 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.
1571end
1572
1573define resume_on
1574 set noresume_on_disconnect = 0
1575end
1576
1577document resume_on
1578| Syntax: resume_on
1579| The target system will resume when detaching or exiting from gdb.
1580| This is the default behavior.
1581end
1582
1583define resume_off
1584 set noresume_on_disconnect = 1
1585end
1586
1587document 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
1591end
1592
1593define paniclog
1594 set $kgm_panic_bufptr = debug_buf
1595 set $kgm_panic_bufptr_max = debug_buf_ptr
1596 while $kgm_panic_bufptr < $kgm_panic_bufptr_max
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
1604end
1605
1606document paniclog
1607| Syntax: paniclog
1608| Display the panic log information
1609|
1610end
1611
1612define 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
1629end
1630
1631document dumpcallqueue
1632| Syntax: dumpcallqueue <queue head>
1633| Displays the contents of the specified call_entry queue.
1634end
1635
1636define showtaskacts
1637showtaskthreads $arg0
1638end
1639document showtaskacts
1640| See help showtaskthreads.
1641end
1642
1643define showallacts
1644showallthreads
1645end
1646document showallacts
1647| See help showallthreads.
1648end
1649
1650
1651define 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
1660end
1661
1662document resetstacks
1663| Syntax: resetstacks
1664| Internal kgmacro routine used by the "showuserstack" macro
1665| to reset the target pmap to the kernel pmap.
1666end
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.
1671define _kgm_flush_loop
1672 set $kgm_flush_loop_ctr = 0
1673 while ($kgm_flush_loop_ctr < 30)
1674 flushregs
1675 flushstack
1676 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1
1677 end
1678end
1679
1680define _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
1686end
1687
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
1695set $kgm_cur_ebp = 0
1696set $kgm_cur_eip = 0
1697
1698define 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
1721end
1722
1723define 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
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
1769end
1770document showuserstack
1771Syntax: 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.
1780end
1781
1782#Stopgap until gdb can generate the HOSTREBOOT packet
1783define kdp-reboot
1784 set flag_kdp_trigger_reboot = 1
1785 continue
1786end
1787
1788document kdp-reboot
1789Syntax: kdp-reboot
1790|Reboot the remote target machine; not guaranteed to succeed. Requires symbols
1791|until gdb support for the HOSTREBOOT packet is implemented.
1792end
1793
1794define 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
1804end
1805
1806document sendcore
1807Syntax: 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.
1815end
1816
1817define disablecore
1818 set kdp_trigger_core_dump = 0
1819 set kdp_flag |= 0x40
1820 set kdp_flag &= ~0x10
1821 set panicd_specified = 0
1822end
1823
1824document disablecore
1825Syntax: 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.
1829end
1830
1831#Use of this macro requires the gdb submission from 3401283
1832define 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
1853end
1854
1855document switchtocorethread
1856Syntax: 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.
1864end
1865
1866define 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
1904end
1905
1906define 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
1912end
1913
1914document resetcorectx
1915Syntax: 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.
1920end
1921
1922#Helper function for "showallgdbstacks"
1923
1924define 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
1965 set $kgm_statep = (struct x86_kernel_state32 *) \
1966 ($kgm_thread->kernel_stack + 0x4000 \
1967 - sizeof(struct x86_kernel_state32))
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
1982end
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
1990define 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
2007end
2008
2009document showallgdbstacks
2010Syntax: 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.
2020end
2021
2022define 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
2048end
2049
2050document switchtouserthread
2051Syntax: 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.
2074end
2075
2076define showmetaclass
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
2081end
2082
2083define showstring
2084 printf "\"%s\"", ((OSString *)$arg0)->string
2085end
2086
2087define shownumber
2088 printf "%lld", ((OSNumber *)$arg0)->value
2089end
2090
2091define showboolean
2092 if ($arg0 == gOSBooleanFalse)
2093 printf "No"
2094 else
2095 printf "Yes"
2096 end
2097end
2098
2099define 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 ">"
2158end
2159
2160define 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 "}"
2176end
2177
2178define 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
2187end
2188
2189define 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"
2207end
2208
2209
2210define 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
2221end
2222
2223define showarrayint
2224 printf "("
2225 showarraysetint $arg0 $arg1
2226 printf ")"
2227end
2228
2229define showsetint
2230 set $kgm_array = ((OSSet *)$arg1)->members
2231 printf "["
2232 showarraysetint $arg0 $kgm_array
2233 printf "]"
2234end
2235
2236
2237define 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
2287end
2288
2289define 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"
2297end
2298document 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>
2303end
2304
2305define 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
2316end
2317
2318
2319define 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
2413end
2414
2415define 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
2420end
2421
2422define showregistry
2423 set $kgm_reg_depth = 0
2424 set $kgm_show_props = 0
2425 showregistryentryint gRegistryRoot
2426end
2427document showregistry
2428| Show info about all registry entries in the current plane.
2429| The following is the syntax:
2430| (gdb) showregistry
2431end
2432
2433define showregistryprops
2434 set $kgm_reg_depth = 0
2435 set $kgm_show_props = 1
2436 showregistryentryint gRegistryRoot
2437end
2438document 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
2444end
2445
2446define showregistryentry
2447 set $kgm_reg_depth = 0
2448 set $kgm_show_props = 1
2449 showregistryentryint $arg0
2450end
2451document 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>
2455end
2456
2457define setregistryplane
2458 if ($arg0)
2459 set $kgm_reg_plane = (void **) $arg0
2460 else
2461 showobjectint _ gIORegistryPlanes
2462 printf "\n"
2463 end
2464end
2465document 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>
2470end
2471
2472define guessclass
2473 set $kgm_classidx = 0
2474 set $kgm_lookvt = *((void **) $arg0)
2475 set $kgm_bestvt = (void *) 0
2476 set $kgm_bestidx = 0
2477
2478 while $kgm_classidx < sAllClassesDict->count
2479 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value
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
2487 set $kgm_classidx = $kgm_classidx + 1
2488 end
2489 printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string
2490end
2491
2492define 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
2498end
2499
2500document 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
2504end
2505
2506define 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
2511end
2512
2513document 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
2517end
2518
2519define readphys
2520 set kdp_trans_off = 1
2521 x/x $arg0
2522 set kdp_trans_off = 0
2523end
2524
2525define 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
2533end
2534
2535document 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.
2539end
2540
2541document 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.
2545end