3 # These gdb macros should be useful during kernel development in
4 # determining what's going on in the kernel.
6 # All the convenience variables used by these macros begin with $kgm_
8 set print asm-demangle on
11 # This option tells gdb to relax its stack tracing heuristics
12 # Useful for debugging across stack switches
13 # (to the interrupt stack, for instance). Requires gdb-675 or greater.
14 set backtrace sanity-checks off
16 echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n
20 echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n
24 | These are the kernel gdb macros. These gdb macros are intended to be
25 | used when debugging a remote kernel via the kdp protocol. Typically, you
26 | would connect to your remote target like so:
27 | (gdb) target remote-kdp
28 | (gdb) attach <name-of-remote-host>
30 | The following macros are available in this package:
31 | showversion Displays a string describing the remote kernel version
33 | showalltasks Display a summary listing of all tasks
34 | showallthreads Display info about all threads in the system
35 | showallstacks Display the stack for each thread in the system
36 | showcurrentthreads Display info about the thread running on each cpu
37 | showcurrentstacks Display the stack for the thread running on each cpu
38 | showallvm Display a summary listing of all the vm maps
39 | showallvme Display a summary listing of all the vm map entries
40 | showallipc Display a summary listing of all the ipc spaces
41 | showallrights Display a summary listing of all the ipc rights
42 | showallkmods Display a summary listing of all the kernel modules
43 | showallbusyports Display a listing of all ports with unread messages
45 | showallclasses Display info about all OSObject subclasses in the system
46 | showobject Show info about an OSObject - its vtable ptr and retain count, & more info for simple container classes.
47 | showregistry Show info about all registry entries in the current plane
48 | showregistryprops Show info about all registry entries in the current plane, and their properties
49 | showregistryentry Show info about a registry entry; its properties and descendants in the current plane
50 | setregistryplane Set the plane to be used for the iokit registry macros (pass zero for list)
52 | setfindregistrystr Set the encoded string for matching with
53 | findregistryentry or findregistryprop (created from
55 | findregistryentry Find a registry entry that matches the encoded string
56 | findregistryentries Find all the registry entries that match the encoded string
57 | findregistryprop Search the registry entry for a property that matches
60 | showtask Display info about the specified task
61 | showtaskthreads Display info about the threads in the task
62 | showtaskstacks Display the stack for each thread in the task
63 | showtaskvm Display info about the specified task's vm_map
64 | showtaskvme Display info about the task's vm_map entries
65 | showtaskipc Display info about the specified task's ipc space
66 | showtaskrights Display info about the task's ipc space entries
67 | showtaskrightsbt Display info about the task's ipc space entries with back traces
68 | showtaskbusyports Display all of the task's ports with unread messages
70 | showact Display info about a thread specified by activation
71 | showactstack Display the stack for a thread specified by activation
73 | showmap Display info about the specified vm_map
74 | showmapvme Display a summary list of the specified vm_map's entries
76 | showipc Display info about the specified ipc space
77 | showrights Display a summary list of all the rights in an ipc space
79 | showpid Display info about the process identified by pid
80 | showproc Display info about the process identified by proc struct
81 | showprocinfo Display detailed info about the process identified by proc struct
82 | showprocfiles Given a proc_t pointer, display the list of open file descriptors
83 | showproclocks Given a proc_t pointer, display the list of advisory file locks
84 | zombproc Print out all procs in the zombie list
85 | allproc Print out all process in the system not in the zombie list
86 | zombstacks Print out all stacks of tasks that are exiting
88 | showinitchild Print out all processes in the system which are children of init process
90 | showkmod Display info about a kernel module
91 | showkmodaddr Given an address, display the kernel module and offset
93 | dumpcallqueue Dump out all the entries given a queue head
95 | showallmtx Display info about mutexes usage
96 | showallrwlck Display info about reader/writer locks usage
98 | zprint Display info about the memory zones
99 | showioalloc Display info about iokit allocations
100 | paniclog Display the panic log info
102 | switchtoact Switch to different context specified by activation
103 | switchtoctx Switch to different context
104 | showuserstack Display numeric backtrace of the user stack for an
107 | switchtouserthread Switch to the user context of the specified thread
108 | resetstacks Return to the original kernel context
110 | resetctx Reset context
111 | resume_on Resume when detaching from gdb
112 | resume_off Don't resume when detaching from gdb
114 | sendcore Configure kernel to send a coredump to the specified IP
115 | sendsyslog Configure kernel to send a system log to the specified IP
116 | sendpaniclog Configure kernel to send a panic log to the specified IP
117 | disablecore Configure the kernel to disable coredump transmission
118 | getdumpinfo Retrieve the current remote dump parameters
119 | setdumpinfo Configure the remote dump parameters
121 | switchtocorethread Corefile version of "switchtoact"
122 | resetcorectx Corefile version of "resetctx"
124 | readphys8 Reads the specified untranslated address (8-bit read)
125 | readphys16 Reads the specified untranslated address (16-bit read)
126 | readphys32 Reads the specified untranslated address (32-bit read)
127 | readphys64 Reads the specified untranslated address (64-bit read)
128 | writephys8 Writes to the specified untranslated address (8-bit write)
129 | writephys16 Writes to the specified untranslated address (16-bit write)
130 | writephys32 Writes to the specified untranslated address (32-bit write)
131 | writephys64 Writes to the specified untranslated address (64-bit write)
133 | readioport8 Read 8-bits from the specified I/O Port
134 | readioport16 Read 16-bits from the specified I/O Port
135 | readioport32 Read 32-bits from the specified I/O Port
136 | writeioport8 Write 8-bits into the specified I/O Port
137 | writeioport16 Write 16-bits into the specified I/O Port
138 | writeioport32 Write 32-bits into the specified I/O Port
140 | readmsr64 Read 64-bits from the specified MSR
141 | writemsr64 Write 64-bits into the specified MSR
143 | rtentry_showdbg Print the debug information of a route entry
144 | rtentry_trash Walk the list of trash route entries
146 | inifa_showdbg Print the debug information of an IPv4 interface address
147 | in6ifa_showdbg Print the debug information of an IPv6 interface address
149 | mbuf_walkpkt Walk the mbuf packet chain (m_nextpkt)
150 | mbuf_walk Walk the mbuf chain (m_next)
151 | mbuf_buf2slab Find the slab structure of the corresponding buffer
152 | mbuf_buf2mca Find the mcache audit structure of the corresponding mbuf
153 | mbuf_showmca Print the contents of an mbuf mcache audit structure
154 | mbuf_showactive Print all active/in-use mbuf objects
155 | mbuf_showinactive Print all freed/in-cache mbuf objects
156 | mbuf_showall Print all mbuf objects
157 | mbuf_slabs Print all slabs in the group
158 | mbuf_slabstbl Print slabs table
159 | mbuf_stat Print extended mbuf allocator statistics
161 | mcache_walkobj Walk the mcache object chain (obj_next)
162 | mcache_stat Print all mcaches in the system
163 | mcache_showcache Display the number of objects in the cache
165 | showbootargs Display boot arguments passed to the target kernel
166 | showbootermemorymap Dump phys memory map from EFI
168 | systemlog Display the kernel's printf ring buffer
170 | hexdump Show the contents of memory as a hex/ASCII dump
172 | showvnodepath Print the path for a vnode
173 | showvnodelocks Display list of advisory locks held/blocked on a vnode
174 | showvnodedev Display information about a device vnode
175 | showtty Display information about a struct tty
176 | showallvols Display a summary of mounted volumes
177 | showvnode Display info about one vnode
178 | showvolvnodes Display info about all vnodes of a given volume
179 | showvolbusyvnodes Display info about busy (iocount!=0) vnodes of a given volume
180 | showallbusyvnodes Display info about all busy (iocount!=0) vnodes
181 | showallvnodes Display info about all vnodes
182 | print_vnode Print out the fields of a vnode struct
183 | showprocvnodes Print out all the open fds which are vnodes in a process
184 | showallprocvnodes Print out all the open fds which are vnodes in any process
185 | showmountvnodes Print the vnode list
186 | showmountallvnodes Print the vnode inactive list
187 | showworkqvnodes Print the vnode worker list
188 | shownewvnodes Print the new vnode list
190 | ifconfig display ifconfig-like output
191 | showifaddrs show the list of addresses for the given ifp
192 | showifmultiaddrs show the list of multicast addresses for the given ifp
194 | showsocket Display information about a socket
195 | showprocsockets Given a proc_t pointer, display information about its sockets
196 | showallprocsockets Display information about the sockets of all the processes
198 | show_tcp_pcbinfo Display the list of the TCP protocol control blocks
199 | show_tcp_timewaitslots Display the list of the TCP protocol control blocks in TIMEWAIT
200 | show_udp_pcbinfo Display the list of UDP protocol control blocks
202 | show_rt_inet Display the IPv4 routing table
203 | show_rt_inet6 Display the IPv6 routing table
205 | showallpmworkqueues Display info about all IOPMWorkQueue objects
206 | showregistrypmstate Display power management state for all IOPower registry entries
207 | showioservicepm Display the IOServicePM object
208 | showstacksaftertask showallstacks starting after a given task
209 | showstacksafterthread showallstacks starting after a given thread
211 | showMCAstate Print machine-check register state after MC exception.
213 | showallgdbstacks Cause GDB to trace all thread stacks
214 | showallgdbcorestacks Corefile equivalent of "showallgdbstacks"
215 | kdp-reenter Schedule reentry into the debugger and continue.
216 | kdp-reboot Restart remote target
217 | kdp-version Get KDP version number
218 | kdp-connect "shorthand" connection macro
220 | zstack Print zalloc caller stack (zone leak debugging)
221 | findoldest Find oldest zone leak debugging record
222 | countpcs Print how often a pc occurs in the zone leak log
224 | pmap_walk Perform a page-table walk
225 | pmap_vtop Translate a virtual address to physical address
227 | showuserlibraries Show binary images known by dyld in the target task
229 | showthreadfortid Displays the address of the thread structure for a given thread_id value.
231 | strcmp_nomalloc A version of strcmp that avoids the use of malloc
232 | through the use of encoded strings created via
234 | strcmp_arg_pack64 Pack a string into a 64-bit quantity for use by
237 | pci_cfg_read8 Read 8-bits from a PCI config space register
238 | pci_cfg_read16 Read 16-bits from a PCI config space register
239 | pci_cfg_read32 Read 32-bits from a PCI config space register
240 | pci_cfg_write8 Write 8-bits into a PCI config space register
241 | pci_cfg_write16 Write 16-bits into a PCI config space register
242 | pci_cfg_write32 Write 32-bits into a PCI config space register
243 | pci_cfg_dump Dump entire config space for a PCI device
244 | pci_cfg_scan Perform a scan for PCI devices
245 | pci_cfg_dump_all Dump config spaces for all detected PCI devices
247 | lapic_read32 Read APIC entry
248 | lapic_write32 Write APIC entry
249 | lapic_dump Dump APIC entries
251 | ioapic_read32 Read IOAPIC entry
252 | ioapic_write32 Write IOAPIC entry
253 | ioapic_dump Dump IOAPIC entries
255 | Type "help <macro>" for more specific help on a particular macro.
256 | Type "show user <macro>" to see what the macro is really doing.
259 # This macro should appear before any symbol references, to facilitate
260 # a gdb "source" without a loaded symbol file.
267 | Read the kernel version string from a fixed address in low
268 | memory. Useful if you don't know which kernel is on the other end,
269 | and need to find the appropriate symbols. Beware that if you've
270 | loaded a symbol file, but aren't connected to a remote target,
271 | the version string from the symbol file will be displayed instead.
272 | This macro expects to be connected to the remote kernel to function
276 set $kgm_mtype_ppc = 0x00000012
277 set $kgm_mtype_arm = 0x0000000C
279 set $kgm_mtype_i386 = 0x00000007
280 set $kgm_mtype_x86_64 = 0x01000007
281 set $kgm_mtype_x86_any = $kgm_mtype_i386
282 set $kgm_mtype_x86_mask = 0xFEFFFFFF
284 set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
285 set $kgm_lp64 = $kgm_mtype & 0x01000000
287 set $kgm_manual_pkt_ppc = 0x549C
288 set $kgm_manual_pkt_i386 = 0x249C
289 set $kgm_manual_pkt_x86_64 = 0xFFFFFF8000002930
290 set $kgm_manual_pkt_arm = 0xFFFF04A0
292 set $kgm_kdp_pkt_data_len = 128
294 # part of data packet
295 set $kgm_kdp_pkt_hdr_req_off = 0
296 set $kgm_kdp_pkt_hdr_seq_off = 1
297 set $kgm_kdp_pkt_hdr_len_off = 2
298 set $kgm_kdp_pkt_hdr_key_off = 4
301 set $kgm_kdp_pkt_len_off = $kgm_kdp_pkt_data_len
302 set $kgm_kdp_pkt_input_off = $kgm_kdp_pkt_data_len + 4
304 set $kgm_kdp_pkt_hostreboot = 0x13
305 set $kgm_kdp_pkt_hdr_size = 8
307 set $kgm_lcpu_self = 0xFFFE
309 set $kgm_reg_depth = 0
310 set $kgm_reg_depth_max = 0xFFFF
311 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
312 set $kgm_namekey = (OSSymbol *) 0
313 set $kgm_childkey = (OSSymbol *) 0
315 set $kgm_show_object_addrs = 0
316 set $kgm_show_object_retain = 0
317 set $kgm_show_props = 0
318 set $kgm_show_data_alwaysbytes = 0
320 set $kgm_show_kmod_syms = 0
322 # send a manual packet header that doesn't require knowing the location
327 set $hdrp = (uint32_t *) $kgm_manual_pkt_i386
328 if ($kgm_mtype == $kgm_mtype_ppc)
329 set $hdrp = (uint32_t *) $kgm_manual_pkt_ppc
330 set $req = $req << 1 # shift to deal with endiannness
332 if ($kgm_mtype == $kgm_mtype_x86_64)
333 set $hdrp = (uint64_t *) $kgm_manual_pkt_x86_64
335 if ($kgm_mtype == $kgm_mtype_arm)
336 set $hdrp = (uint32_t *) $kgm_manual_pkt_arm
339 set $pkt_hdr = *$hdrp
340 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off)) = 0
341 set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_len_off)) = $kgm_kdp_pkt_hdr_size
343 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_req_off)) = $req
344 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_seq_off)) = 0
345 set *((uint16_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_len_off)) = $kgm_kdp_pkt_hdr_size
346 set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_key_off)) = 0
347 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off)) = 1
349 # dummy to make sure manual packet is executed
350 set $kgm_dummy = &_mh_execute_header
356 printf "0x%016llx", $arg0
358 printf "0x%08x", $arg0
362 # for headers, leave 8 chars for LP64 pointers
369 define showkmodheader
376 printf " id refs version name\n"
380 set $kgm_kmodp = (struct kmod_info *)$arg0
383 showptr $kgm_kmodp->address
385 showptr $kgm_kmodp->size
387 printf "%3d ", $kgm_kmodp->id
388 printf "%5d ", $kgm_kmodp->reference_count
389 printf "%10s ", $kgm_kmodp->version
390 printf "%s\n", $kgm_kmodp->name
393 # cached info of the last kext found, to speed up subsequent lookups
398 define showkmodaddrint
400 if ((unsigned long)$arg0 >= (unsigned long)$kgm_pkmodst) && ((unsigned long)$arg0 < (unsigned long)$kgm_pkmoden)
401 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_pkmodst)
402 printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off
404 set $kgm_kmodp = (struct kmod_info *)kmod
405 if ($kgm_mtype == $kgm_mtype_x86_64) && ($arg0 >= (unsigned long)&_mh_execute_header)
406 # kexts are loaded below the kernel for x86_64
410 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_kmodp->address)
411 if ($kgm_kmodp->address <= $arg0) && ($kgm_off < $kgm_kmodp->size)
412 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off
413 set $kgm_pkmod = $kgm_kmodp
414 set $kgm_pkmodst = $kgm_kmodp->address
415 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmodp->size
418 set $kgm_kmodp = $kgm_kmodp->next
425 showkmodaddrint $arg0
428 document showkmodaddr
429 Syntax: (gdb) showkmodaddr <addr>
430 | Given an address, print the offset and name for the kmod containing it
438 Syntax: (gdb) showkmod <kmod>
439 | Routine to print info about a kernel module
444 set $kgm_kmodp = (struct kmod_info *)kmod
446 showkmodint $kgm_kmodp
447 set $kgm_kmodp = $kgm_kmodp->next
450 document showallkmods
451 Syntax: (gdb) showallkmods
452 | Routine to print a summary listing of all the kernel modules
464 printf " pri io_policy state wait_queue"
466 printf " wait_event\n"
473 set $kgm_thread = *(struct thread *)$arg0
475 if ($kgm_thread.static_param)
480 printf " %7ld ", $kgm_thread.thread_id
481 showptr $kgm_thread.last_processor
482 printf " %3d ", $kgm_thread.sched_pri
483 if ($kgm_thread.uthread != 0)
485 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
486 if ($kgm_uthread->uu_flag & 0x400)
491 if ($kgm_uthread->uu_iopol_disk == 1)
495 if ($kgm_uthread->uu_iopol_disk == 2)
499 if ($kgm_uthread->uu_iopol_disk == 3)
503 if ($kgm_printed == 0)
507 set $kgm_state = $kgm_thread.state
532 showptr $kgm_thread.wait_queue
534 if (((unsigned long)$kgm_thread.wait_event > (unsigned long)&last_kernel_symbol) \
535 && ($arg1 != 2) && ($kgm_show_kmod_syms == 0))
536 showkmodaddr $kgm_thread.wait_event
538 output /a $kgm_thread.wait_event
540 if ($kgm_thread.uthread != 0)
541 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
542 if ($kgm_uthread->uu_wmesg != 0)
543 printf "\t \"%s\"", $kgm_uthread->uu_wmesg
548 if ($kgm_thread.kernel_stack != 0)
549 if ($kgm_thread.reserved_stack != 0)
552 printf " reserved_stack="
553 showptr $kgm_thread.reserved_stack
557 printf " kernel_stack="
558 showptr $kgm_thread.kernel_stack
559 if ($kgm_mtype == $kgm_mtype_ppc)
560 set $mysp = $kgm_thread.machine.pcb->save_r1
562 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
563 set $kgm_statep = (struct x86_kernel_state *) \
564 ($kgm_thread->kernel_stack + kernel_stack_size \
565 - sizeof(struct x86_kernel_state))
566 if ($kgm_mtype == $kgm_mtype_i386)
567 set $mysp = $kgm_statep->k_ebp
569 set $mysp = $kgm_statep->k_rbp
572 if ($kgm_mtype == $kgm_mtype_arm)
573 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
574 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
577 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
578 set $mysp = $kgm_statep->r[7]
581 set $prevsp = $mysp - 16
586 if ($kgm_mtype == $kgm_mtype_ppc)
592 while ($mysp != 0) && (($mysp & $stkmask) == 0) \
593 && ($mysp != $prevsp) \
594 && ((((unsigned long) $mysp ^ (unsigned long) $prevsp) < 0x2000) \
595 || (((unsigned long)$mysp < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
596 && ((unsigned long)$mysp > (unsigned long) ($kgm_thread->kernel_stack))))
602 if ($kgm_mtype == $kgm_mtype_ppc)
603 set $kgm_return = *($mysp + 8)
605 if ($kgm_mtype == $kgm_mtype_i386)
606 set $kgm_return = *($mysp + 4)
608 if ($kgm_mtype == $kgm_mtype_x86_64)
609 set $kgm_return = *(unsigned long *)($mysp + 8)
611 if ($kgm_mtype == $kgm_mtype_arm)
612 set $kgm_return = *($mysp + 4)
614 if (((unsigned long) $kgm_return < (unsigned long) &_mh_execute_header || \
615 (unsigned long) $kgm_return >= (unsigned long) &last_kernel_symbol ) \
616 && ($kgm_show_kmod_syms == 0))
617 showkmodaddr $kgm_return
619 output /a $kgm_return
622 set $mysp = *(unsigned long *)$mysp
627 printf " stackbottom="
632 printf " continuation="
633 output /a $kgm_thread.continuation
646 Syntax: (gdb) showact <activation>
647 | Routine to print out the state of a specific thread.
655 document showactstack
656 Syntax: (gdb) showactstack <activation>
657 | Routine to print out the stack of a specific thread.
661 define showallthreads
662 set $kgm_head_taskp = &tasks
663 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
664 while $kgm_taskp != $kgm_head_taskp
666 showtaskint $kgm_taskp
668 set $kgm_head_actp = &($kgm_taskp->threads)
669 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
670 while $kgm_actp != $kgm_head_actp
671 showactint $kgm_actp 0
672 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
675 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
678 document showallthreads
679 Syntax: (gdb) showallthreads
680 | Routine to print out info about all threads in the system.
683 define showcurrentthreads
684 set $kgm_prp = (struct processor *)processor_list
686 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_id
687 if ($kgm_prp)->active_thread != 0
688 set $kgm_actp = ($kgm_prp)->active_thread
690 showtaskint ($kgm_actp)->task
692 showactint $kgm_actp 0
695 set $kgm_prp = ($kgm_prp)->processor_list
698 document showcurrentthreads
699 Syntax: (gdb) showcurrentthreads
700 | Routine to print out info about the thread running on each cpu.
703 set $decode_wait_events = 0
705 set $kgm_head_taskp = &tasks
706 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
707 while $kgm_taskp != $kgm_head_taskp
709 showtaskint $kgm_taskp
710 set $kgm_head_actp = &($kgm_taskp->threads)
711 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
712 while $kgm_actp != $kgm_head_actp
714 if ($decode_wait_events > 0)
715 showactint $kgm_actp 1
717 showactint $kgm_actp 2
719 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
722 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
726 document showallstacks
727 Syntax: (gdb) showallstacks
728 | Routine to print out the stack for each thread in the system.
729 | If the variable $decode_wait_events is non-zero, the routine attempts to
730 | interpret thread wait_events as kernel module offsets, which can add to
734 define showcurrentstacks
735 set $kgm_prp = processor_list
737 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_id
738 if ($kgm_prp)->active_thread != 0
739 set $kgm_actp = ($kgm_prp)->active_thread
741 showtaskint ($kgm_actp)->task
743 showactint $kgm_actp 1
746 set $kgm_prp = ($kgm_prp)->processor_list
750 document showcurrentstacks
751 Syntax: (gdb) showcurrentstacks
752 | Routine to print out the thread running on each cpu (incl. its stack)
755 define showwaiterheader
756 printf "waiters thread "
757 printf "processor pri state wait_queue wait_event\n"
760 define showwaitqwaiters
761 set $kgm_w_waitqp = (WaitQueue*)$arg0
762 set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue)
763 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_linksp->next
765 while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp)
766 if ($kgm_w_wqe->wqe_type != &_wait_queue_link)
771 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe
772 showactint $kgm_w_shuttle 0
774 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_wqe->wqe_links.next
778 define showwaitqwaitercount
779 set $kgm_wc_waitqp = (WaitQueue*)$arg0
780 set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue)
781 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_linksp->next
782 set $kgm_wc_count = 0
783 while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp)
784 if ($kgm_wc_wqe->wqe_type != &_wait_queue_link)
785 set $kgm_wc_count = $kgm_wc_count + 1
787 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_wqe->wqe_links.next
789 printf "0x%08x ", $kgm_wc_count
792 define showwaitqmembercount
793 set $kgm_mc_waitqsetp = (WaitQueueSet*)$arg0
794 set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks)
795 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_setlinksp->next
796 set $kgm_mc_count = 0
797 while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp)
798 set $kgm_mc_count = $kgm_mc_count + 1
799 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_wql->wql_setlinks.next
801 printf "0x%08x ", $kgm_mc_count
805 define showwaitqmemberheader
806 printf "set-members wait_queue interlock "
807 printf "pol type member_cnt waiter_cnt\n"
810 define showwaitqmemberint
811 set $kgm_m_waitqp = (WaitQueue*)$arg0
812 printf " 0x%08x ", $kgm_m_waitqp
813 printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data
814 if ($kgm_m_waitqp->wq_fifo)
819 if ($kgm_m_waitqp->wq_type == 0xf1d1)
821 showwaitqmembercount $kgm_m_waitqp
823 printf "Que 0x00000000 "
825 showwaitqwaitercount $kgm_m_waitqp
830 define showwaitqmemberofheader
831 printf "member-of wait_queue interlock "
832 printf "pol type member_cnt waiter_cnt\n"
835 define showwaitqmemberof
836 set $kgm_mo_waitqp = (WaitQueue*)$arg0
837 set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue)
838 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_linksp->next
839 set $kgm_mo_found = 0
840 while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp)
841 if ($kgm_mo_wqe->wqe_type == &_wait_queue_link)
843 set $kgm_mo_found = 1
844 showwaitqmemberofheader
846 set $kgm_mo_wqlp = (WaitQueueLink *)$kgm_mo_wqe
847 set $kgm_mo_wqsetp = (WaitQueue*)($kgm_mo_wqlp->wql_setqueue)
848 showwaitqmemberint $kgm_mo_wqsetp
850 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_wqe->wqe_links.next
854 define showwaitqmembers
855 set $kgm_ms_waitqsetp = (WaitQueueSet*)$arg0
856 set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks)
857 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_setlinksp->next
858 set $kgm_ms_found = 0
859 while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp)
860 set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue
862 showwaitqmemberheader
863 set $kgm_ms_found = 1
865 showwaitqmemberint $kgm_ms_waitqp
866 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_wql->wql_setlinks.next
870 define showwaitqheader
871 printf "wait_queue ref_count interlock "
872 printf "pol type member_cnt waiter_cnt\n"
876 set $kgm_waitqp = (WaitQueue*)$arg0
877 printf "0x%08x ", $kgm_waitqp
878 if ($kgm_waitqp->wq_type == 0xf1d1)
879 printf "0x%08x ", ((WaitQueueSet*)$kgm_waitqp)->wqs_refcount
883 printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data
884 if ($kgm_waitqp->wq_fifo)
889 if ($kgm_waitqp->wq_type == 0xf1d1)
891 showwaitqmembercount $kgm_waitqp
893 printf "Que 0x00000000 "
895 showwaitqwaitercount $kgm_waitqp
900 set $kgm_waitq1p = (WaitQueue*)$arg0
902 showwaitqint $kgm_waitq1p
903 if ($kgm_waitq1p->wq_type == 0xf1d1)
904 showwaitqmembers $kgm_waitq1p
906 showwaitqmemberof $kgm_waitq1p
908 showwaitqwaiters $kgm_waitq1p
918 printf " #ents rpage hint "
920 printf " first_free\n"
926 printf " start prot #page object "
932 set $kgm_mapp = (vm_map_t)$arg0
933 set $kgm_map = *$kgm_mapp
936 showptr $kgm_map.pmap
938 showptr $kgm_map.size
939 printf " %3d ", $kgm_map.hdr.nentries
941 printf "%5d ", $kgm_map.pmap->stats.resident_count
945 showptr $kgm_map.hint
947 showptr $kgm_map.first_free
951 set $kgm_head_vmep = &($kgm_mapp->hdr.links)
952 set $kgm_vmep = $kgm_map.hdr.links.next
953 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
954 set $kgm_vme = *$kgm_vmep
957 printf " 0x%016llx ", $kgm_vme.links.start
958 printf "%1x", $kgm_vme.protection
959 printf "%1x", $kgm_vme.max_protection
960 if $kgm_vme.inheritance == 0x0
963 if $kgm_vme.inheritance == 0x1
966 if $kgm_vme.inheritance == 0x2
969 if $kgm_vme.inheritance == 0x3
972 if $kgm_vme.is_sub_map
975 if $kgm_vme.needs_copy
981 printf "%6d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
982 showptr $kgm_vme.object.vm_object
983 printf " 0x%016llx\n", $kgm_vme.offset
984 set $kgm_vmep = $kgm_vme.links.next
996 Syntax: (gdb) showmapvme <vm_map>
997 | Routine to print out a summary listing of all the entries in a vm_map
1006 Syntax: (gdb) showmap <vm_map>
1007 | Routine to print out info about the specified vm_map
1011 set $kgm_head_taskp = &tasks
1012 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1013 while $kgm_taskp != $kgm_head_taskp
1016 showtaskint $kgm_taskp
1017 showvmint $kgm_taskp->map 0
1018 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1022 Syntax: (gdb) showallvm
1023 | Routine to print a summary listing of all the vm maps
1028 set $kgm_head_taskp = &tasks
1029 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1030 while $kgm_taskp != $kgm_head_taskp
1033 showtaskint $kgm_taskp
1034 showvmint $kgm_taskp->map 1
1035 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1039 Syntax: (gdb) showallvme
1040 | Routine to print a summary listing of all the vm map entries
1044 define showipcheader
1049 printf " table_next"
1051 printf " flags tsize splaytree splaybase\n"
1054 define showipceheader
1055 printf " name object "
1057 printf " rite urefs destname destination\n"
1061 set $kgm_ie = *(ipc_entry_t)$arg0
1062 printf " 0x%08x ", $arg1
1063 showptr $kgm_ie.ie_object
1065 if $kgm_ie.ie_bits & 0x00100000
1067 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1069 if $kgm_ie.ie_bits & 0x00080000
1071 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1073 if $kgm_ie.ie_bits & 0x00010000
1074 if $kgm_ie.ie_bits & 0x00020000
1080 if $kgm_ie.ie_bits & 0x00020000
1084 if $kgm_ie.ie_bits & 0x00040000
1087 if $kgm_ie.index.request
1092 if $kgm_ie.ie_bits & 0x00800000
1097 printf "%5d ", $kgm_ie.ie_bits & 0xffff
1098 showportdest $kgm_ie.ie_object
1104 set $kgm_isp = (ipc_space_t)$arg0
1105 set $kgm_is = *$kgm_isp
1108 showptr $kgm_is.is_table
1110 showptr $kgm_is.is_table_next
1112 if $kgm_is.is_growing != 0
1117 if $kgm_is.is_fast != 0
1122 if $kgm_is.is_active != 0
1127 printf "%5d ", $kgm_is.is_table_size
1128 printf "0x%08x ", $kgm_is.is_tree_total
1129 showptr &$kgm_isp->is_tree
1134 set $kgm_iep = $kgm_is.is_table
1135 set $kgm_destspacep = (ipc_space_t)0
1136 while ( $kgm_iindex < $kgm_is.is_table_size )
1137 set $kgm_ie = *$kgm_iep
1138 if $kgm_ie.ie_bits & 0x001f0000
1139 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24))
1140 showipceint $kgm_iep $kgm_name
1141 if $arg2 != 0 && $kgm_ie.ie_object != 0 && ($kgm_ie.ie_bits & 0x00070000) && ((ipc_port_t) $kgm_ie.ie_object)->ip_callstack[0] != 0
1143 showportbt $kgm_ie.ie_object $kgm_is.is_task
1146 set $kgm_iindex = $kgm_iindex + 1
1147 set $kgm_iep = &($kgm_is.is_table[$kgm_iindex])
1149 if $kgm_is.is_tree_total
1150 printf "Still need to write tree traversal\n"
1158 set $kgm_isp = (ipc_space_t)$arg0
1160 showipcint $kgm_isp 0 0
1163 Syntax: (gdb) showipc <ipc_space>
1164 | Routine to print the status of the specified ipc space
1168 set $kgm_isp = (ipc_space_t)$arg0
1170 showipcint $kgm_isp 1 0
1173 Syntax: (gdb) showrights <ipc_space>
1174 | Routine to print a summary list of all the rights in a specified ipc space
1179 set $kgm_taskp = (task_t)$arg0
1182 showtaskint $kgm_taskp
1183 showipcint $kgm_taskp->itk_space 0 0
1185 document showtaskipc
1186 Syntax: (gdb) showtaskipc <task>
1187 | Routine to print info about the ipc space for a task
1191 define showtaskrights
1192 set $kgm_taskp = (task_t)$arg0
1195 showtaskint $kgm_taskp
1196 showipcint $kgm_taskp->itk_space 1 0
1198 document showtaskrights
1199 Syntax: (gdb) showtaskrights <task>
1200 | Routine to print info about the ipc rights for a task
1203 define showtaskrightsbt
1204 set $kgm_taskp = (task_t)$arg0
1207 showtaskint $kgm_taskp
1208 showipcint $kgm_taskp->itk_space 1 1
1210 document showtaskrightsbt
1211 Syntax: (gdb) showtaskrightsbt <task>
1212 | Routine to print info about the ipc rights for a task with backtraces
1216 set $kgm_head_taskp = &tasks
1217 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1218 while $kgm_cur_taskp != $kgm_head_taskp
1221 showtaskint $kgm_cur_taskp
1222 showipcint $kgm_cur_taskp->itk_space 0 0
1223 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1227 Syntax: (gdb) showallipc
1228 | Routine to print a summary listing of all the ipc spaces
1232 define showallrights
1233 set $kgm_head_taskp = &tasks
1234 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1235 while $kgm_cur_taskp != $kgm_head_taskp
1238 showtaskint $kgm_cur_taskp
1239 showipcint $kgm_cur_taskp->itk_space 1 0
1240 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1243 document showallrights
1244 Syntax: (gdb) showallrights
1245 | Routine to print a summary listing of all the ipc rights
1250 set $kgm_taskp = (task_t)$arg0
1253 showtaskint $kgm_taskp
1254 showvmint $kgm_taskp->map 0
1257 Syntax: (gdb) showtaskvm <task>
1258 | Routine to print out info about a task's vm_map
1262 set $kgm_taskp = (task_t)$arg0
1265 showtaskint $kgm_taskp
1266 showvmint $kgm_taskp->map 1
1268 document showtaskvme
1269 Syntax: (gdb) showtaskvme <task>
1270 | Routine to print out info about a task's vm_map_entries
1274 define showtaskheader
1279 printf " ipc_space "
1287 set $kgm_taskp = (struct task *)$arg0
1290 showptr $kgm_taskp->map
1292 showptr $kgm_taskp->itk_space
1293 printf " %5d ", $kgm_taskp->thread_count
1294 showprocint $kgm_taskp->bsd_info
1302 Syntax (gdb) showtask <task>
1303 | Routine to print out info about a task.
1307 define showtaskthreads
1309 set $kgm_taskp = (struct task *)$arg0
1310 showtaskint $kgm_taskp
1312 set $kgm_head_actp = &($kgm_taskp->threads)
1313 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1314 while $kgm_actp != $kgm_head_actp
1315 showactint $kgm_actp 0
1316 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1319 document showtaskthreads
1320 Syntax: (gdb) showtaskthreads <task>
1321 | Routine to print info about the threads in a task.
1325 define showtaskstacks
1327 set $kgm_taskp = (struct task *)$arg0
1328 showtaskint $kgm_taskp
1329 set $kgm_head_actp = &($kgm_taskp->threads)
1330 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1331 while $kgm_actp != $kgm_head_actp
1333 showactint $kgm_actp 1
1334 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1337 document showtaskstacks
1338 Syntax: (gdb) showtaskstacks <task>
1339 | Routine to print out the stack for each thread in a task.
1345 set $kgm_head_taskp = &tasks
1346 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1347 while $kgm_taskp != $kgm_head_taskp
1348 showtaskint $kgm_taskp
1349 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1352 document showalltasks
1353 Syntax: (gdb) showalltasks
1354 | Routine to print a summary listing of all the tasks
1355 | wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
1356 | if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
1357 | io_policy -> RAGE - rapid aging of vnodes requested
1358 | NORM - normal I/O explicitly requested (this is the default)
1359 | PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
1360 | THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
1363 define showprocheader
1364 printf " pid process io_policy wq_state"
1370 set $kgm_procp = (struct proc *)$arg0
1372 set $kgm_printed = 0
1373 printf "%5d ", $kgm_procp->p_pid
1375 if ($kgm_procp->p_lflag & 0x400000)
1380 if ($kgm_procp->p_iopol_disk == 1)
1382 set $kgm_printed = 1
1384 if ($kgm_procp->p_iopol_disk == 2)
1386 set $kgm_printed = 1
1388 if ($kgm_procp->p_iopol_disk == 3)
1390 set $kgm_printed = 1
1392 if ($kgm_printed == 0)
1395 set $kgm_wqp = (struct workqueue *)$kgm_procp->p_wqptr
1397 printf " %2d %2d %2d ", $kgm_wqp->wq_nthreads, $kgm_wqp->wq_thidlecount, $kgm_wqp->wq_itemcount
1401 printf " %s\n", $kgm_procp->p_comm
1411 set $kgm_head_taskp = &tasks
1412 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1413 while $kgm_taskp != $kgm_head_taskp
1414 set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info
1415 if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0))
1416 showtaskint $kgm_taskp
1417 set $kgm_taskp = $kgm_head_taskp
1419 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1424 Syntax: (gdb) showpid <pid>
1425 | Routine to print a single process by pid
1430 set $kgm_procp = (struct proc *)$arg0
1431 showtaskint $kgm_procp->task
1436 set switch_debugger=1
1440 | kdb - Switch to the inline kernel debugger
1444 | The kdb macro allows you to invoke the inline kernel debugger.
1447 define showpsetheader
1448 printf "portset waitqueue recvname "
1449 printf "flags refs recvname process\n"
1452 define showportheader
1453 printf "port mqueue recvname "
1454 printf "flags refs recvname process\n"
1457 define showportmemberheader
1458 printf "members port recvname "
1459 printf "flags refs mqueue msgcount\n"
1462 define showkmsgheader
1463 printf "messages kmsg size "
1464 printf "disp msgid remote-port local-port\n"
1468 printf " 0x%08x ", $arg0
1469 set $kgm_kmsgh = ((ipc_kmsg_t)$arg0)->ikm_header
1470 printf "0x%08x ", $kgm_kmsgh.msgh_size
1471 if (($kgm_kmsgh.msgh_bits & 0xff) == 19)
1476 if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 << 8))
1481 if ($kgm_kmsgh.msgh_bits & 0xf0000000)
1486 printf "%5d ", $kgm_kmsgh.msgh_id
1487 printf "0x%08x ", $kgm_kmsgh.msgh_remote_port
1488 printf "0x%08x\n", $kgm_kmsgh.msgh_local_port
1494 set $kgm_portp = (struct ipc_port *)$arg0
1495 showptr $kgm_portp->ip_kobject
1497 set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff)
1498 if ($kgm_kotype == 1)
1501 if ($kgm_kotype == 2)
1504 if ($kgm_kotype == 3)
1507 if ($kgm_kotype == 4)
1510 if ($kgm_kotype == 5)
1513 if ($kgm_kotype == 6)
1516 if ($kgm_kotype == 7)
1519 if ($kgm_kotype == 8)
1522 if ($kgm_kotype == 9)
1525 if ($kgm_kotype == 10)
1528 if ($kgm_kotype == 11)
1531 if ($kgm_kotype == 12)
1534 if ($kgm_kotype == 13)
1537 if ($kgm_kotype == 14)
1540 if ($kgm_kotype == 15)
1543 if ($kgm_kotype == 16)
1546 if ($kgm_kotype == 17)
1549 if ($kgm_kotype == 18)
1552 if ($kgm_kotype == 19)
1555 if ($kgm_kotype == 20)
1558 if ($kgm_kotype == 21)
1561 if ($kgm_kotype == 22)
1562 printf "IO_DONE_QUE"
1564 if ($kgm_kotype == 23)
1567 if ($kgm_kotype == 24)
1570 if ($kgm_kotype == 25)
1573 if ($kgm_kotype == 26)
1576 if ($kgm_kotype == 27)
1577 printf "IOKIT_SPARE"
1579 if ($kgm_kotype == 28)
1582 if ($kgm_kotype == 29)
1585 if ($kgm_kotype == 30)
1588 if ($kgm_kotype == 31)
1594 define showportdestproc
1595 set $kgm_portp = (struct ipc_port *)$arg0
1596 set $kgm_spacep = $kgm_portp->data.receiver
1597 # check against the previous cached value - this is slow
1598 if ($kgm_spacep != $kgm_destspacep)
1599 set $kgm_destprocp = (struct proc *)0
1600 set $kgm_head_taskp = &tasks
1601 set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next)
1602 while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp))
1603 set $kgm_destspacep = $kgm_desttaskp->itk_space
1604 if ($kgm_destspacep == $kgm_spacep)
1605 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info
1607 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->tasks.next)
1611 if $kgm_destprocp != 0
1612 printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid
1615 showptr $kgm_desttaskp
1621 set $kgm_portp = (struct ipc_port *)$arg0
1622 set $kgm_spacep = $kgm_portp->data.receiver
1623 if ($kgm_spacep == ipc_space_kernel)
1624 showkobject $kgm_portp
1626 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1627 showptr $kgm_portp->ip_messages.data.port.receiver_name
1629 showportdestproc $kgm_portp
1632 printf " inactive-port\n"
1637 define showportmember
1638 printf " 0x%08x ", $arg0
1639 set $kgm_portp = (struct ipc_port *)$arg0
1640 printf "0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
1641 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1647 printf "%5d ", $kgm_portp->ip_object.io_references
1648 printf "0x%08x ", &($kgm_portp->ip_messages)
1649 printf "0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount
1653 set $kgm_iebt = ((ipc_port_t) $arg0)->ip_callstack
1654 set $kgm_iepid = ((ipc_port_t) $arg0)->ip_spares[0]
1655 set $kgm_procpid = ((proc_t) (((task_t) $arg1)->bsd_info))->p_pid
1656 if $kgm_iebt[0] != 0
1657 showptr $kgm_iebt[0]
1658 set $kgm_iebt_loop_ctr = 1
1659 while ($kgm_iebt_loop_ctr < 16 && $kgm_iebt[$kgm_iebt_loop_ctr])
1661 showptr $kgm_iebt[$kgm_iebt_loop_ctr]
1662 set $kgm_iebt_loop_ctr = $kgm_iebt_loop_ctr + 1
1664 if $kgm_iepid != $kgm_procpid
1665 printf " (%d)", $kgm_iepid
1672 printf "0x%08x ", $arg0
1673 set $kgm_portp = (struct ipc_port *)$arg0
1674 printf "0x%08x ", &($kgm_portp->ip_messages)
1675 printf "0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
1676 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1682 printf "%5d ", $kgm_portp->ip_object.io_references
1683 set $kgm_destspacep = (struct ipc_space *)0
1684 showportdest $kgm_portp
1685 set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base
1686 if $arg1 && $kgm_kmsgp
1688 showkmsgint $kgm_kmsgp
1689 set $kgm_kmsgheadp = $kgm_kmsgp
1690 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
1691 while $kgm_kmsgp != $kgm_kmsgheadp
1692 showkmsgint $kgm_kmsgp
1693 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
1699 printf "0x%08x ", $arg0
1700 set $kgm_psetp = (struct ipc_pset *)$arg0
1701 printf "0x%08x ", &($kgm_psetp->ips_messages)
1702 printf "0x%08x ", $kgm_psetp->ips_messages.data.pset.local_name
1703 if ($kgm_psetp->ips_object.io_bits & 0x80000000)
1709 printf "%5d ", $kgm_psetp->ips_object.io_references
1710 printf "0x%08x ", $kgm_psetp->ips_messages.data.pset.local_name
1711 set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.set_queue.wqs_setlinks)
1712 set $kgm_wql = (WaitQueueLink *)$kgm_setlinksp->next
1714 while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp)
1715 set $kgm_portp = (struct ipc_port *)((int)($kgm_wql->wql_element->wqe_queue) - ((int)$kgm_portoff))
1717 set $kgm_destspacep = (struct ipc_space *)0
1718 showportdestproc $kgm_portp
1719 showportmemberheader
1722 showportmember $kgm_portp 0
1723 set $kgm_wql = (WaitQueueLink *)$kgm_wql->wql_setlinks.next
1740 define showipcobject
1741 set $kgm_object = (ipc_object_t)$arg0
1742 if ($kgm_objectp->io_bits & 0x7fff0000)
1743 showpset $kgm_objectp
1745 showport $kgm_objectp
1750 set $kgm_mqueue = *(struct ipc_mqueue *)$arg0
1751 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d1)
1752 set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages)
1753 set $kgm_pset = (((long)$arg0) - ((long)$kgm_psetoff))
1755 showpsetint $kgm_pset 1
1757 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d0)
1758 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
1759 set $kgm_port = (((long)$arg0) - ((long)$kgm_portoff))
1761 showportint $kgm_port 1
1766 set $kgm_zone = (struct zone *)$arg0
1769 printf " %6d ",$kgm_zone->count
1770 printf "%8x ",$kgm_zone->cur_size
1771 printf "%8x ",$kgm_zone->max_size
1772 printf "%6d ",$kgm_zone->elem_size
1773 printf "%8x ",$kgm_zone->alloc_size
1774 printf "%s ",$kgm_zone->zone_name
1776 if ($kgm_zone->exhaustible)
1779 if ($kgm_zone->collectable)
1782 if ($kgm_zone->expandable)
1792 printf " COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n"
1793 set $kgm_zone_ptr = (struct zone *)first_zone
1794 while ($kgm_zone_ptr != 0)
1795 zprint_one $kgm_zone_ptr
1796 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
1801 Syntax: (gdb) zprint
1802 | Routine to print a summary listing of all the kernel zones
1806 set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0
1808 if ($kgm_mtxgrp->lck_grp_mtxcnt)
1810 printf " %8d ",$kgm_mtxgrp->lck_grp_mtxcnt
1811 printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
1812 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
1813 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
1814 printf "%s ",&$kgm_mtxgrp->lck_grp_name
1823 printf " CNT UTIL MISS WAIT NAME\n"
1824 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1825 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
1826 while ($kgm_mtxgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
1827 showmtxgrp $kgm_mtxgrp_ptr
1828 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
1833 Syntax: (gdb) showallmtx
1834 | Routine to print a summary listing of all mutexes
1838 set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0
1840 if ($kgm_rwlckgrp->lck_grp_rwcnt)
1841 showptr $kgm_rwlckgrp
1842 printf " %8d ",$kgm_rwlckgrp->lck_grp_rwcnt
1843 printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
1844 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
1845 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
1846 printf "%s ",&$kgm_rwlckgrp->lck_grp_name
1855 printf " CNT UTIL MISS WAIT NAME\n"
1856 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1857 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1858 while ($kgm_rwlckgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
1859 showrwlckgrp $kgm_rwlckgrp_ptr
1860 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1864 document showallrwlck
1865 Syntax: (gdb) showallrwlck
1866 | Routine to print a summary listing of all read/writer locks
1869 set $kdp_act_counter = 0
1888 define showcontext_int
1889 echo Context switched, current instruction pointer:
1895 set $newact = (struct thread *) $arg0
1897 if ($newact->kernel_stack == 0)
1898 echo This activation does not have a stack.\n
1900 output/a (unsigned) $newact.continuation
1903 if ($kgm_mtype == $kgm_mtype_ppc)
1904 if ($kdp_act_counter == 0)
1905 set $kdpstate = (struct savearea *) kdp.saved_state
1907 set $kdp_act_counter = $kdp_act_counter + 1
1908 set (struct savearea *) kdp.saved_state=$newact->machine->pcb
1911 set $pc=$newact->machine->pcb.save_srr0
1914 if ($kgm_mtype == $kgm_mtype_i386)
1915 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
1916 if ($kdp_act_counter == 0)
1917 set $kdpstate = *($kdpstatep)
1919 set $kdp_act_counter = $kdp_act_counter + 1
1921 set $kgm_statep = (struct x86_kernel_state *) \
1922 ($newact->kernel_stack + kernel_stack_size \
1923 - sizeof(struct x86_kernel_state))
1924 set $kdpstatep->ebx = $kgm_statep->k_ebx
1925 set $kdpstatep->ebp = $kgm_statep->k_ebp
1926 set $kdpstatep->edi = $kgm_statep->k_edi
1927 set $kdpstatep->esi = $kgm_statep->k_esi
1928 set $kdpstatep->eip = $kgm_statep->k_eip
1931 set $pc = $kgm_statep->k_eip
1934 if ($kgm_mtype == $kgm_mtype_x86_64)
1935 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
1936 if ($kdp_act_counter == 0)
1937 set $kdpstate = *($kdpstatep)
1939 set $kdp_act_counter = $kdp_act_counter + 1
1941 set $kgm_statep = (struct x86_kernel_state *) \
1942 ($newact->kernel_stack + kernel_stack_size \
1943 - sizeof(struct x86_kernel_state))
1944 set $kdpstatep->rbx = $kgm_statep->k_rbx
1945 set $kdpstatep->rbp = $kgm_statep->k_rbp
1946 set $kdpstatep->r12 = $kgm_statep->k_r12
1947 set $kdpstatep->r13 = $kgm_statep->k_r13
1948 set $kdpstatep->r14 = $kgm_statep->k_r14
1949 set $kdpstatep->r15 = $kgm_statep->k_r15
1950 set $kdpstatep->isf.rsp = $kgm_statep->k_rsp
1953 set $pc = $kgm_statep->k_rip
1956 if ($kgm_mtype == $kgm_mtype_arm)
1967 set $r10_save = $r10
1968 set $r11_save = $r11
1969 set $r12_save = $r12
1973 set $pc_ctx = load_reg+8
1974 set $kgm_statep = (struct arm_saved_state *)((struct thread*)$arg0)->machine.kstackptr
1975 set $r0 = $kgm_statep->r[0]
1976 set $r1 = $kgm_statep->r[1]
1977 set $r2 = $kgm_statep->r[2]
1978 set $r3 = $kgm_statep->r[3]
1979 set $r4 = $kgm_statep->r[4]
1980 set $r5 = $kgm_statep->r[5]
1981 set $r6 = $kgm_statep->r[6]
1982 set $r8 = $kgm_statep->r[8]
1983 set $r9 = $kgm_statep->r[9]
1984 set $r10 = $kgm_statep->r[10]
1985 set $r11 = $kgm_statep->r[11]
1986 set $r12 = $kgm_statep->r[12]
1987 set $sp = $kgm_statep->sp
1988 set $lr = $kgm_statep->lr
1990 set $r7 = $kgm_statep->r[7]
1998 document switchtoact
1999 Syntax: switchtoact <address of activation>
2000 | This command allows gdb to examine the execution context and call
2001 | stack for the specified activation. For example, to view the backtrace
2002 | for an activation issue "switchtoact <address>", followed by "bt".
2003 | Before resuming execution, issue a "resetctx" command, to
2004 | return to the original execution context.
2009 if ($kgm_mtype == $kgm_mtype_ppc)
2010 if ($kdp_act_counter == 0)
2011 set $kdpstate = (struct savearea *) kdp.saved_state
2013 set $kdp_act_counter = $kdp_act_counter + 1
2014 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0
2017 set $pc=((struct savearea *) $arg0)->save_srr0
2020 if ($kgm_mtype == $kgm_mtype_arm)
2021 set arm disassembler std
2033 set $r10_save = $r10
2034 set $r11_save = $r11
2035 set $r12_save = $r12
2039 set $kgm_statep = (struct arm_saved_state *)$arg0
2040 set $r0 = $kgm_statep->r[0]
2041 set $r1 = $kgm_statep->r[1]
2042 set $r2 = $kgm_statep->r[2]
2043 set $r3 = $kgm_statep->r[3]
2044 set $r4 = $kgm_statep->r[4]
2045 set $r5 = $kgm_statep->r[5]
2046 set $r6 = $kgm_statep->r[6]
2047 set $r8 = $kgm_statep->r[8]
2048 set $r9 = $kgm_statep->r[9]
2049 set $r10 = $kgm_statep->r[10]
2050 set $r11 = $kgm_statep->r[11]
2051 set $r12 = $kgm_statep->r[12]
2052 set $sp = $kgm_statep->sp
2053 set $lr = $kgm_statep->lr
2054 set $r7 = $kgm_statep->r[7]
2055 set $pc = $kgm_statep->pc
2060 echo switchtoctx not implemented for this architecture.\n
2064 document switchtoctx
2065 Syntax: switchtoctx <address of pcb>
2066 | This command allows gdb to examine an execution context and dump the
2067 | backtrace for this execution context.
2068 | Before resuming execution, issue a "resetctx" command, to
2069 | return to the original execution context.
2074 if ($kdp_act_counter != 0)
2075 if ($kgm_mtype == $kgm_mtype_ppc)
2076 set (struct savearea *)kdp.saved_state=$kdpstate
2079 set $pc=((struct savearea *) kdp.saved_state)->save_srr0
2081 set $kdp_act_counter = 0
2083 if ($kgm_mtype == $kgm_mtype_i386)
2084 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
2085 set *($kdpstatep)=$kdpstate
2088 set $pc=$kdpstatep->eip
2090 set $kdp_act_counter = 0
2092 if ($kgm_mtype == $kgm_mtype_x86_64)
2093 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
2094 set *($kdpstatep)=$kdpstate
2097 set $pc=$kdpstatep->isf.rip
2099 set $kdp_act_counter = 0
2101 if ($kgm_mtype == $kgm_mtype_arm)
2120 set $r10 = $r10_save
2122 set $r11 = $r11_save
2124 set $r12 = $r12_save
2141 | Returns to the original execution context. This command should be
2142 | issued if you wish to resume execution after using the "switchtoact"
2143 | or "switchtoctx" commands.
2146 # This is a pre-hook for the continue command, to prevent inadvertent attempts
2147 # to resume from the context switched to for examination.
2148 define hook-continue
2152 # This is a pre-hook for the detach command, to prevent inadvertent attempts
2153 # to resume from the context switched to for examination.
2159 set $resume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_RESUME
2165 | The target system will resume when detaching or exiting from gdb.
2166 | This is the default behavior.
2170 set $noresume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_NORESUME
2171 dumpinfoint $noresume
2175 | Syntax: resume_off
2176 | The target system won't resume after detaching from gdb and
2177 | can be attached with a new gdb session
2181 set $kgm_panic_bufptr = debug_buf
2182 set $kgm_panic_bufptr_max = debug_buf_ptr
2183 while $kgm_panic_bufptr < $kgm_panic_bufptr_max
2184 if *(char *)$kgm_panic_bufptr == 10
2187 printf "%c", *(char *)$kgm_panic_bufptr
2189 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1
2195 | Display the panic log information
2199 define dumpcallqueue
2200 set $kgm_callhead = $arg0
2201 set $kgm_callentry = $kgm_callhead->next
2203 while $kgm_callentry != $kgm_callhead
2204 set $kgm_call = (struct call_entry *)$kgm_callentry
2205 printf "0x%08x ", $kgm_call
2206 printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1
2207 output $kgm_call->deadline
2209 output $kgm_call->func
2211 set $kgm_i = $kgm_i + 1
2212 set $kgm_callentry = $kgm_callentry->next
2214 printf "%d entries\n", $kgm_i
2217 document dumpcallqueue
2218 | Syntax: dumpcallqueue <queue head>
2219 | Displays the contents of the specified call_entry queue.
2223 showtaskthreads $arg0
2225 document showtaskacts
2226 | See help showtaskthreads.
2232 document showallacts
2233 | See help showallthreads.
2248 document resetstacks
2249 | Syntax: resetstacks
2250 | Internal kgmacro routine used by the "showuserstack" macro
2251 | to reset the target pmap to the kernel pmap.
2254 #Barely effective hacks to work around bugs in the "flush" and "update"
2255 #gdb commands in Tiger (up to 219); these aren't necessary with Panther
2256 #gdb, but do no harm.
2257 define _kgm_flush_loop
2258 set $kgm_flush_loop_ctr = 0
2259 while ($kgm_flush_loop_ctr < 30)
2262 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1
2266 define _kgm_update_loop
2267 set $kgm_update_loop_ctr = 0
2268 while ($kgm_update_loop_ctr < 30)
2270 set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1
2273 # Internal routine used by "_loadfrom" to read from 64-bit addresses
2276 # set up the manual KDP packet
2277 set manual_pkt.input = 0
2278 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
2279 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
2280 set $kgm_pkt->hdr.request = KDP_READMEM64
2281 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
2282 set $kgm_pkt->hdr.is_reply = 0
2283 set $kgm_pkt->hdr.seq = 0
2284 set $kgm_pkt->hdr.key = 0
2285 set $kgm_pkt->address = (uint64_t)$arg0
2286 set $kgm_pkt->nbytes = sizeof(uint64_t)
2287 set manual_pkt.input = 1
2288 # dummy to make sure manual packet is executed
2289 set $kgm_dummy = &_mh_execute_header
2290 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
2291 if ($kgm_pkt->error == 0)
2292 set $kgm_k32read64 = *(uint64_t *)$kgm_pkt->data
2294 set $kgm_k32read64 = 0
2298 # Internal routine used by "showx86backtrace" to abstract possible loads from
2302 set $kgm_loadval = *(uintptr_t *)$arg0
2304 if ($kgm_x86_abi == 0xe)
2305 set $kgm_loadval = *(uint32_t *)$arg0
2307 if ($kgm_x86_abi == 0xf)
2308 if ($kgm_mtype == $kgm_mtype_i386)
2310 set $kgm_loadval = $kgm_k32read64
2312 set $kgm_loadval = *(uint64_t *)$arg0
2320 #This is necessary since gdb often doesn't do backtraces on x86 correctly
2321 #in the absence of symbols.The code below in showuserstack and
2322 #showx86backtrace also contains several workarouds for the gdb bug where
2323 #gdb stops macro evaluation because of spurious "Cannot read memory"
2324 #errors on x86. These errors appear on ppc as well, but they don't
2325 #always stop macro evaluation.
2327 set $kgm_cur_frame = 0
2329 set $kgm_x86_abi = 0
2330 define showx86backtrace
2331 if ($kgm_mtype == $kgm_mtype_i386)
2332 set $kgm_frame_reg = $ebp
2334 set $kgm_ret_off = 4
2336 if ($kgm_mtype == $kgm_mtype_x86_64)
2337 set $kgm_frame_reg = $rbp
2339 set $kgm_ret_off = 8
2342 if ($kgm_x86_abi == 0xe)
2343 set $kgm_ret_off = 4
2345 if ($kgm_x86_abi == 0xf)
2346 set $kgm_ret_off = 8
2349 if ($kgm_cur_frame == 0)
2350 set $kgm_cur_frame = $kgm_frame_reg
2352 if ($kgm_cur_pc == 0)
2353 set $kgm_cur_pc = $kgm_pc
2355 printf "0: Frame: 0x%016llx PC: 0x%016llx\n", $kgm_cur_frame, $kgm_cur_pc
2356 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
2359 set $kgm_tmp_frame = $kgm_cur_frame
2360 set $kgm_cur_frame = 0
2362 _loadfrom ($kgm_tmp_frame)
2363 set $kgm_prev_frame = $kgm_loadval
2364 _loadfrom ($kgm_tmp_frame+$kgm_ret_off)
2365 set $kgm_prev_pc = $kgm_loadval
2366 set $kgm_frameno = 1
2367 while $kgm_prev_frame != 0
2368 printf "%d: Saved frame: 0x%016llx Saved PC: 0x%016llx\n", $kgm_frameno, $kgm_prev_frame, $kgm_prev_pc
2369 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
2372 _loadfrom ($kgm_prev_frame+$kgm_ret_off)
2373 set $kgm_prev_pc = $kgm_loadval
2374 _loadfrom ($kgm_prev_frame)
2375 set $kgm_prev_frame = $kgm_loadval
2376 set $kgm_frameno = $kgm_frameno + 1
2379 set $kgm_x86_abi = 0
2382 define showx86backtrace2
2383 set $kgm_cur_frame = $arg0
2384 set $kgm_cur_pc = $arg1
2388 define showuserstack
2390 if ($kgm_mtype == $kgm_mtype_ppc)
2391 if ($kdp_act_counter == 0)
2392 set $kdpstate = (struct savearea *) kdp.saved_state
2394 set $kdp_act_counter = $kdp_act_counter + 1
2395 set $newact = (struct thread *) $arg0
2397 set $checkpc = $newact->machine->upcb.save_srr0
2399 echo This activation does not appear to have
2400 echo \20 a valid user context.\n
2402 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
2404 #flush and update seem to be executed lazily by gdb on Tiger, hence the
2405 #repeated invocations - see 3743135
2407 # This works because the new pmap is used only for reads
2408 set kdp_pmap = $newact->task->map->pmap
2420 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
2421 set $newact = (struct thread *) $arg0
2422 set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
2423 set $kgm_x86_abi = $newiss.flavor
2424 if ($newiss.flavor == 0xf)
2425 set $checkpc = $newiss.uss.ss_64.isf.rip
2426 set $checkframe = $newiss.uss.ss_64.rbp
2429 set $checkpc = $newiss.uss.ss_32.eip
2430 set $checkframe = $newiss.uss.ss_32.ebp
2434 echo This activation does not appear to have
2435 echo \20 a valid user context.\n
2437 set $kgm_cur_frame = $checkframe
2438 set $kgm_cur_pc = $checkpc
2439 printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread ("
2441 printf "); you can also examine memory locations in this address space (pmap "
2442 showptr $newact->task->map->pmap
2443 printf ") 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"
2444 set kdp_pmap = $newact->task->map->pmap
2449 echo showuserstack not supported on this architecture\n
2453 document showuserstack
2454 Syntax: showuserstack <address of thread activation>
2455 |This command displays a numeric backtrace for the user space stack of
2456 |the given thread activation. It may, of course, fail to display a
2457 |complete backtrace if portions of the user stack are not mapped in.
2458 |Symbolic backtraces can be obtained either by running gdb on the
2459 |user space binary, or a tool such as "symbolicate".
2460 |Note that while this command works on Panther's gdb, an issue
2461 |with Tiger gdb (3743135) appears to hamper the evaluation of this
2462 |macro in some cases.
2466 # Alternatively, set *(*(unsigned **) 0x2498) = 1
2467 # (or 0x5498 on PPC, 0xffffff8000002928 on x86_64, 0xffff049c on arm)
2468 manualhdrint $kgm_kdp_pkt_hostreboot
2474 |Reboot the remote target machine; not guaranteed to succeed.
2477 define kdpversionint
2478 # set up the manual KDP packet
2479 set manual_pkt.input = 0
2480 set manual_pkt.len = sizeof(kdp_version_req_t)
2481 set $kgm_pkt = (kdp_version_req_t *)&manual_pkt.data
2482 set $kgm_pkt->hdr.request = KDP_VERSION
2483 set $kgm_pkt->hdr.len = sizeof(kdp_version_req_t)
2484 set $kgm_pkt->hdr.is_reply = 0
2485 set $kgm_pkt->hdr.seq = 0
2486 set $kgm_pkt->hdr.key = 0
2487 set manual_pkt.input = 1
2488 # dummy to make sure manual packet is executed
2489 set $kgm_dummy = &_mh_execute_header
2490 set $kgm_pkt = (kdp_version_reply_t *)&manual_pkt.data
2491 set $kgm_kdp_version = $kgm_pkt->version
2492 set $kgm_kdp_feature = $kgm_pkt->feature
2497 printf "KDP VERSION = %d, FEATURE = 0x%x\n", $kgm_kdp_version, $kgm_kdp_feature
2500 document kdp-version
2502 |Get the KDP protocol version being used by the kernel.
2506 # set up the manual KDP packet
2507 set manual_pkt.input = 0
2509 set manual_pkt.len = sizeof(kdp_dumpinfo_req_t)
2510 set $kgm_pkt = (kdp_dumpinfo_req_t *)manual_pkt.data
2511 set $kgm_pkt->hdr.request = KDP_DUMPINFO
2512 set $kgm_pkt->hdr.len = sizeof(kdp_dumpinfo_req_t)
2513 set $kgm_pkt->hdr.is_reply = 0
2514 set $kgm_pkt->hdr.seq = 0
2515 set $kgm_pkt->hdr.key = 0
2516 set $kgm_pkt->type = $arg0
2517 set $kgm_pkt->name = ""
2518 set $kgm_pkt->destip = ""
2519 set $kgm_pkt->routerip = ""
2520 set $kgm_pkt->port = 0
2523 set $kgm_pkt->name = "$arg1"
2526 set $kgm_pkt->destip = "$arg2"
2529 set $kgm_pkt->routerip = "$arg3"
2532 set $kgm_pkt->port = $arg4
2535 set manual_pkt.input = 1
2536 # dummy to make sure manual packet is executed
2537 set $kgm_dummy = &_mh_execute_header
2542 dumpinfoint KDP_DUMPINFO_CORE $arg1 $arg0
2544 dumpinfoint KDP_DUMPINFO_CORE \0 $arg0
2549 Syntax: sendcore <IP address> [filename]
2550 |Configure the kernel to transmit a kernel coredump to a server (kdumpd)
2551 |at the specified IP address. This is useful when the remote target has
2552 |not been previously configured to transmit coredumps, and you wish to
2553 |preserve kernel state for later examination. NOTE: You must issue a "continue"
2554 |command after using this macro to trigger the kernel coredump. The kernel
2555 |will resume waiting in the debugger after completion of the coredump. You
2556 |may disable coredumps by executing the "disablecore" macro. You can
2557 |optionally specify the filename to be used for the generated core file.
2562 dumpinfoint KDP_DUMPINFO_SYSTEMLOG $arg1 $arg0
2564 dumpinfoint KDP_DUMPINFO_SYSTEMLOG \0 $arg0
2569 Syntax: sendsyslog <IP address> [filename]
2570 |Configure the kernel to transmit a kernel system log to a server (kdumpd)
2571 |at the specified IP address. NOTE: You must issue a "continue"
2572 |command after using this macro to trigger the kernel system log. The kernel
2573 |will resume waiting in the debugger after completion. You can optionally
2574 |specify the name to be used for the generated system log.
2580 dumpinfoint KDP_DUMPINFO_PANICLOG $arg1 $arg0
2582 dumpinfoint KDP_DUMPINFO_PANICLOG \0 $arg0
2585 printf "No panic log available.\n"
2589 document sendpaniclog
2590 Syntax: sendpaniclog <IP address> [filename]
2591 |Configure the kernel to transmit a kernel paniclog to a server (kdumpd)
2592 |at the specified IP address. NOTE: You must issue a "continue"
2593 |command after using this macro to trigger the kernel panic log. The kernel
2594 |will resume waiting in the debugger after completion. You can optionally
2595 |specify the name to be used for the generated panic log.
2599 dumpinfoint KDP_DUMPINFO_GETINFO
2600 set $kgm_dumpinfo = (kdp_dumpinfo_reply_t *) manual_pkt.data
2601 if $kgm_dumpinfo->type & KDP_DUMPINFO_REBOOT
2602 printf "System will reboot after kernel info gets dumped.\n"
2604 printf "Sysem will not reboot after kernel info gets dumped.\n"
2606 if $kgm_dumpinfo->type & KDP_DUMPINFO_NORESUME
2607 printf "System will allow a re-attach after a KDP disconnect.\n"
2609 printf "System will resume after a KDP disconnect.\n"
2611 set $kgm_dumpinfo_type = $kgm_dumpinfo->type & KDP_DUMPINFO_MASK
2612 if $kgm_dumpinfo_type == KDP_DUMPINFO_DISABLE
2613 printf "Kernel not setup for remote dumps.\n"
2615 printf "Remote dump type: "
2616 if $kgm_dumpinfo_type == KDP_DUMPINFO_CORE
2617 printf "Core file\n"
2619 if $kgm_dumpinfo_type == KDP_DUMPINFO_PANICLOG
2620 printf "Panic log\n"
2622 if $kgm_dumpinfo_type == KDP_DUMPINFO_SYSTEMLOG
2623 printf "System log\n"
2627 if $kgm_dumpinfo->name[0] == '\0'
2628 printf "(autogenerated)\n"
2630 printf "%s\n", $kgm_dumpinfo->name
2633 printf "Network Info: %s[%d] ", $kgm_dumpinfo->destip, $kgm_dumpinfo->port
2634 if $kgm_dumpinfo->routerip[0] == '\0'
2637 printf "Router: %s\n", $kgm_dumpinfo->routerip
2642 document getdumpinfo
2644 |Retrieve the current remote dump settings.
2648 dumpinfoint KDP_DUMPINFO_SETINFO $arg0 $arg1 $arg2 $arg3
2651 document setdumpinfo
2652 Syntax: setdumpinfo <filename> <ip> <router> <port>
2653 |Configure the current remote dump settings. Specify \0 if you
2654 |want to use the defaults (filename) or previously configured
2655 |settings (ip/router). Specify 0 for the port if you wish to
2656 |use the previously configured/default setting for that.
2660 dumpinfoint KDP_DUMPINFO_DISABLE
2663 document disablecore
2665 |Reconfigures the kernel so that it no longer transmits kernel coredumps. This
2666 |complements the "sendcore" macro, but it may be used if the kernel has been
2667 |configured to transmit coredumps through boot-args as well.
2670 define switchtocorethread
2671 set $newact = (struct thread *) $arg0
2673 if ($newact->kernel_stack == 0)
2674 echo This thread does not have a stack.\n
2676 output/a (unsigned) $newact.continuation
2679 if ($kgm_mtype == $kgm_mtype_ppc)
2680 loadcontext $newact->machine->pcb
2682 set $pc = $newact->machine->pcb.save_srr0
2684 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
2685 set $kgm_cstatep = (struct x86_kernel_state *) \
2686 ($newact->kernel_stack + kernel_stack_size \
2687 - sizeof(struct x86_kernel_state))
2688 loadcontext $kgm_cstatep
2691 echo switchtocorethread not supported on this architecture\n
2698 document switchtocorethread
2699 Syntax: switchtocorethread <address of activation>
2700 | The corefile equivalent of "switchtoact". When debugging a kernel coredump
2701 | file, this command can be used to examine the execution context and stack
2702 | trace for a given thread activation. For example, to view the backtrace
2703 | for a thread issue "switchtocorethread <address>", followed by "bt".
2704 | Before resuming execution, issue a "resetcorectx" command, to
2705 | return to the original execution context. Note that this command
2706 | requires gdb support, as documented in Radar 3401283.
2711 if ($kgm_mtype == $kgm_mtype_ppc)
2712 set $kgm_contextp = (struct savearea *) $arg0
2713 set $pc = $kgm_contextp.save_srr0
2714 set $r1 = $kgm_contextp.save_r1
2715 set $lr = $kgm_contextp.save_lr
2717 set $r2 = $kgm_contextp.save_r2
2718 set $r3 = $kgm_contextp.save_r3
2719 set $r4 = $kgm_contextp.save_r4
2720 set $r5 = $kgm_contextp.save_r5
2721 set $r6 = $kgm_contextp.save_r6
2722 set $r7 = $kgm_contextp.save_r7
2723 set $r8 = $kgm_contextp.save_r8
2724 set $r9 = $kgm_contextp.save_r9
2725 set $r10 = $kgm_contextp.save_r10
2726 set $r11 = $kgm_contextp.save_r11
2727 set $r12 = $kgm_contextp.save_r12
2728 set $r13 = $kgm_contextp.save_r13
2729 set $r14 = $kgm_contextp.save_r14
2730 set $r15 = $kgm_contextp.save_r15
2731 set $r16 = $kgm_contextp.save_r16
2732 set $r17 = $kgm_contextp.save_r17
2733 set $r18 = $kgm_contextp.save_r18
2734 set $r19 = $kgm_contextp.save_r19
2735 set $r20 = $kgm_contextp.save_r20
2736 set $r21 = $kgm_contextp.save_r21
2737 set $r22 = $kgm_contextp.save_r22
2738 set $r23 = $kgm_contextp.save_r23
2739 set $r24 = $kgm_contextp.save_r24
2740 set $r25 = $kgm_contextp.save_r25
2741 set $r26 = $kgm_contextp.save_r26
2742 set $r27 = $kgm_contextp.save_r27
2743 set $r28 = $kgm_contextp.save_r28
2744 set $r29 = $kgm_contextp.save_r29
2745 set $r30 = $kgm_contextp.save_r30
2746 set $r31 = $kgm_contextp.save_r31
2748 set $cr = $kgm_contextp.save_cr
2749 set $ctr = $kgm_contextp.save_ctr
2751 if ($kgm_mtype == $kgm_mtype_i386)
2752 set $kgm_contextp = (struct x86_kernel_state *) $arg0
2753 set $ebx = $kgm_contextp->k_ebx
2754 set $ebp = $kgm_contextp->k_ebp
2755 set $edi = $kgm_contextp->k_edi
2756 set $esi = $kgm_contextp->k_esi
2757 set $eip = $kgm_contextp->k_eip
2758 set $pc = $kgm_contextp->k_eip
2760 if ($kgm_mtype == $kgm_mtype_x86_64)
2761 set $kgm_contextp = (struct x86_kernel_state *) $arg0
2762 set $rbx = $kgm_contextp->k_rbx
2763 set $rbp = $kgm_contextp->k_rbp
2764 set $r12 = $kgm_contextp->k_r12
2765 set $r13 = $kgm_contextp->k_r13
2766 set $r14 = $kgm_contextp->k_r14
2767 set $r15 = $kgm_contextp->k_r15
2768 set $rip = $kgm_contextp->k_rip
2769 set $pc = $kgm_contextp->k_rip
2771 echo loadcontext not supported on this architecture\n
2779 if ($kgm_mtype == $kgm_mtype_ppc)
2780 set $kgm_corecontext = (struct savearea *) kdp.saved_state
2781 loadcontext $kgm_corecontext
2783 if ($kgm_mtype == $kgm_mtype_i386)
2784 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
2785 set $ebx = $kdpstatep->ebx
2786 set $ebp = $kdpstatep->ebp
2787 set $edi = $kdpstatep->edi
2788 set $esi = $kdpstatep->esi
2789 set $eip = $kdpstatep->eip
2790 set $eax = $kdpstatep->eax
2791 set $ecx = $kdpstatep->ecx
2792 set $edx = $kdpstatep->edx
2795 set $pc = $kdpstatep->eip
2798 echo resetcorectx not supported on this architecture\n
2804 document resetcorectx
2805 Syntax: resetcorectx
2806 | The corefile equivalent of "resetctx". Returns to the original
2807 | execution context (that of the active thread at the time of the NMI or
2808 | panic). This command should be issued if you wish to resume
2809 | execution after using the "switchtocorethread" command.
2812 #Helper function for "showallgdbstacks"
2814 define showgdbthread
2815 printf " 0x%08x ", $arg0
2816 set $kgm_thread = *(struct thread *)$arg0
2817 printf "0x%08x ", $arg0
2818 printf "%3d ", $kgm_thread.sched_pri
2819 set $kgm_state = $kgm_thread.state
2820 if $kgm_state & 0x80
2823 if $kgm_state & 0x40
2826 if $kgm_state & 0x20
2829 if $kgm_state & 0x10
2832 if $kgm_state & 0x08
2835 if $kgm_state & 0x04
2838 if $kgm_state & 0x02
2841 if $kgm_state & 0x01
2843 printf "0x%08x ", $kgm_thread.wait_queue
2844 output /a (unsigned) $kgm_thread.wait_event
2845 if ($kgm_thread.uthread != 0)
2846 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
2847 if ($kgm_uthread->uu_wmesg != 0)
2848 printf " \"%s\"", $kgm_uthread->uu_wmesg
2853 if ($kgm_thread.kernel_stack != 0)
2854 if ($kgm_thread.reserved_stack != 0)
2855 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack
2857 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack
2858 if ($kgm_mtype == $kgm_mtype_ppc)
2859 set $mysp = $kgm_thread.machine.pcb->save_r1
2861 if ($kgm_mtype == $kgm_mtype_i386)
2862 set $kgm_statep = (struct x86_kernel_state *) \
2863 ($kgm_thread->kernel_stack + kernel_stack_size \
2864 - sizeof(struct x86_kernel_state))
2865 set $mysp = $kgm_statep->k_ebp
2867 if ($kgm_mtype == $kgm_mtype_arm)
2868 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
2869 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
2872 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
2873 set $mysp = $kgm_statep->r[7]
2877 printf "\n\t\tstacktop=0x%08x", $mysp
2881 switchtocorethread $arg0
2885 printf "\n\t\t\tcontinuation="
2886 output /a (unsigned) $kgm_thread.continuation
2894 #Use of this macro is currently (8/04) blocked by the fact that gdb
2895 #stops evaluating macros when encountering an error, such as a failure
2896 #to read memory from a certain location. Until this issue (described in
2897 #3758949) is addressed, evaluation of this macro may stop upon
2898 #encountering such an error.
2900 define showallgdbstacks
2901 set $kgm_head_taskp = &tasks
2902 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
2903 while $kgm_taskp != $kgm_head_taskp
2905 showtaskint $kgm_taskp
2906 set $kgm_head_actp = &($kgm_taskp->threads)
2907 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
2908 while $kgm_actp != $kgm_head_actp
2910 showgdbthread $kgm_actp 1 0
2911 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
2914 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
2919 document showallgdbstacks
2920 Syntax: showallgdbstacks
2921 | An alternative to "showallstacks". Iterates through the task list and
2922 | displays a gdb generated backtrace for each kernel thread. It is
2923 | advantageous in that it is much faster than "showallstacks", and
2924 | decodes function call arguments and displays source level traces, but
2925 | it has the drawback that it doesn't determine if frames belong to
2926 | functions from kernel extensions, as with "showallstacks".
2927 | This command may terminate prematurely because of a gdb bug
2928 | (Radar 3758949), which stops macro evaluation on memory read
2932 define showallgdbcorestacks
2934 set $kgm_head_taskp = &tasks
2935 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
2936 while $kgm_taskp != $kgm_head_taskp
2938 showtaskint $kgm_taskp
2939 set $kgm_head_actp = &($kgm_taskp->threads)
2940 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
2941 while $kgm_actp != $kgm_head_actp
2943 showgdbthread $kgm_actp 1 1
2944 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
2947 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
2953 document showallgdbcorestacks
2954 Syntax: showallgdbcorestacks
2955 |Corefile version of "showallgdbstacks"
2959 define switchtouserthread
2961 if ($kgm_mtype == $kgm_mtype_ppc)
2962 if ($kdp_act_counter == 0)
2963 set $kdpstate = (struct savearea *) kdp.saved_state
2965 set $kdp_act_counter = $kdp_act_counter + 1
2966 set $newact = (struct thread *) $arg0
2968 set $checkpc = $newact->machine->upcb.save_srr0
2970 echo This activation does not appear to have
2971 echo \20 a valid user context.\n
2973 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
2975 #flush and update seem to be executed lazily by gdb on Tiger, hence the
2976 #repeated invocations - see 3743135
2978 # This works because the new pmap is used only for reads
2979 set kdp_pmap = $newact->task->map->pmap
2984 echo switchtouserthread not implemented for this architecture.\n
2988 document switchtouserthread
2989 Syntax: switchtouserthread <address of thread>
2990 | Analogous to switchtoact, but switches to the user context of a
2991 | specified thread address. Similar to the "showuserstack"
2992 | command, but this command does not return gdb to the kernel context
2993 | immediately. This is to assist with the following (rather risky)
2994 | manoeuvre - upon switching to the user context and virtual address
2995 | space, the user may choose to call remove-symbol-file on the
2996 | mach_kernel symbol file, and then add-symbol-file on the user space
2997 | binary's symfile. gdb can then generate symbolic backtraces
2998 | for the user space thread. To return to the
2999 | kernel context and virtual address space, the process must be
3000 | reversed, i.e. call remove-symbol-file on the user space symbols, and
3001 | then add-symbol-file on the appropriate mach_kernel, and issue the
3002 | "resetstacks" command. Note that gdb may not react kindly to all these
3003 | symbol file switches. The same restrictions that apply to "showuserstack"
3004 | apply here - pages that have been paged out cannot be read while in the
3005 | debugger context, so backtraces may terminate early.
3006 | If the virtual addresses in the stack trace do not conflict with those
3007 | of symbols in the kernel's address space, it may be sufficient to
3008 | just do an add-symbol-file on the user space binary's symbol file.
3009 | Note that while this command works on Panther's gdb, an issue
3010 | with Tiger gdb (3743135) appears to hamper the evaluation of this
3011 | macro in some cases.
3014 define showmetaclass
3015 set $kgm_metaclassp = (OSMetaClass *)$arg0
3016 printf "%-5d", $kgm_metaclassp->instanceCount
3017 printf "x %5d bytes", $kgm_metaclassp->classSize
3018 printf " %s\n", $kgm_metaclassp->className->string
3022 printf "\"%s\"", ((OSString *)$arg0)->string
3026 printf "%lld", ((OSNumber *)$arg0)->value
3030 if ($arg0 == gOSBooleanFalse)
3037 define showdatabytes
3038 set $kgm_data = (OSData *)$arg0
3041 set $kgm_datap = (const unsigned char *) $kgm_data->data
3043 while ( $kgm_idx < $kgm_data->length )
3044 printf "%02X", *$kgm_datap
3045 set $kgm_datap = $kgm_datap + 1
3046 set $kgm_idx = $kgm_idx + 1
3052 set $kgm_data = (OSData *)$arg0
3055 set $kgm_datap = (const unsigned char *) $kgm_data->data
3057 set $kgm_printstr = 0
3058 if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3))
3059 set $kgm_bytes = *(unsigned int *) $kgm_datap
3060 if (0xffff0000 & $kgm_bytes)
3062 set $kgm_printstr = 1
3063 while ($kgm_idx++ < 4)
3064 set $kgm_bytes = $kgm_bytes >> 8
3065 set $kgm_char = 0xff & $kgm_bytes
3066 if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e)))
3067 set $kgm_printstr = 0
3076 while ($kgm_idx < $kgm_data->length)
3077 set $kgm_char = $kgm_datap[$kgm_idx++]
3079 if (0 == $kgm_quoted)
3087 printf "%c", $kgm_char
3099 if (0 == (3 & (unsigned int)$kgm_datap))
3100 while (($kgm_idx + 3) <= $kgm_data->length)
3101 printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx]
3102 set $kgm_idx = $kgm_idx + 4
3105 while ($kgm_idx < $kgm_data->length)
3106 printf "%02x", $kgm_datap[$kgm_idx++]
3112 define showdictionaryint
3113 set $kgm$arg0_dict = (OSDictionary *)$arg1
3116 set $kgm$arg0_idx = 0
3117 while ($kgm$arg0_idx < $kgm$arg0_dict->count)
3118 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key
3119 showobjectint _$arg0 $kgm_obj
3121 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value
3122 showobjectint _$arg0 $kgm_obj
3123 if ($kgm$arg0_idx < $kgm$arg0_dict->count)
3132 while ($kgm_idx < $arg0)
3133 if ($arg1 & (1 << $kgm_idx++))
3141 define showregdictionary
3142 indent $kgm_reg_depth+2 $arg1
3145 set $kgm_reg_idx = 0
3146 while ($kgm_reg_idx < $arg0->count)
3147 indent $kgm_reg_depth+2 $arg1
3149 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key
3150 showobjectint _ $kgm_obj
3153 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value
3154 showobjectint _ $kgm_obj
3157 indent $kgm_reg_depth+2 $arg1
3162 define showarraysetint
3163 set $kgm$arg0_array = (OSArray *)$arg1
3165 set $kgm$arg0_idx = 0
3166 while ($kgm$arg0_idx < $kgm$arg0_array->count)
3167 set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++]
3168 showobjectint _$arg0 $kgm_obj
3169 if ($kgm$arg0_idx < $kgm$arg0_array->count)
3177 showarraysetint $arg0 $arg1
3182 set $kgm_array = ((OSSet *)$arg1)->members
3184 showarraysetint $arg0 $kgm_array
3189 define showobjectint
3190 set $kgm_obj = (OSObject *) $arg1
3191 set $kgm_vt = *((void **) $arg1)
3193 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
3194 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
3197 if ($kgm_show_object_addrs)
3201 output /a (unsigned long) $kgm_vt
3202 if ($kgm_show_object_retain)
3203 printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16
3208 # No multiple-inheritance
3210 if ($kgm_vt == &_ZTV8OSString)
3214 if ($kgm_vt == &_ZTV8OSSymbol)
3218 if ($kgm_vt == &_ZTV8OSNumber)
3222 if ($kgm_vt == &_ZTV6OSData)
3223 if $kgm_show_data_alwaysbytes == 1
3230 if ($kgm_vt == &_ZTV9OSBoolean)
3234 if ($kgm_vt == &_ZTV12OSDictionary)
3235 showdictionaryint _$arg0 $arg1
3238 if ($kgm_vt == &_ZTV7OSArray)
3239 showarrayint _$arg0 $arg1
3242 if ($kgm_vt == &_ZTV5OSSet)
3243 showsetint _$arg0 $arg1
3247 if ($kgm_shown != 1)
3248 if ($kgm_show_object_addrs == 0)
3252 output /a (unsigned long) $kgm_vt
3259 set $kgm_save = $kgm_show_object_addrs
3260 set $kgm_show_object_addrs = 1
3261 set $kgm_show_object_retain = 1
3262 showobjectint _ $arg0
3263 set $kgm_show_object_addrs = $kgm_save
3264 set $kgm_show_object_retain = 0
3268 Syntax: (gdb) showobject <object address>
3269 | Show info about an OSObject - its vtable ptr and retain count.
3270 | If the object is a simple container class, more info will be shown.
3274 set $kgm_dictp = (OSDictionary *)$arg0
3275 set $kgm_keyp = (const OSSymbol *)$arg1
3278 while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0))
3279 if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key)
3280 set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value
3282 set $kgm_idx = $kgm_idx + 1
3287 define _registryentryrecurseinit
3288 set $kgm_re = (IOService *)$arg1
3289 set $kgm$arg0_stack = (unsigned long long) $arg2
3292 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
3294 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
3297 dictget $kgm_re->fRegistryTable $kgm_childkey
3298 set $kgm$arg0_child_array = (OSArray *) $kgm_result
3300 if ($kgm$arg0_child_array)
3301 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
3303 set $kgm$arg0_child_count = 0
3306 if ($kgm$arg0_child_count)
3307 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
3309 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
3313 define findregistryentryrecurse
3314 set $kgm_registry_entry = 0
3315 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
3317 dictget $kgm_re->fRegistryTable $kgm_namekey
3318 if ($kgm_result == 0)
3319 dictget $kgm_re->fRegistryTable gIONameKey
3321 if ($kgm_result == 0)
3322 dictget $kgm_re->fPropertyTable gIOClassKey
3325 if ($kgm_result != 0)
3326 set $str = ((OSString *) $kgm_result)->string
3327 strcmp_nomalloc $str $kgm_reg_find_str0 $kgm_reg_find_str1 $kgm_reg_find_str2 $kgm_reg_find_str3 $kgm_reg_find_str4 $kgm_reg_find_str5 $kgm_reg_find_str6 $kgm_reg_find_str7 $kgm_reg_find_str8
3328 if $kgm_findregistry_verbose
3332 if $kgm_strcmp_result == 0
3333 if $kgm_findregistry_verbose
3334 printf "\n%s:\n | ", ((OSString *) $kgm_result)->string
3340 # if we want to show everything, then don't populate $kgm_registry_entry
3341 if !$kgm_findregistry_continue
3342 set $kgm_registry_entry = $kgm_re
3348 if (!$kgm_registry_entry && ($kgm$arg0_child_count != 0))
3349 set $kgm_reg_depth = $kgm_reg_depth + 1
3350 set $kgm$arg0_child_idx = 0
3352 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3353 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
3354 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3355 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
3358 findregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
3359 if $kgm_registry_entry
3363 set $kgm_reg_depth = $kgm_reg_depth - 1
3367 define findregdictvalue
3368 set $kgm_registry_value = 0
3369 set $kgm_reg_idx = 0
3370 while ($kgm_reg_idx < $arg0->count)
3371 set $kgm_obj = $arg0->dictionary + $kgm_reg_idx
3372 set $str = ((OSString *)$kgm_obj->key)->string
3373 strcmp_nomalloc $str $kgm_reg_find_str0 $kgm_reg_find_str1 $kgm_reg_find_str2 $kgm_reg_find_str3 $kgm_reg_find_str4 $kgm_reg_find_str5 $kgm_reg_find_str6 $kgm_reg_find_str7 $kgm_reg_find_str8
3375 if $kgm_strcmp_result == 0
3376 set $kgm_registry_value = $kgm_obj->value
3377 if $kgm_findregistry_verbose
3378 showobject $kgm_registry_value
3379 print $kgm_registry_value
3383 set $kgm_reg_idx = $kgm_reg_idx + 1
3387 define setfindregistrystr
3388 set $kgm_reg_find_str0 = 0
3389 set $kgm_reg_find_str1 = 0
3390 set $kgm_reg_find_str2 = 0
3391 set $kgm_reg_find_str3 = 0
3392 set $kgm_reg_find_str4 = 0
3393 set $kgm_reg_find_str5 = 0
3394 set $kgm_reg_find_str6 = 0
3395 set $kgm_reg_find_str7 = 0
3396 set $kgm_reg_find_str8 = 0
3399 set $kgm_reg_find_str0 = $arg0
3402 set $kgm_reg_find_str1 = $arg1
3405 set $kgm_reg_find_str2 = $arg2
3408 set $kgm_reg_find_str3 = $arg3
3411 set $kgm_reg_find_str4 = $arg4
3414 set $kgm_reg_find_str5 = $arg5
3417 set $kgm_reg_find_str6 = $arg6
3420 set $kgm_reg_find_str7 = $arg7
3423 set $kgm_reg_find_str8 = $arg8
3427 document setfindregistrystr
3428 Syntax: (gdb) setfindregistrystr [a] [b] [c] [d] [e] [f] [g] [h] [i]
3429 | Store an encoded string into up to 9 arguments for use by
3430 | findregistryprop or findregistryentry. The arguments are created
3431 | through calls to strcmp_arg_pack64
3434 define _findregistryprop
3435 set $reg = (IOService *) $arg0
3436 set $kgm_props = $reg->fPropertyTable
3437 set $kgm_findregistry_verbose = 0
3439 findregdictvalue $kgm_props
3442 define findregistryprop
3443 set $reg = (IOService *) $arg0
3444 set $kgm_props = $reg->fPropertyTable
3446 set $kgm_findregistry_verbose = 1
3447 findregdictvalue $kgm_props
3450 document findregistryprop
3451 Syntax: (gdb) findregistryprop <entry>
3452 | Given a registry entry, print out the contents for the property that matches
3453 | the encoded string specified via setfindregistrystr.
3455 | For example, the following will print out the "intel-pic" property stored in
3456 | the AppleACPIPlatformExpert registry entry $pe_entry:
3457 | strcmp_arg_pack64 'i' 'n' 't' 'e' 'l' '-' 'p' 'i'
3458 | set $intel_pi = $kgm_strcmp_arg
3459 | strcmp_arg_pack64 'c' 0 0 0 0 0 0 0
3460 | set $c = $kgm_strcmp_arg
3461 | setfindregistrystr $intel_pi $c
3462 | findregistryprop $pe_entry
3465 define findregistryentryint
3467 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
3471 printf "Please load kgmacros after KDP attaching to the target.\n"
3473 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
3474 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
3475 if $kgm_findregistry_verbose
3478 findregistryentryrecurse _ $arg0 0 0
3482 define _findregistryentry
3483 set $kgm_findregistry_verbose = 0
3484 set $kgm_findregistry_continue = 0
3485 set $kgm_reg_depth = 0
3487 findregistryentryint gRegistryRoot
3490 define findregistryentry
3491 set $kgm_findregistry_verbose = 1
3492 set $kgm_findregistry_continue = 0
3493 set $kgm_reg_depth = 0
3495 findregistryentryint gRegistryRoot
3498 define findregistryentries
3499 set $kgm_findregistry_verbose = 1
3500 set $kgm_findregistry_continue = 1
3501 set $kgm_reg_depth = 0
3503 findregistryentryint gRegistryRoot
3506 document findregistryentry
3507 Syntax: (gdb) findregistryentry
3508 | Search for a registry entry that matches the encoded string specified through
3509 | setfindregistrystr. You can alter the search depth through use of
3510 | $kgm_reg_depth_max.
3512 | For example, the following will pull out the AppleACPIPlatformExpert registry
3514 | strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
3515 | set $AppleACP = $kgm_strcmp_arg
3516 | strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
3517 | set $IPlatfor = $kgm_strcmp_arg
3518 | strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
3519 | set $mExpert = $kgm_strcmp_arg
3520 | setfindregistrystr $AppleACP $IPlatfor $mExpert
3524 document findregistryentries
3525 Syntax: (gdb) findregistryentries
3526 | Search for all registry entries that match the encoded string specified through
3527 | setfindregistrystr. You can alter the search depth through use of
3528 | $kgm_reg_depth_max. See findregistryentry for an example of how to encode a string.
3532 define showregistryentryrecurse
3533 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
3535 indent $kgm_reg_depth $kgm$arg0_stack
3538 dictget $kgm_re->fRegistryTable $kgm_namekey
3539 if ($kgm_result == 0)
3540 dictget $kgm_re->fRegistryTable gIONameKey
3542 if ($kgm_result == 0)
3543 dictget $kgm_re->fPropertyTable gIOClassKey
3546 if ($kgm_result != 0)
3547 printf "%s", ((OSString *)$kgm_result)->string
3549 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
3550 printf "%s", ((IOService*)$kgm_re)->pwrMgt->Name
3552 # printf ", guessclass "
3553 # guessclass $kgm_re
3561 printf ", id 0x%llx, ", $kgm_re->IORegistryEntry::reserved->fRegistryEntryID
3563 set $kgm_vt = (unsigned long) *(void**) $kgm_re
3564 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
3565 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
3569 if ($kgm_vt != &_ZTV15IORegistryEntry)
3571 set $kgm_state = $kgm_re->__state[0]
3572 # kIOServiceRegisteredState
3573 if (0 == ($kgm_state & 2))
3576 printf "registered, "
3577 # kIOServiceMatchedState
3578 if (0 == ($kgm_state & 4))
3582 # kIOServiceInactiveState
3586 printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount)
3590 if ($kgm_show_props)
3591 set $kgm_props = $kgm_re->fPropertyTable
3592 showregdictionary $kgm_props $kgm$arg0_stack
3596 if ($kgm$arg0_child_count != 0)
3598 set $kgm_reg_depth = $kgm_reg_depth + 1
3599 set $kgm$arg0_child_idx = 0
3601 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3602 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
3603 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3604 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
3607 showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
3610 set $kgm_reg_depth = $kgm_reg_depth - 1
3614 define showregistryentryint
3616 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
3620 printf "Please load kgmacros after KDP attaching to the target.\n"
3622 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
3623 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
3624 showregistryentryrecurse _ $arg0 0 0
3629 set $kgm_reg_depth = 0
3630 set $kgm_show_props = 0
3631 showregistryentryint gRegistryRoot
3633 document showregistry
3634 Syntax: (gdb) showregistry
3635 | Show info about all registry entries in the current plane. You can specify the maximum
3636 | display depth with $kgm_reg_depth_max.
3639 define showregistryprops
3640 set $kgm_reg_depth = 0
3641 set $kgm_show_props = 1
3642 showregistryentryint gRegistryRoot
3644 document showregistryprops
3645 Syntax: (gdb) showregistryprops
3646 | Show info about all registry entries in the current plane, and their properties.
3647 | set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display
3648 | more verbose information
3651 define showregistryentry
3652 set $kgm_reg_depth = 0
3653 set $kgm_show_props = 1
3654 showregistryentryint $arg0
3656 document showregistryentry
3657 Syntax: (gdb) showregistryentry <object address>
3658 | Show info about a registry entry; its properties and descendants in the current plane.
3661 define setregistryplane
3663 set $kgm_reg_plane = (IORegistryPlane *) $arg0
3665 showobjectint _ gIORegistryPlanes
3669 document setregistryplane
3670 Syntax: (gdb) setregistryplane <plane object address>
3671 | Set the plane to be used for the iokit registry macros. An argument of zero will
3672 | display known planes.
3676 set $kgm_classidx = 0
3677 set $kgm_lookvt = *((void **) $arg0)
3678 set $kgm_bestvt = (void *) 0
3679 set $kgm_bestidx = 0
3681 while $kgm_classidx < sAllClassesDict->count
3682 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value
3684 set $kgm_vt = *((void **) $kgm_meta)
3686 if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt))
3687 set $kgm_bestvt = $kgm_vt
3688 set $kgm_bestidx = $kgm_classidx
3690 set $kgm_classidx = $kgm_classidx + 1
3692 printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string
3695 define showallclasses
3696 set $kgm_classidx = 0
3697 while $kgm_classidx < sAllClassesDict->count
3698 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value
3699 showmetaclass $kgm_meta
3703 document showallclasses
3704 Syntax: (gdb) showallclasses
3705 | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
3709 printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024
3710 printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024
3711 printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024
3712 printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024
3715 document showioalloc
3716 Syntax: (gdb) showioalloc
3717 | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
3720 define showosobjecttracking
3721 set $kgm_next = (OSObjectTracking *) gOSObjectTrackList.next
3722 while $kgm_next != &gOSObjectTrackList
3723 set $obj = (OSObject *) ($kgm_next+1)
3726 while $kgm_idx < (sizeof($kgm_next->bt) / sizeof($kgm_next->bt[0]))
3727 if ((unsigned long) $kgm_next->bt[$kgm_idx] > (unsigned long) &last_kernel_symbol)
3728 showkmodaddr $kgm_next->bt[$kgm_idx]
3731 if ((unsigned long) $kgm_next->bt[$kgm_idx] > 0)
3732 output /a $kgm_next->bt[$kgm_idx]
3736 set $kgm_idx = $kgm_idx + 1
3739 set $kgm_next = (OSObjectTracking *) $kgm_next->link.next
3743 document showosobjecttracking
3744 Syntax: (gdb) showosobjecttracking
3745 | Show the list of tracked OSObject allocations with backtraces.
3746 | Boot with the kOSTraceObjectAlloc (0x00400000) io debug flag set.
3747 | Set gOSObjectTrackThread to 1 or a thread_t to capture new OSObjects allocated by a thread or all threads.
3751 set $kgm_readphysint_result = 0xBAD10AD
3752 # set up the manual KDP packet
3753 set manual_pkt.input = 0
3754 set manual_pkt.len = sizeof(kdp_readphysmem64_req_t)
3755 set $kgm_pkt = (kdp_readphysmem64_req_t *)&manual_pkt.data
3756 set $kgm_pkt->hdr.request = KDP_READPHYSMEM64
3757 set $kgm_pkt->hdr.len = sizeof(kdp_readphysmem64_req_t)
3758 set $kgm_pkt->hdr.is_reply = 0
3759 set $kgm_pkt->hdr.seq = 0
3760 set $kgm_pkt->hdr.key = 0
3761 set $kgm_pkt->address = (uint64_t)$arg0
3762 set $kgm_pkt->nbytes = $arg1 >> 3
3763 set $kgm_pkt->lcpu = $arg2
3764 set manual_pkt.input = 1
3765 # dummy to make sure manual packet is executed
3766 set $kgm_dummy = &_mh_execute_header
3767 set $kgm_pkt = (kdp_readphysmem64_reply_t *)&manual_pkt.data
3768 if ($kgm_pkt->error == 0)
3770 set $kgm_readphysint_result = *((uint8_t *)$kgm_pkt->data)
3773 set $kgm_readphysint_result = *((uint16_t *)$kgm_pkt->data)
3776 set $kgm_readphysint_result = *((uint32_t *)$kgm_pkt->data)
3779 set $kgm_readphysint_result = *((uint64_t *)$kgm_pkt->data)
3785 readphysint $arg0 8 $kgm_lcpu_self
3787 printf ":\t0x%02hhx\n", $kgm_readphysint_result
3788 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3792 readphysint $arg0 16 $kgm_lcpu_self
3794 printf ":\t0x%04hx\n", $kgm_readphysint_result
3795 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3799 readphysint $arg0 32 $kgm_lcpu_self
3801 printf ":\t0x%08x\n", $kgm_readphysint_result
3802 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3806 readphysint $arg0 64 $kgm_lcpu_self
3808 printf ":\t0x%016llx\n", $kgm_readphysint_result
3809 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3829 | The argument is interpreted as a physical address, and the 64-bit word
3830 | addressed is displayed. Saves 64-bit result in $kgm_readphys_result.
3834 # set up the manual KDP packet
3835 set manual_pkt.input = 0
3836 set manual_pkt.len = sizeof(kdp_writephysmem64_req_t)
3837 set $kgm_pkt = (kdp_writephysmem64_req_t *)&manual_pkt.data
3838 set $kgm_pkt->hdr.request = KDP_WRITEPHYSMEM64
3839 set $kgm_pkt->hdr.len = sizeof(kdp_writephysmem64_req_t)
3840 set $kgm_pkt->hdr.is_reply = 0
3841 set $kgm_pkt->hdr.seq = 0
3842 set $kgm_pkt->hdr.key = 0
3843 set $kgm_pkt->address = (uint64_t)$arg0
3844 set $kgm_pkt->nbytes = $arg1 >> 3
3845 set $kgm_pkt->lcpu = $arg3
3847 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
3850 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
3853 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
3856 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg2
3858 set manual_pkt.input = 1
3859 # dummy to make sure manual packet is executed
3860 set $kgm_dummy = &_mh_execute_header
3861 set $kgm_pkt = (kdp_writephysmem64_reply_t *)&manual_pkt.data
3862 set $kgm_writephysint_result = $kgm_pkt->error
3866 writephysint $arg0 8 $arg1 $kgm_lcpu_self
3870 writephysint $arg0 16 $arg1 $kgm_lcpu_self
3874 writephysint $arg0 32 $arg1 $kgm_lcpu_self
3878 writephysint $arg0 64 $arg1 $kgm_lcpu_self
3885 document writephys16
3889 document writephys32
3893 document writephys64
3894 | The argument is interpreted as a physical address, and the second argument is
3895 | written to that address as a 64-bit word.
3899 shell ls $arg0/* | xargs -n 1 echo add-symbol-file > /tmp/gdb-syms
3900 source /tmp/gdb-syms
3901 set $kgm_show_kmod_syms = 1
3904 document addkextsyms
3905 | Takes a directory of symbols for kexts generated with kextcache -y and loads them
3907 | (gdb) addkextsyms /path/to/symboldir
3910 define showprocfiles
3913 _showprocfiles $arg0
3915 printf "| Usage:\n|\n"
3919 document showprocfiles
3920 Syntax: (gdb) showprocfiles <proc_t>
3921 | Given a proc_t pointer, display the list of open file descriptors for the
3922 | referenced process.
3925 define _showprocheader
3926 printf "fd fileglob "
3928 printf " fg flags fg type fg data "
3931 printf "----- ----------"
3935 printf " ---------- -------- ----------"
3939 printf " -------------------\n"
3942 define _showprocfiles
3943 set $kgm_spf_filedesc = ((proc_t)$arg0)->p_fd
3944 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
3945 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
3946 set $kgm_spf_count = 0
3947 while ($kgm_spf_count <= $kgm_spf_last)
3948 if ($kgm_spf_ofiles[$kgm_spf_count] == 0)
3949 # DEBUG: For files that were open, but are now closed
3950 # printf "%-5d FILEPROC_NULL\n", $kgm_spf_count
3952 # display fd #, fileglob address, fileglob flags
3953 set $kgm_spf_flags = $kgm_spf_ofiles[$kgm_spf_count].f_flags
3954 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
3955 printf "%-5d ", $kgm_spf_count
3957 printf " 0x%08x ", $kgm_spf_flags
3958 # decode fileglob type
3959 set $kgm_spf_fgt = $kgm_spf_fg->fg_type
3960 if ($kgm_spf_fgt == 1)
3963 if ($kgm_spf_fgt == 2)
3966 if ($kgm_spf_fgt == 3)
3969 if ($kgm_spf_fgt == 4)
3972 if ($kgm_spf_fgt == 5)
3975 if ($kgm_spf_fgt == 6)
3978 if ($kgm_spf_fgt == 7)
3981 if ($kgm_spf_fgt < 1 || $kgm_spf_fgt > 7)
3982 printf "?: %-5d", $kgm_spf_fgt
3985 # display fileglob data address and decode interesting fact(s)
3986 # about data, if we know any
3987 set $kgm_spf_fgd = $kgm_spf_fg->fg_data
3989 showptr $kgm_spf_fgd
3991 if ($kgm_spf_fgt == 1)
3992 set $kgm_spf_name = ((struct vnode *)$kgm_spf_fgd)->v_name
3993 if ($kgm_spf_name == 0)
3996 printf "%s", $kgm_spf_name
4001 set $kgm_spf_count = $kgm_spf_count + 1
4006 # Show all the advisory file locks held by a process for each of the vnode
4007 # type files that it has open; do this by walking the per process open file
4008 # table and looking at any vnode type fileglob that has a non-NULL lock list
4009 # associated with it.
4011 define showproclocks
4013 _showproclocks $arg0
4015 printf "| Usage:\n|\n"
4019 document showproclocks
4020 Syntax: (gdb) showproclocks <proc_t>
4021 | Given a proc_t pointer, display the list of advisory file locks held by the
4022 | referenced process.
4025 define _showproclocks
4026 set $kgm_spl_filedesc = ((proc_t)$arg0)->p_fd
4027 set $kgm_spl_last = $kgm_spl_filedesc->fd_lastfile
4028 set $kgm_spl_ofiles = $kgm_spl_filedesc->fd_ofiles
4029 set $kgm_spl_count = 0
4030 set $kgm_spl_seen = 0
4031 while ($kgm_spl_count <= $kgm_spl_last)
4032 if ($kgm_spl_ofiles[$kgm_spl_count] == 0)
4033 # DEBUG: For files that were open, but are now closed
4034 # printf "%-5d FILEPROC_NULL\n", $kgm_spl_count
4036 set $kgm_spl_fg = $kgm_spl_ofiles[$kgm_spl_count].f_fglob
4037 # decode fileglob type
4038 set $kgm_spl_fgt = $kgm_spl_fg->fg_type
4039 if ($kgm_spl_fgt == 1)
4040 set $kgm_spl_fgd = $kgm_spl_fg->fg_data
4041 set $kgm_spl_name = ((struct vnode *)$kgm_spl_fgd)->v_name
4042 set $kgm_spl_vnode = ((vnode_t)$kgm_spl_fgd)
4043 set $kgm_spl_lockiter = $kgm_spl_vnode->v_lockf
4044 if ($kgm_spl_lockiter != 0)
4045 if ($kgm_spl_seen == 0)
4046 _showvnodelockheader
4048 set $kgm_spl_seen = $kgm_spl_seen + 1
4049 printf "( fd %d, name ", $kgm_spl_count
4050 if ($kgm_spl_name == 0)
4053 printf "%s )\n", $kgm_spl_name
4055 _showvnodelocks $kgm_spl_fgd
4059 set $kgm_spl_count = $kgm_spf_count + 1
4061 printf "%d total locks for ", $kgm_spl_seen
4067 set $kgm_spi_proc = (proc_t)$arg0
4069 showptr $kgm_spi_proc
4071 printf " name %s\n", $kgm_spi_proc->p_comm
4072 printf " pid:%.8d", $kgm_spi_proc->p_pid
4074 showptr $kgm_spi_proc->task
4075 printf " p_stat:%.1d", $kgm_spi_proc->p_stat
4076 printf " parent pid:%.8d", $kgm_spi_proc->p_ppid
4078 # decode part of credential
4079 set $kgm_spi_cred = $kgm_spi_proc->p_ucred
4080 if ($kgm_spi_cred != 0)
4081 printf "Cred: euid %d ruid %d svuid %d\n", $kgm_spi_cred->cr_uid, $kgm_spi_cred->cr_ruid, $kgm_spi_cred->cr_svuid
4083 printf "Cred: (null)\n"
4086 set $kgm_spi_flag = $kgm_spi_proc->p_flag
4087 printf "Flags: 0x%08x\n", $kgm_spi_flag
4088 if ($kgm_spi_flag & 0x00000001)
4089 printf " 0x00000001 - may hold advisory locks\n"
4091 if ($kgm_spi_flag & 0x00000002)
4092 printf " 0x00000002 - has a controlling tty\n"
4094 if ($kgm_spi_flag & 0x00000004)
4095 printf " 0x00000004 - process is 64 bit\n"
4097 printf " !0x00000004 - process is 32 bit\n"
4099 if ($kgm_spi_flag & 0x00000008)
4100 printf " 0x00000008 - no SIGCHLD on child stop\n"
4102 if ($kgm_spi_flag & 0x00000010)
4103 printf " 0x00000010 - waiting for child exec/exit\n"
4105 if ($kgm_spi_flag & 0x00000020)
4106 printf " 0x00000020 - has started profiling\n"
4108 if ($kgm_spi_flag & 0x00000040)
4109 printf " 0x00000040 - in select; wakeup/waiting danger\n"
4111 if ($kgm_spi_flag & 0x00000080)
4112 printf " 0x00000080 - was stopped and continued\n"
4114 if ($kgm_spi_flag & 0x00000100)
4115 printf " 0x00000100 - has set privileges since exec\n"
4117 if ($kgm_spi_flag & 0x00000200)
4118 printf " 0x00000200 - system process: no signals, stats, or swap\n"
4120 if ($kgm_spi_flag & 0x00000400)
4121 printf " 0x00000400 - timing out during a sleep\n"
4123 if ($kgm_spi_flag & 0x00000800)
4124 printf " 0x00000800 - debugged process being traced\n"
4126 if ($kgm_spi_flag & 0x00001000)
4127 printf " 0x00001000 - debugging process has waited for child\n"
4129 if ($kgm_spi_flag & 0x00002000)
4130 printf " 0x00002000 - exit in progress\n"
4132 if ($kgm_spi_flag & 0x00004000)
4133 printf " 0x00004000 - process has called exec\n"
4135 if ($kgm_spi_flag & 0x00008000)
4136 printf " 0x00008000 - owe process an addupc() XXX\n"
4138 if ($kgm_spi_flag & 0x00010000)
4139 printf " 0x00010000 - affinity for Rosetta children\n"
4141 if ($kgm_spi_flag & 0x00020000)
4142 printf " 0x00020000 - wants to run Rosetta\n"
4144 if ($kgm_spi_flag & 0x00040000)
4145 printf " 0x00040000 - has wait() in progress\n"
4147 if ($kgm_spi_flag & 0x00080000)
4148 printf " 0x00080000 - kdebug tracing on for this process\n"
4150 if ($kgm_spi_flag & 0x00100000)
4151 printf " 0x00100000 - blocked due to SIGTTOU or SIGTTIN\n"
4153 if ($kgm_spi_flag & 0x00200000)
4154 printf " 0x00200000 - has called reboot()\n"
4156 if ($kgm_spi_flag & 0x00400000)
4157 printf " 0x00400000 - is TBE state\n"
4159 if ($kgm_spi_flag & 0x00800000)
4160 printf " 0x00800000 - signal exceptions\n"
4162 if ($kgm_spi_flag & 0x01000000)
4163 printf " 0x01000000 - has thread cwd\n"
4165 if ($kgm_spi_flag & 0x02000000)
4166 printf " 0x02000000 - has vfork() children\n"
4168 if ($kgm_spi_flag & 0x04000000)
4169 printf " 0x04000000 - not allowed to attach\n"
4171 if ($kgm_spi_flag & 0x08000000)
4172 printf " 0x08000000 - vfork() in progress\n"
4174 if ($kgm_spi_flag & 0x10000000)
4175 printf " 0x10000000 - no shared libraries\n"
4177 if ($kgm_spi_flag & 0x20000000)
4178 printf " 0x20000000 - force quota for root\n"
4180 if ($kgm_spi_flag & 0x40000000)
4181 printf " 0x40000000 - no zombies when children exit\n"
4183 if ($kgm_spi_flag & 0x80000000)
4184 printf " 0x80000000 - don't hang on remote FS ops\n"
4187 set $kgm_spi_state = $kgm_spi_proc->p_stat
4189 if ($kgm_spi_state == 1)
4192 if ($kgm_spi_state == 2)
4195 if ($kgm_spi_state == 3)
4198 if ($kgm_spi_state == 4)
4201 if ($kgm_spi_state == 5)
4204 if ($kgm_spi_state == 6)
4207 if ($kgm_spi_state < 1 || $kgm_spi_state > 6)
4208 printf "(Unknown)\n"
4212 document showprocinfo
4213 Syntax: (gdb) showprocinfo <proc_t>
4214 | Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
4218 # dump the zombprocs
4221 set $basep = (struct proc *)zombproc->lh_first
4225 set $pp = $pp->p_list.le_next
4230 Syntax: (gdb) zombproc
4231 | Routine to print out all procs in the zombie list
4235 # dump the zombstacks
4238 set $basep = (struct proc *)zombproc->lh_first
4242 showtaskstacks $pp->task
4244 set $pp = $pp->p_list.le_next
4249 Syntax: (gdb) zombstacks
4250 | Routine to print out all stacks of tasks that are exiting
4258 set $basep = (struct proc *)allproc->lh_first
4262 set $pp = $pp->p_list.le_next
4267 Syntax: (gdb) allproc
4268 | Routine to print out all process in the system
4269 | which are not in the zombie list
4275 set $vp = (struct vnode *)$arg0
4279 printf " use %d", $vp->v_usecount
4280 printf " io %d", $vp->v_iocount
4281 printf " kuse %d", $vp->v_kusecount
4282 printf " type %d", $vp->v_type
4283 printf " flg 0x%.8x", $vp->v_flag
4284 printf " lflg 0x%.8x", $vp->v_lflag
4286 showptr $vp->v_parent
4287 set $_name = (char *)$vp->v_name
4289 printf " %s", $_name
4291 if ($vp->v_type == VREG) && ($vp->v_un.vu_ubcinfo != 0)
4292 printf " mapped %d", ($vp->v_un.vu_ubcinfo.ui_flags & 0x08) ? 1 : 0
4297 document print_vnode
4298 Syntax: (gdb) print_vnode <vnode>
4299 | Prints out the fields of a vnode struct
4302 define showprocvnodes
4303 set $pp = (struct proc *)$arg0
4304 set $fdp = (struct filedesc *)$pp->p_fd
4305 set $cvp = $fdp->fd_cdir
4306 set $rvp = $fdp->fd_rdir
4308 printf "Current Working Directory \n"
4313 printf "Current Root Directory \n"
4318 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
4319 set $fpo = (char)($fdp->fd_ofileflags[0])
4320 while $count < $fdp->fd_nfiles
4321 #printf"fpp %x ", *$fpp
4323 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
4324 if $fg && (($fg)->fg_type == 1)
4325 if $fdp->fd_ofileflags[$count] & 4
4330 printf "fd = %d ", $count
4331 print_vnode $fg->fg_data
4335 set $count = $count + 1
4339 document showprocvnodes
4340 Syntax: (gdb) showprocvnodes <proc_address>
4341 | Routine to print out all the open fds
4342 | which are vnodes in a process
4345 define showallprocvnodes
4346 set $basep = (struct proc *)allproc->lh_first
4349 printf "============================================ \n"
4352 set $pp = $pp->p_list.le_next
4356 document showallprocvnodes
4357 Syntax: (gdb) showallprocvnodes
4358 | Routine to print out all the open fds
4364 # dump the childrent of a proc
4366 define showinitchild
4367 set $basep = (struct proc *)initproc->p_children.lh_first
4371 set $pp = $pp->p_sibling.le_next
4375 document showinitchild
4376 Syntax: (gdb) showinitchild
4377 | Routine to print out all processes in the system
4378 | which are children of init process
4382 define showmountallvnodes
4383 set $mp = (struct mount *)$arg0
4384 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
4386 printf "____________________ Vnode list Queue ---------------\n"
4389 set $vp = $vp->v_mntvnodes->tqe_next
4391 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
4393 printf "____________________ Worker Queue ---------------\n"
4396 set $vp = $vp->v_mntvnodes->tqe_next
4398 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
4400 printf "____________________ New vnodes Queue ---------------\n"
4403 set $vp = $vp->v_mntvnodes->tqe_next
4406 document showmountallvnodes
4407 Syntax: showmountallvnodes <struct mount *>
4408 | Print the vnode inactive list
4412 define showmountvnodes
4413 set $mp = (struct mount *)$arg0
4414 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
4416 printf "____________________ Vnode list Queue ---------------\n"
4419 set $vp = $vp->v_mntvnodes->tqe_next
4422 document showmountvnodes
4423 Syntax: showmountvnodes <struct mount *>
4424 | Print the vnode list
4429 define showworkqvnodes
4430 set $mp = (struct mount *)$arg0
4431 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
4433 printf "____________________ Worker Queue ---------------\n"
4436 set $vp = $vp->v_mntvnodes->tqe_next
4439 document showworkqvnodes
4440 Syntax: showworkqvnodes <struct mount *>
4441 | Print the vnode worker list
4445 define shownewvnodes
4446 set $mp = (struct mount *)$arg0
4447 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
4449 printf "____________________ New vnodes Queue ---------------\n"
4452 set $vp = $vp->v_mntvnodes->tqe_next
4456 document shownewvnodes
4457 Syntax: shownewvnodes <struct mount *>
4458 | Print the new vnode list
4463 # print mount point info
4465 set $mp = (struct mount *)$arg0
4469 printf " flag %x", $mp->mnt_flag
4470 printf " kern_flag %x", $mp->mnt_kern_flag
4471 printf " lflag %x", $mp->mnt_lflag
4472 printf " type: %s", $mp->mnt_vfsstat.f_fstypename
4473 printf " mnton: %s", $mp->mnt_vfsstat.f_mntonname
4474 printf " mntfrom: %s", $mp->mnt_vfsstat.f_mntfromname
4478 define showallmounts
4479 set $mp=(struct mount *)mountlist.tqh_first
4482 set $mp = $mp->mnt_list.tqe_next
4486 document showallmounts
4487 Syntax: showallmounts
4488 | Print all mount points
4492 if (((unsigned long) $arg0 < (unsigned long) &_mh_execute_header || \
4493 (unsigned long) $arg0 >= (unsigned long) &last_kernel_symbol ))
4501 set $mp = (struct mbuf *)$arg0
4505 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
4506 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
4511 set $tot = $tot + $mp->m_hdr.mh_len
4512 printf "total %d]\n", $tot
4513 set $mp = $mp->m_hdr.mh_nextpkt
4518 document mbuf_walkpkt
4519 Syntax: (gdb) mbuf_walkpkt <addr>
4520 | Given an mbuf address, walk its m_nextpkt pointer
4524 set $mp = (struct mbuf *)$arg0
4528 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
4529 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
4534 set $tot = $tot + $mp->m_hdr.mh_len
4535 printf "total %d]\n", $tot
4536 set $mp = $mp->m_hdr.mh_next
4542 Syntax: (gdb) mbuf_walk <addr>
4543 | Given an mbuf address, walk its m_next pointer
4546 define mbuf_buf2slab
4548 set $gix = ((char *)$addr - (char *)mbutl) >> 20
4549 set $ix = ((char *)$addr - (char *)mbutl) >> 11
4550 set $slab = &slabstbl[$gix].slg_slab[$ix]
4554 document mbuf_buf2slab
4555 | Given an mbuf object, find its corresponding slab address.
4560 set $ix = ((char *)$addr - (char *)mbutl) >> 11
4561 set $clbase = ((union mcluster *)(mbutl + $ix))
4562 set $mclidx = (((char *)$addr - (char *)$clbase) >> 8)
4563 set $mca = mclaudit[$ix].cl_audit[$mclidx]
4564 printf "mca: %p", $mca
4567 document mbuf_buf2mca
4568 Syntax: (gdb) mbuf_buf2mca <addr>
4569 | Given an mbuf object, find its buffer audit structure address.
4570 | This requires mbuf buffer auditing to be turned on, by setting
4571 | the appropriate flags to the "mbuf_debug" boot-args parameter.
4576 set $mca = (mcache_audit_t *)$arg0
4577 set $cp = (mcache_t *)$mca->mca_cache
4578 printf "object type:\t\t"
4579 mbuf_mca_ctype $mca 1
4580 printf "\ncontrolling mcache:\t%p (%s)\n", $mca->mca_cache, $cp->mc_name
4581 if $mca->mca_uflags & $MB_SCVALID
4582 set $ix = ((char *)$mca->mca_addr - (char *)mbutl) >> 11
4583 set $clbase = ((union mcluster *)(mbutl + $ix))
4584 set $mclidx = (((char *)$mca->mca_addr - (char *)$clbase) >> 8)
4585 printf "mbuf obj:\t\t%p\n", $mca->mca_addr
4586 printf "mbuf index:\t\t%d (out of 8) in cluster base %p\n", \
4587 $mclidx + 1, $clbase
4588 if $mca->mca_uptr != 0
4589 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
4590 printf "paired cluster obj:\t%p (mca %p)\n", \
4591 $peer_mca->mca_addr, $peer_mca
4593 printf "saved contents:\t\t%p (%d bytes)\n", \
4594 $mca->mca_contents, $mca->mca_contents_size
4596 printf "cluster obj:\t\t%p\n", $mca->mca_addr
4597 if $mca->mca_uptr != 0
4598 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
4599 printf "paired mbuf obj:\t%p (mca %p)\n", \
4600 $peer_mca->mca_addr, $peer_mca
4603 printf "recent transaction for this buffer (thread %p):\n", \
4606 while $cnt < $mca->mca_depth
4607 set $kgm_pc = $mca->mca_stack[$cnt]
4608 printf "%4d: ", $cnt + 1
4613 if $mca->mca_pdepth > 0
4614 printf "previous transaction for this buffer (thread %p):\n", \
4618 while $cnt < $mca->mca_pdepth
4619 set $kgm_pc = $mca->mca_pstack[$cnt]
4620 printf "%4d: ", $cnt + 1
4628 document mbuf_showmca
4629 Syntax: (gdb) mbuf_showmca <addr>
4630 | Given an mbuf/cluster buffer audit structure address, print the audit
4631 | records including the stack trace of the last buffer transaction.
4634 set $MCF_NOCPUCACHE = 0x10
4637 set $head = (mcache_t *)mcache_head
4641 printf "cache cache cache buf buf backing (# of retries) bufs\n"
4642 printf "name state addr size align zone wait nowait failed incache\n"
4643 printf "------------------------- -------- ------------------ ------ ----- ------------------ -------------------------- --------\n"
4645 printf "cache cache cache buf buf backing (# of retries) bufs\n"
4646 printf "name state addr size align zone wait nowait failed incache\n"
4647 printf "------------------------- -------- ---------- ------ ----- ---------- -------------------------- --------\n"
4650 set $bktsize = $mc->mc_cpu.cc_bktsize
4651 printf "%-25s ", $mc->mc_name
4652 if ($mc->mc_flags & $MCF_NOCPUCACHE)
4655 if $mc->mc_purge_cnt > 0
4665 printf " %p %6d %5d ",$mc, \
4666 $mc->mc_bufsize, $mc->mc_align
4667 if $mc->mc_slab_zone != 0
4668 printf "%p", $mc->mc_slab_zone
4677 set $tot += $mc->mc_full.bl_total * $bktsize
4678 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
4681 if $ccp->cc_objs > 0
4682 set $tot += $ccp->cc_objs
4684 if $ccp->cc_pobjs > 0
4685 set $tot += $ccp->cc_pobjs
4690 printf " %8d %8d %8d %8d", $mc->mc_wretry_cnt, \
4691 $mc->mc_nwretry_cnt, $mc->mc_nwfail_cnt, $tot
4693 set $mc = (mcache_t *)$mc->mc_list.le_next
4697 document mcache_stat
4698 Syntax: (gdb) mcache_stat
4699 | Print all mcaches in the system.
4702 define mcache_showzone
4703 set $mc = (mcache_t *)$arg0
4704 if $mc->mc_slab_zone != 0
4705 printf "%p", $mc->mc_slab_zone
4710 document mcache_showzone
4711 Syntax: (gdb) mcache_showzone <mcache_addr>
4712 | Print the type of backend (custom or zone) of a mcache.
4715 define mcache_walkobj
4716 set $p = (mcache_obj_t *)$arg0
4720 printf "%4d: %p\n", $cnt, $p,
4721 set $p = $p->obj_next
4726 document mcache_walkobj
4727 Syntax: (gdb) mcache_walkobj <addr>
4728 | Given a mcache object address, walk its obj_next pointer
4731 define mcache_showcache
4732 set $cp = (mcache_t *)$arg0
4733 set $ccp = (mcache_cpu_t *)$cp->mc_cpu
4734 set $bktsize = $cp->mc_cpu.cc_bktsize
4737 printf "Showing cache '%s':\n\n", $cp->mc_name
4738 printf " CPU cc_objs cc_pobjs total\n"
4739 printf "---- -------- -------- --------\n"
4741 set $objs = $ccp->cc_objs
4745 set $pobjs = $ccp->cc_pobjs
4749 set $tot_cpu = $objs + $pobjs
4750 set $tot += $tot_cpu
4751 printf "%4d %8d %8d %8d\n", $cnt, $objs, $pobjs, $tot_cpu
4755 printf " ========\n"
4756 printf " %8d\n", $tot
4758 set $tot += $cp->mc_full.bl_total * $bktsize
4759 printf "Total # of full buckets (%d objs/bkt):\t%-8d\n", \
4760 $bktsize, $cp->mc_full.bl_total
4761 printf "Total # of objects cached:\t\t%-8d\n", $tot
4764 document mcache_showcache
4765 | Display the number of objects in the cache
4768 set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
4770 define mbuf_slabstbl
4773 printf "slot addr slabs range\n"
4774 printf "---- ---------- -----------------------\n"
4775 while $x < maxslabgrp
4776 set $slg = slabstbl[$x]
4781 printf "%p [%p-%p]\n", $slg, &$slg->slg_slab[0], \
4782 &$slg->slg_slab[$NSLABSPMB-1]
4788 document mbuf_slabstbl
4789 | Display the mbuf slabs table
4792 set $SLF_MAPPED=0x0001
4793 set $SLF_PARTIAL=0x0002
4794 set $SLF_DETACHED=0x0004
4797 set $slg = (mcl_slabg_t *)$arg0
4801 printf "slot addr next base C R N size flags\n"
4802 printf "---- ------------------ ------------------ ------------------ -- -- -- ------ -----\n"
4804 printf "slot addr next base C R N size flags\n"
4805 printf "---- ---------- ---------- ---------- -- -- -- ------ -----\n"
4807 while $x < $NSLABSPMB
4808 set $sl = &$slg->slg_slab[$x]
4809 printf "%3d: %p %p %p %2d %2d %2d %6d 0x%04x ", \
4810 $x + 1, $sl, $sl->sl_next, $sl->sl_base, $sl->sl_class, \
4811 $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
4813 if $sl->sl_flags != 0
4815 if $sl->sl_flags & $SLF_MAPPED
4818 if $sl->sl_flags & $SLF_PARTIAL
4821 if $sl->sl_flags & $SLF_DETACHED
4832 | Display all mbuf slabs in the group
4838 printf "class total cached uncached inuse failed waiter notified purge\n"
4839 printf "name objs objs objs / slabs objs alloc count count count count\n"
4840 printf "---------------- -------- -------- ------------------- -------- ---------------- -------- -------- --------\n"
4841 while $x < (sizeof(mbuf_table) / sizeof(mbuf_table[0]))
4842 set $mbt = mbuf_table[$x]
4843 set $mcs = (mb_class_stat_t *)mbuf_table[$x].mtbl_stats
4845 set $mc = $mbt->mtbl_cache
4846 set $bktsize = $mc->mc_cpu.cc_bktsize
4847 set $tot += $mc->mc_full.bl_total * $bktsize
4848 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
4851 if $ccp->cc_objs > 0
4852 set $tot += $ccp->cc_objs
4854 if $ccp->cc_pobjs > 0
4855 set $tot += $ccp->cc_pobjs
4861 printf "%-16s %8d %8d %8d / %-8d %8d %16llu %8d %8llu %8llu", \
4862 $mcs->mbcl_cname, $mcs->mbcl_total, $tot, \
4863 $mcs->mbcl_infree, $mcs->mbcl_slab_cnt, \
4864 ($mcs->mbcl_total - $tot - $mcs->mbcl_infree), \
4865 $mcs->mbcl_fail_cnt, $mc->mc_waiter_cnt, \
4866 $mcs->mbcl_notified, $mcs->mbcl_purge_cnt
4873 | Print extended mbuf allocator statistics.
4877 set $MB_COMP_INUSE = 0x2
4878 set $MB_SCVALID = 0x4
4880 set $MCLBYTES = 2048
4883 set $M16KCLBYTES = 16384
4885 define mbuf_mca_ctype
4886 set $mca = (mcache_audit_t *)$arg0
4888 set $cp = $mca->mca_cache
4889 set $class = (unsigned int)$cp->mc_private
4890 set $csize = mbuf_table[$class].mtbl_stats->mbcl_size
4900 if !$done && $csize == $MCLBYTES
4902 printf "CL (2K cluster) "
4908 if !$done && $csize == $NBPG
4910 printf "BCL (4K cluster) "
4916 if !$done && $csize == $M16KCLBYTES
4918 printf "JCL (16K cluster) "
4924 if !$done && $csize == ($MSIZE+$MCLBYTES)
4925 if $mca->mca_uflags & $MB_SCVALID
4929 printf "(paired mbuf, 2K cluster)"
4934 printf "(unpaired mbuf, 2K cluster) "
4941 printf "(paired 2K cluster, mbuf) "
4946 printf "(paired 2K cluster, mbuf) "
4952 if !$done && $csize == ($MSIZE+$NBPG)
4953 if $mca->mca_uflags & $MB_SCVALID
4957 printf "(paired mbuf, 4K cluster) "
4962 printf "(unpaired mbuf, 4K cluster) "
4969 printf "(paired 4K cluster, mbuf) "
4974 printf "(unpaired 4K cluster, mbuf) "
4980 if !$done && $csize == ($MSIZE+$M16KCLBYTES)
4981 if $mca->mca_uflags & $MB_SCVALID
4985 printf "(paired mbuf, 16K cluster) "
4990 printf "(unpaired mbuf, 16K cluster) "
4997 printf "(paired 16K cluster, mbuf) "
5002 printf "(unpaired 16K cluster, mbuf) "
5009 printf "unknown: %s ", $cp->mc_name
5013 document mbuf_mca_ctype
5014 | This is a helper macro for mbuf_show{active,inactive,all} that prints
5015 | out the mbuf object type represented by a given mcache audit structure.
5018 define mbuf_showactive
5020 mbuf_walkallslabs 1 0
5022 mbuf_walkallslabs 1 0 $arg0
5026 document mbuf_showactive
5027 Syntax: (gdb) mbuf_showactive
5028 | Walk the mbuf objects pool and print only the active ones; this
5029 | requires mbuf debugging to be turned on, by setting the appropriate flags
5030 | to the "mbuf_debug" boot-args parameter. Active objects are those that
5031 | are outstanding (have not returned to the mbuf slab layer) and in use
5032 | by the client (have not been freed).
5035 define mbuf_showinactive
5036 mbuf_walkallslabs 0 1
5039 document mbuf_showinactive
5040 Syntax: (gdb) mbuf_showinactive
5041 | Walk the mbuf objects pool and print only the inactive ones; this
5042 | requires mbuf debugging to be turned on, by setting the appropriate flags
5043 | to the "mbuf_debug" boot-args parameter. Inactive objects are those that
5044 | are outstanding (have not returned to the mbuf slab layer) but have been
5045 | freed by the client, i.e. they still reside in the mcache layer ready to
5046 | be used for subsequent allocation requests.
5050 mbuf_walkallslabs 1 1
5053 document mbuf_showall
5054 Syntax: (gdb) mbuf_showall
5055 | Walk the mbuf objects pool and print them all; this requires
5056 | mbuf debugging to be turned on, by setting the appropriate flags to the
5057 | "mbuf_debug" boot-args parameter.
5063 define mbuf_walkallslabs
5067 set $show_tr = $arg2
5077 if $show_a && !$show_f
5078 printf "Searching only for active "
5080 if !$show_a && $show_f
5081 printf "Searching only for inactive "
5083 if $show_a && $show_f
5084 printf "Displaying all "
5086 printf "objects; this may take a while ...)\n\n"
5089 printf " slab mca obj allocation\n"
5090 printf "slot idx address address address type state\n"
5091 printf "---- ---- ------------------ ------------------ ------------------ ----- -----------\n"
5093 printf " slab mca obj allocation\n"
5094 printf "slot idx address address address type state\n"
5095 printf "---- ---- ---------- ---------- ---------- ----- -----------\n"
5099 set $slg = slabstbl[$x]
5102 while $y < $NSLABSPMB && $stop == 0
5103 set $sl = &$slg->slg_slab[$y]
5104 set $base = (char *)$sl->sl_base
5105 set $ix = ($base - (char *)mbutl) >> 11
5106 set $clbase = ((union mcluster *)(mbutl + $ix))
5107 set $mclidx = ($base - (char *)$clbase) >> 8
5108 set $mca = mclaudit[$ix].cl_audit[$mclidx]
5111 while $mca != 0 && $mca->mca_addr != 0
5113 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
5114 set $total_a = $total_a + 1
5115 set $printmca = $show_a
5117 set $total_f = $total_f + 1
5118 set $printmca = $show_f
5123 printf "%4d %4d %p ", $x, $y, $sl
5132 printf "%p %p ", $mca, $mca->mca_addr
5133 mbuf_mca_ctype $mca 0
5134 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
5143 set $total = $total + 1
5146 printf "recent transaction for this buffer (thread %p):\n", \
5149 while $cnt < $mca->mca_depth
5150 set $kgm_pc = $mca->mca_stack[$cnt]
5151 printf "%4d: ", $cnt + 1
5159 set $mca = $mca->mca_next
5162 if $slg->slg_slab[$y].sl_base == 0
5168 if $total && $show_a && $show_f
5169 printf "\ntotal objects:\t%d\n", $total
5170 printf "active/unfreed:\t%d\n", $total_a
5171 printf "freed/in_cache:\t%d\n", $total_f
5175 document mbuf_walkallslabs
5176 | Walk the mbuf objects pool; this requires mbuf debugging to be
5177 | turned on, by setting the appropriate flags to the "mbuf_debug" boot-args
5178 | parameter. This is a backend routine for mbuf_show{active,inactive,all}.
5182 set $RTF_GATEWAY = 0x2
5184 set $RTF_REJECT = 0x8
5185 set $RTF_DYNAMIC = 0x10
5186 set $RTF_MODIFIED = 0x20
5187 set $RTF_DONE = 0x40
5188 set $RTF_DELCLONE = 0x80
5189 set $RTF_CLONING = 0x100
5190 set $RTF_XRESOLVE = 0x200
5191 set $RTF_LLINFO = 0x400
5192 set $RTF_STATIC = 0x800
5193 set $RTF_BLACKHOLE = 0x1000
5194 set $RTF_PROTO2 = 0x4000
5195 set $RTF_PROTO1 = 0x8000
5196 set $RTF_PRCLONING = 0x10000
5197 set $RTF_WASCLONED = 0x20000
5198 set $RTF_PROTO3 = 0x40000
5199 set $RTF_PINNED = 0x100000
5200 set $RTF_LOCAL = 0x200000
5201 set $RTF_BROADCAST = 0x400000
5202 set $RTF_MULTICAST = 0x800000
5203 set $RTF_IFSCOPE = 0x1000000
5204 set $RTF_CONDEMNED = 0x2000000
5210 define rtentry_prdetails
5211 set $rt = (struct rtentry *)$arg0
5214 set $dst = (struct sockaddr *)$rt->rt_nodes->rn_u.rn_leaf.rn_Key
5215 if $dst->sa_family == $AF_INET
5216 showsockaddr_in $dst
5219 if $dst->sa_family == $AF_INET6
5220 showsockaddr_in6 $dst
5224 if $dst->sa_family == $AF_LINK
5225 showsockaddr_dl $dst
5228 showsockaddr_unspec $dst
5233 set $dst = (struct sockaddr *)$rt->rt_gateway
5234 if $dst->sa_family == $AF_INET
5235 showsockaddr_in $dst
5238 if $dst->sa_family == $AF_INET6
5240 showsockaddr_in6 $dst
5243 if $dst->sa_family == $AF_LINK
5244 showsockaddr_dl $dst
5251 showsockaddr_unspec $dst
5256 if $rt->rt_flags & $RTF_WASCLONED
5258 printf "%18p ", $rt->rt_parent
5260 printf "%10p ", $rt->rt_parent
5270 printf "%6u %8u ", $rt->rt_refcnt, $rt->rt_rmx.rmx_pksent
5272 if $rt->rt_flags & $RTF_UP
5275 if $rt->rt_flags & $RTF_GATEWAY
5278 if $rt->rt_flags & $RTF_HOST
5281 if $rt->rt_flags & $RTF_REJECT
5284 if $rt->rt_flags & $RTF_DYNAMIC
5287 if $rt->rt_flags & $RTF_MODIFIED
5290 if $rt->rt_flags & $RTF_CLONING
5293 if $rt->rt_flags & $RTF_PRCLONING
5296 if $rt->rt_flags & $RTF_LLINFO
5299 if $rt->rt_flags & $RTF_STATIC
5302 if $rt->rt_flags & $RTF_PROTO1
5305 if $rt->rt_flags & $RTF_PROTO2
5308 if $rt->rt_flags & $RTF_PROTO3
5311 if $rt->rt_flags & $RTF_WASCLONED
5314 if $rt->rt_flags & $RTF_BROADCAST
5317 if $rt->rt_flags & $RTF_MULTICAST
5320 if $rt->rt_flags & $RTF_XRESOLVE
5323 if $rt->rt_flags & $RTF_BLACKHOLE
5326 if $rt->rt_flags & $RTF_IFSCOPE
5330 printf "/%s%d", $rt->rt_ifp->if_name, $rt->rt_ifp->if_unit
5335 define _rttable_dump
5337 set $rn = (struct radix_node *)$rnh->rnh_treetop
5338 set $rnh_cnt = $rnh->rnh_cnt
5340 while $rn->rn_bit >= 0
5341 set $rn = $rn->rn_u.rn_node.rn_L
5345 set $base = (struct radix_node *)$rn
5346 while ($rn->rn_parent->rn_u.rn_node.rn_R == $rn) && ($rn->rn_flags & $RNF_ROOT) == 0
5347 set $rn = $rn->rn_parent
5349 set $rn = $rn->rn_parent->rn_u.rn_node.rn_R
5350 while $rn->rn_bit >= 0
5351 set $rn = $rn->rn_u.rn_node.rn_L
5356 set $base = $rn->rn_u.rn_leaf.rn_Dupedkey
5357 if ($rn->rn_flags & $RNF_ROOT) == 0
5359 set $rt = (struct rtentry *)$rn
5366 rtentry_prdetails $rt
5372 if ($rn->rn_flags & $RNF_ROOT) != 0
5381 printf " rtentry dst gw parent Refs Use flags/if\n"
5382 printf " ----------------- --------------- ----------------- ------------------ ------ -------- -----------\n"
5384 printf " rtentry dst gw parent Refs Use flags/if\n"
5385 printf " --------- --------------- ----------------- ---------- ------ -------- -----------\n"
5387 _rttable_dump rt_tables[2]
5390 document show_rt_inet
5391 Syntax: (gdb) show_rt_inet
5392 | Show the entries of the IPv4 routing table.
5395 define show_rt_inet6
5397 printf " rtentry dst gw parent Refs Use flags/if\n"
5398 printf " ----------------- --------------------------------------- --------------------------------------- ------------------ ------ -------- -----------\n"
5400 printf " rtentry dst gw parent Refs Use flags/if\n"
5401 printf " --------- --------------------------------------- --------------------------------------- ---------- ------ -------- -----------\n"
5403 _rttable_dump rt_tables[30]
5406 document show_rt_inet6
5407 Syntax: (gdb) show_rt_inet6
5408 | Show the entries of the IPv6 routing table.
5411 define rtentry_trash
5412 set $rtd = (struct rtentry_dbg *)rttrash_head.tqh_first
5417 printf " rtentry ref hold rele dst gw parent flags/if\n"
5418 printf " ----------------- --- ------ ------ --------------- ----- ------------------ -----------\n"
5420 printf " rtentry ref hold rele dst gw parent flags/if\n"
5421 printf " --------- --- ------ ------ --------------- ----- ---------- -----------\n"
5424 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $rtd, \
5425 $rtd->rtd_refhold_cnt - $rtd->rtd_refrele_cnt, \
5426 $rtd->rtd_refhold_cnt, $rtd->rtd_refrele_cnt
5427 rtentry_prdetails $rtd
5429 set $rtd = $rtd->rtd_trash_link.tqe_next
5434 document rtentry_trash
5435 Syntax: (gdb) rtentry_trash
5436 | Walk the list of trash route entries; this requires route entry
5437 | debugging to be turned on, by setting the appropriate flags to the
5438 | "rte_debug" boot-args parameter.
5441 set $CTRACE_STACK_SIZE = ctrace_stack_size
5442 set $CTRACE_HIST_SIZE = ctrace_hist_size
5444 define rtentry_showdbg
5445 set $rtd = (struct rtentry_dbg *)$arg0
5448 printf "Total holds:\t%d\n", $rtd->rtd_refhold_cnt
5449 printf "Total releases:\t%d\n", $rtd->rtd_refrele_cnt
5452 while $ix < $CTRACE_STACK_SIZE
5453 set $kgm_pc = $rtd->rtd_alloc.pc[$ix]
5456 printf "\nAlloc (thread %p):\n", \
5459 printf "%4d: ", $ix + 1
5466 while $ix < $CTRACE_STACK_SIZE
5467 set $kgm_pc = $rtd->rtd_free.pc[$ix]
5470 printf "\nFree: (thread %p)\n", \
5473 printf "%4d: ", $ix + 1
5479 while $cnt < $CTRACE_HIST_SIZE
5481 while $ix < $CTRACE_STACK_SIZE
5482 set $kgm_pc = $rtd->rtd_refhold[$cnt].pc[$ix]
5485 printf "\nHold [%d] (thread %p):\n", \
5486 $cnt, $rtd->rtd_refhold[$cnt].th
5488 printf "%4d: ", $ix + 1
5497 while $cnt < $CTRACE_HIST_SIZE
5499 while $ix < $CTRACE_STACK_SIZE
5500 set $kgm_pc = $rtd->rtd_refrele[$cnt].pc[$ix]
5503 printf "\nRelease [%d] (thread %p):\n",\
5504 $cnt, $rtd->rtd_refrele[$cnt].th
5506 printf "%4d: ", $ix + 1
5515 printf "\nTotal locks:\t%d\n", $rtd->rtd_lock_cnt
5516 printf "Total unlocks:\t%d\n", $rtd->rtd_unlock_cnt
5519 while $cnt < $CTRACE_HIST_SIZE
5521 while $ix < $CTRACE_STACK_SIZE
5522 set $kgm_pc = $rtd->rtd_lock[$cnt].pc[$ix]
5525 printf "\nLock [%d] (thread %p):\n",\
5526 $cnt, $rtd->rtd_lock[$cnt].th
5528 printf "%4d: ", $ix + 1
5537 while $cnt < $CTRACE_HIST_SIZE
5539 while $ix < $CTRACE_STACK_SIZE
5540 set $kgm_pc = $rtd->rtd_unlock[$cnt].pc[$ix]
5543 printf "\nUnlock [%d] (thread %p):\n",\
5544 $cnt, $rtd->rtd_unlock[$cnt].th
5546 printf "%4d: ", $ix + 1
5556 document rtentry_showdbg
5557 Syntax: (gdb) rtentry_showdbg <addr>
5558 | Given a route entry structure address, print the debug information
5559 | related to it. This requires route entry debugging to be turned
5560 | on, by setting the appropriate flags to the "rte_debug" boot-args
5564 define inifa_showdbg
5565 set $inifa = (struct in_ifaddr_dbg *)$arg0
5568 printf "Total holds:\t%d\n", $inifa->inifa_refhold_cnt
5569 printf "Total releases:\t%d\n", $inifa->inifa_refrele_cnt
5572 while $ix < $CTRACE_STACK_SIZE
5573 set $kgm_pc = $inifa->inifa_alloc.pc[$ix]
5576 printf "\nAlloc (thread %p):\n", \
5577 $inifa->inifa_alloc.th
5579 printf "%4d: ", $ix + 1
5586 while $ix < $CTRACE_STACK_SIZE
5587 set $kgm_pc = $inifa->inifa_free.pc[$ix]
5590 printf "\nFree: (thread %p)\n", \
5591 $inifa->inifa_free.th
5593 printf "%4d: ", $ix + 1
5599 while $cnt < $CTRACE_HIST_SIZE
5601 while $ix < $CTRACE_STACK_SIZE
5602 set $kgm_pc = $inifa->inifa_refhold[$cnt].pc[$ix]
5605 printf "\nHold [%d] (thread %p):\n", \
5606 $cnt, $inifa->inifa_refhold[$cnt].th
5608 printf "%4d: ", $ix + 1
5617 while $cnt < $CTRACE_HIST_SIZE
5619 while $ix < $CTRACE_STACK_SIZE
5620 set $kgm_pc = $inifa->inifa_refrele[$cnt].pc[$ix]
5623 printf "\nRelease [%d] (thread %p):\n",\
5624 $cnt, $inifa->inifa_refrele[$cnt].th
5626 printf "%4d: ", $ix + 1
5636 document inifa_showdbg
5637 Syntax: (gdb) inifa_showdbg <addr>
5638 | Given an IPv4 interface structure address, print the debug information
5639 | related to it. This requires interface address debugging to be turned
5640 | on, by setting the appropriate flags to the "ifa_debug" boot-args
5644 define in6ifa_showdbg
5645 set $in6ifa = (struct in6_ifaddr_dbg *)$arg0
5648 printf "Total holds:\t%d\n", $in6ifa->in6ifa_refhold_cnt
5649 printf "Total releases:\t%d\n", $in6ifa->in6ifa_refrele_cnt
5652 while $ix < $CTRACE_STACK_SIZE
5653 set $kgm_pc = $in6ifa->in6ifa_alloc.pc[$ix]
5656 printf "\nAlloc (thread %p):\n", \
5657 $in6ifa->in6ifa_alloc.th
5659 printf "%4d: ", $ix + 1
5666 while $ix < $CTRACE_STACK_SIZE
5667 set $kgm_pc = $in6ifa->in6ifa_free.pc[$ix]
5670 printf "\nFree: (thread %p)\n", \
5671 $in6ifa->in6ifa_free.th
5673 printf "%4d: ", $ix + 1
5679 while $cnt < $CTRACE_HIST_SIZE
5681 while $ix < $CTRACE_STACK_SIZE
5682 set $kgm_pc = $in6ifa->in6ifa_refhold[$cnt].pc[$ix]
5685 printf "\nHold [%d] (thread %p):\n", \
5686 $cnt, $in6ifa->in6ifa_refhold[$cnt].th
5688 printf "%4d: ", $ix + 1
5697 while $cnt < $CTRACE_HIST_SIZE
5699 while $ix < $CTRACE_STACK_SIZE
5700 set $kgm_pc = $in6ifa->in6ifa_refrele[$cnt].pc[$ix]
5703 printf "\nRelease [%d] (thread %p):\n",\
5704 $cnt, $in6ifa->in6ifa_refrele[$cnt].th
5706 printf "%4d: ", $ix + 1
5716 document in6ifa_showdbg
5717 Syntax: (gdb) in6ifa_showdbg <addr>
5718 | Given an IPv6 interface structure address, print the debug information
5719 | related to it. This requires interface address debugging to be turned
5720 | on, by setting the appropriate flags to the "ifa_debug" boot-args
5725 # print all OSMalloc stats
5728 set $kgm_tagp = (OSMallocTag)$arg0
5729 printf "0x%08x: ", $kgm_tagp
5730 printf "%8d ",$kgm_tagp->OSMT_refcnt
5731 printf "%8x ",$kgm_tagp->OSMT_state
5732 printf "%8x ",$kgm_tagp->OSMT_attr
5733 printf "%s ",$kgm_tagp->OSMT_name
5739 printf "TAG COUNT STATE ATTR NAME\n"
5740 set $kgm_tagheadp = (OSMallocTag)&OSMalloc_tag_list
5741 set $kgm_tagptr = (OSMallocTag )($kgm_tagheadp->OSMT_link.next)
5742 while $kgm_tagptr != $kgm_tagheadp
5743 ostag_print $kgm_tagptr
5744 set $kgm_tagptr = (OSMallocTag)$kgm_tagptr->OSMT_link.next
5748 document showosmalloc
5749 Syntax: (gdb) showosmalloc
5750 | Print the outstanding allocation count by OSMallocTags.
5755 if msgbufp->msg_bufc[msgbufp->msg_bufx] == 0
5756 # The buffer hasn't wrapped, so take the easy (and fast!) path
5757 printf "%s", msgbufp->msg_bufc
5759 set $kgm_msgbuf = *msgbufp
5760 set $kgm_syslog_bufsize = $kgm_msgbuf.msg_size
5761 set $kgm_syslog_bufend = $kgm_msgbuf.msg_bufx
5762 if $kgm_syslog_bufend >= $kgm_syslog_bufsize
5763 set $kgm_syslog_bufend = 0
5766 # print older messages from msg_bufx to end of buffer
5767 set $kgm_i = $kgm_syslog_bufend
5768 while $kgm_i < $kgm_syslog_bufsize
5769 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
5770 if $kgm_syslog_char == 0
5772 set $kgm_i = $kgm_syslog_bufsize
5774 printf "%c", $kgm_syslog_char
5776 set $kgm_i = $kgm_i + 1
5779 # print newer messages from start of buffer to msg_bufx
5781 while $kgm_i < $kgm_syslog_bufend
5782 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
5783 printf "%c", $kgm_syslog_char
5784 set $kgm_i = $kgm_i + 1
5791 | Display the kernel's printf ring buffer
5796 set $kgm_addr = (unsigned char *)$arg0
5797 set $kgm_len = $arg1
5803 printf "%02x ", *($kgm_addr+$kgm_i)
5809 set $kgm_temp = *($kgm_addr+$kgm_i)
5810 if $kgm_temp < 32 || $kgm_temp >= 127
5813 printf "%c", $kgm_temp
5823 | Show the contents of memory as a hex/ASCII dump
5824 | The following is the syntax:
5825 | (gdb) hexdump <address> <length>
5829 define printcolonhex
5834 while ($li < $count)
5836 printf "%02x", (u_char)$addr[$li]
5839 printf ":%02x", (u_char)$addr[$li]
5846 define showsockaddr_dl
5847 set $sdl = (struct sockaddr_dl *)$arg0
5851 if $sdl->sdl_nlen == 0 && $sdl->sdl_alen == 0 && $sdl->sdl_slen == 0
5852 printf "link#%3d ", $sdl->sdl_index
5854 set $addr = $sdl->sdl_data + $sdl->sdl_nlen
5855 set $count = $sdl->sdl_alen
5856 printcolonhex $addr $count
5861 define showsockaddr_unspec
5862 set $sockaddr = (struct sockaddr *)$arg0
5863 set $addr = $sockaddr->sa_data
5864 set $count = $sockaddr->sa_len - 2
5865 printcolonhex $addr $count
5868 define showsockaddr_at
5869 set $sockaddr = (struct sockaddr *)$arg0
5870 set $addr = $sockaddr->sa_data
5871 set $count = $sockaddr->sa_len - 2
5872 printcolonhex $addr $count
5875 define showsockaddr_in
5876 set $sin = (struct sockaddr_in *)$arg0
5877 set $sa_bytes = (unsigned char *)&($sin->sin_addr)
5878 printf "%3u.%03u.%03u.%03u", $sa_bytes[0], $sa_bytes[1], $sa_bytes[2], $sa_bytes[3]
5881 define showsockaddr_in6
5882 set $sin6 = (struct sockaddr_in6 *)$arg0
5883 set $sa_bytes = $sin6->sin6_addr.__u6_addr.__u6_addr8
5884 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
5885 $sa_bytes[0], $sa_bytes[1], $sa_bytes[2], $sa_bytes[3], $sa_bytes[4], $sa_bytes[5], $sa_bytes[6], $sa_bytes[7], $sa_bytes[8], $sa_bytes[9], $sa_bytes[10], $sa_bytes[11], $sa_bytes[12], $sa_bytes[13], $sa_bytes[14], $sa_bytes[15]
5888 define showsockaddr_un
5889 set $sun = (struct sockaddr_un *)$arg0
5893 if $sun->sun_path[0] == 0
5896 printf "%s", $sun->sun_path
5901 define showifmultiaddrs
5902 set $ifp = (struct ifnet *)$arg0
5903 set $if_multi = (struct ifmultiaddr *)$ifp->if_multiaddrs->lh_first
5904 set $mymulti = $if_multi
5906 while ($mymulti != 0)
5907 printf "%2d. ", $myi
5908 set $sa_family = $mymulti->ifma_addr.sa_family
5909 if ($sa_family == 2)
5910 if ($mymulti->ifma_ll != 0)
5911 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
5914 showsockaddr_in $mymulti->ifma_addr
5916 if ($sa_family == 30)
5917 if ($mymulti->ifma_ll != 0)
5918 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
5921 showsockaddr_in6 $mymulti->ifma_addr
5923 if ($sa_family == 18)
5924 showsockaddr_dl $mymulti->ifma_addr
5926 if ($sa_family == 0)
5927 showsockaddr_unspec $mymulti->ifma_addr 6
5929 printf " [%d]", $mymulti->ifma_refcount
5931 set $mymulti = $mymulti->ifma_link.le_next
5936 document showifmultiaddrs
5937 Syntax showifmultiaddrs <ifp>
5938 | show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
5942 set $mysock = (struct sockaddr *)$arg0
5943 set $showsockaddr_handled = 0
5947 if ($mysock->sa_family == 0)
5949 showsockaddr_unspec $mysock
5950 set $showsockaddr_handled = 1
5952 if ($mysock->sa_family == 1)
5954 showsockaddr_un $mysock
5955 set $showsockaddr_handled = 1
5957 if ($mysock->sa_family == 2)
5959 showsockaddr_in $mysock
5960 set $showsockaddr_handled = 1
5962 if ($mysock->sa_family == 30)
5964 showsockaddr_in6 $mysock
5965 set $showsockaddr_handled = 1
5967 if ($mysock->sa_family == 18)
5969 showsockaddr_dl $mysock
5970 set $showsockaddr_handled = 1
5972 if ($mysock->sa_family == 16)
5974 showsockaddr_at $mysock
5975 set $showsockaddr_handled = 1
5977 if ($showsockaddr_handled == 0)
5978 printf "FAM %d ", $mysock->sa_family
5979 set $addr = $mysock->sa_data
5980 set $count = $mysock->sa_len
5981 printcolonhex $addr $count
5987 set $flags = (u_short)$arg0
6019 printf "POINTTOPOINT"
6021 # if ($flags & 0x20)
6027 # printf "NOTRAILERS"
6077 if ($flags & 0x1000)
6085 if ($flags & 0x2000)
6093 if ($flags & 0x4000)
6099 printf "LINK2-ALTPHYS"
6101 if ($flags & 0x8000)
6113 set $ifp = (struct ifnet *)$arg0
6114 set $myifaddr = (struct ifaddr *)$ifp->if_addrhead->tqh_first
6116 while ($myifaddr != 0)
6117 printf "\t%d. ", $myi
6118 showsockaddr $myifaddr->ifa_addr
6119 printf " [%d]\n", $myifaddr->ifa_refcnt
6120 set $myifaddr = $myifaddr->ifa_link->tqe_next
6125 document showifaddrs
6126 Syntax: showifaddrs <ifp>
6127 | show the (struct ifnet).if_addrhead list of addresses for the given ifp
6131 set $ifconfig_all = 0
6133 set $ifconfig_all = 1
6135 set $ifp = (struct ifnet *)(ifnet->tqh_first)
6137 printf "%s%d: flags=%hx", $ifp->if_name, $ifp->if_unit, (u_short)$ifp->if_flags
6138 showifflags $ifp->if_flags
6139 printf " index %d", $ifp->if_index
6140 printf " mtu %d\n", $ifp->if_data.ifi_mtu
6141 printf "\t(struct ifnet *)"
6144 if ($ifconfig_all == 1)
6147 set $ifp = $ifp->if_link->tqe_next
6151 Syntax: (gdb) ifconfig
6152 | display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
6155 define _show_unix_domain_socket
6156 set $so = (struct socket *)$arg0
6157 set $pcb = (struct unpcb *)$so->so_pcb
6159 printf "unpcb: (null) "
6161 printf "unpcb: %p ", $pcb
6162 printf "unp_vnode: %p ", $pcb->unp_vnode
6163 printf "unp_conn: %p ", $pcb->unp_conn
6165 showsockaddr_un $pcb->unp_addr
6169 define _show_in_port
6170 set $str = (unsigned char *)$arg0
6171 set $port = *(unsigned short *)$arg0
6173 if (((($port & 0xff00) >> 8) == $str[0])) && ((($port & 0x00ff) == $str[1]))
6174 #printf "big endian "
6175 printf ":%d ", $port
6177 #printf "little endian "
6178 printf ":%d ", (($port & 0xff00) >> 8) | (($port & 0x00ff) << 8)
6182 define _show_in_addr_4in6
6183 set $ia = (unsigned char *)$arg0
6185 printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
6189 define _show_in6_addr
6190 set $ia = (unsigned char *)$arg0
6192 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
6193 $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], \
6194 $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
6198 define _showtcpstate
6199 set $tp = (struct tcpcb *)$arg0
6201 if $tp->t_state == 0
6204 if $tp->t_state == 1
6207 if $tp->t_state == 2
6210 if $tp->t_state == 3
6213 if $tp->t_state == 4
6214 printf "ESTABLISHED "
6216 if $tp->t_state == 5
6217 printf "CLOSE_WAIT "
6219 if $tp->t_state == 6
6220 printf "FIN_WAIT_1 "
6222 if $tp->t_state == 7
6225 if $tp->t_state == 8
6228 if $tp->t_state == 9
6229 printf "FIN_WAIT_2 "
6231 if $tp->t_state == 10
6237 define _showsockprotocol
6238 set $so = (struct socket *)$arg0
6239 set $inpcb = (struct inpcb *)$so->so_pcb
6241 if $so->so_proto->pr_protocol == 6
6243 _showtcpstate $inpcb->inp_ppcb
6245 if $so->so_proto->pr_protocol == 17
6248 if $so->so_proto->pr_protocol == 1
6251 if $so->so_proto->pr_protocol == 254
6254 if $so->so_proto->pr_protocol == 255
6259 define _show_ipv4_socket
6260 set $so = (struct socket *)$arg0
6261 set $inpcb = (struct inpcb *)$so->so_pcb
6263 printf "inpcb: (null) "
6265 printf "inpcb: %p ", $inpcb
6267 _showsockprotocol $so
6269 _show_in_addr_4in6 &$inpcb->inp_dependladdr.inp46_local
6270 _show_in_port &$inpcb->inp_lport
6272 _show_in_addr_4in6 &$inpcb->inp_dependfaddr.inp46_foreign
6273 _show_in_port &$inpcb->inp_fport
6277 define _show_ipv6_socket
6278 set $so = (struct socket *)$arg0
6279 set $pcb = (struct inpcb *)$so->so_pcb
6281 printf "inpcb: (null) "
6283 printf "inpcb: %p ", $pcb
6285 _showsockprotocol $so
6287 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
6288 _show_in_port &$pcb->inp_lport
6290 _show_in6_addr &$pcb->inp_dependfaddr.inp6_foreign
6291 _show_in_port &$pcb->inp_fport
6297 set $so = (struct socket *)$arg0
6299 printf "so: (null) "
6301 printf "so: %p ", $so
6302 if $so && $so->so_proto && $so->so_proto->pr_domain
6303 set $domain = (struct domain *) $so->so_proto->pr_domain
6305 printf "%s ", $domain->dom_name
6306 if $domain->dom_family == 1
6307 _show_unix_domain_socket $so
6309 if $domain->dom_family == 2
6310 _show_ipv4_socket $so
6312 if $domain->dom_family == 30
6313 _show_ipv6_socket $so
6320 Syntax: (gdb) showsocket <socket_address>
6321 | Routine to print out a socket
6324 define showprocsockets
6325 set $pp = (struct proc *)$arg0
6326 set $fdp = (struct filedesc *)$pp->p_fd
6329 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
6330 set $fpo = (char)($fdp->fd_ofileflags[0])
6331 while $count < $fdp->fd_nfiles
6333 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
6334 if $fg && (($fg)->fg_type == 2)
6335 if $fdp->fd_ofileflags[$count] & 4
6340 printf "fd = %d ", $count
6342 showsocket $fg->fg_data
6349 set $count = $count + 1
6352 document showprocsockets
6353 Syntax: (gdb) showprocsockets <proc_address>
6354 | Routine to print out all the open fds
6355 | which are sockets in a process
6358 define showallprocsockets
6359 set $basep = (struct proc *)allproc->lh_first
6362 printf "============================================ \n"
6365 set $pp = $pp->p_list.le_next
6368 document showallprocsockets
6369 Syntax: (gdb) showallprocsockets
6370 | Routine to print out all the open fds
6375 set $port = (unsigned short)$arg0
6376 set $port = (unsigned short)((($arg0 & 0xff00) >> 8) & 0xff)
6377 set $port |= (unsigned short)(($arg0 & 0xff) << 8)
6381 set $INPCB_STATE_INUSE=0x1
6382 set $INPCB_STATE_CACHED=0x2
6383 set $INPCB_STATE_DEAD=0x3
6385 set $INP_RECVOPTS=0x01
6386 set $INP_RECVRETOPTS=0x02
6387 set $INP_RECVDSTADDR=0x04
6388 set $INP_HDRINCL=0x08
6389 set $INP_HIGHPORT=0x10
6390 set $INP_LOWPORT=0x20
6391 set $INP_ANONPORT=0x40
6392 set $INP_RECVIF=0x80
6393 set $INP_MTUDISC=0x100
6394 set $INP_STRIPHDR=0x200
6395 set $INP_FAITH=0x400
6396 set $INP_INADDR_ANY=0x800
6397 set $INP_RECVTTL=0x1000
6398 set $INP_UDP_NOCKSUM=0x2000
6399 set $IN6P_IPV6_V6ONLY=0x008000
6400 set $IN6P_PKTINFO=0x010000
6401 set $IN6P_HOPLIMIT=0x020000
6402 set $IN6P_HOPOPTS=0x040000
6403 set $IN6P_DSTOPTS=0x080000
6404 set $IN6P_RTHDR=0x100000
6405 set $IN6P_RTHDRDSTOPTS=0x200000
6406 set $IN6P_AUTOFLOWLABEL=0x800000
6407 set $IN6P_BINDV6ONLY=0x10000000
6416 set $pcb = (struct inpcb *)$arg0
6420 printf "%10p ", $pcb
6422 if $arg1 == $IPPROTO_TCP
6425 if $arg1 == $IPPROTO_UDP
6428 printf "%2d.", $arg1
6431 if ($pcb->inp_vflag & $INP_IPV4)
6434 if ($pcb->inp_vflag & $INP_IPV6)
6438 if ($pcb->inp_vflag & $INP_IPV4)
6440 _show_in_addr &$pcb->inp_dependladdr.inp46_local.ia46_addr4
6442 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
6445 _print_ntohs $pcb->inp_lport
6447 if ($pcb->inp_vflag & $INP_IPV4)
6449 _show_in_addr &($pcb->inp_dependfaddr.inp46_foreign.ia46_addr4)
6451 _show_in6_addr &($pcb->inp_dependfaddr.inp6_foreign)
6454 _print_ntohs $pcb->inp_fport
6457 if $arg1 == $IPPROTO_TCP
6458 _showtcpstate $pcb->inp_ppcb
6462 # set $phd = $pcb->inp_phd
6465 # _print_ntohs $phd->phd_port
6466 # set $phd = $phd->phd_hash.le_next
6469 if ($pcb->inp_flags & $INP_RECVOPTS)
6472 if ($pcb->inp_flags & $INP_RECVRETOPTS)
6473 printf "recvretopts "
6475 if ($pcb->inp_flags & $INP_RECVDSTADDR)
6476 printf "recvdstaddr "
6478 if ($pcb->inp_flags & $INP_HDRINCL)
6481 if ($pcb->inp_flags & $INP_HIGHPORT)
6484 if ($pcb->inp_flags & $INP_LOWPORT)
6487 if ($pcb->inp_flags & $INP_ANONPORT)
6490 if ($pcb->inp_flags & $INP_RECVIF)
6493 if ($pcb->inp_flags & $INP_MTUDISC)
6496 if ($pcb->inp_flags & $INP_STRIPHDR)
6499 if ($pcb->inp_flags & $INP_FAITH)
6502 if ($pcb->inp_flags & $INP_INADDR_ANY)
6503 printf "inaddr_any "
6505 if ($pcb->inp_flags & $INP_RECVTTL)
6508 if ($pcb->inp_flags & $INP_UDP_NOCKSUM)
6511 if ($pcb->inp_flags & $IN6P_IPV6_V6ONLY)
6514 if ($pcb->inp_flags & $IN6P_PKTINFO)
6517 if ($pcb->inp_flags & $IN6P_HOPLIMIT)
6520 if ($pcb->inp_flags & $IN6P_HOPOPTS)
6523 if ($pcb->inp_flags & $IN6P_DSTOPTS)
6526 if ($pcb->inp_flags & $IN6P_RTHDR)
6529 if ($pcb->inp_flags & $IN6P_RTHDRDSTOPTS)
6530 printf "rthdrdstopts "
6532 if ($pcb->inp_flags & $IN6P_AUTOFLOWLABEL)
6533 printf "autoflowlabel "
6535 if ($pcb->inp_flags & $IN6P_BINDV6ONLY)
6536 printf "bindv6only "
6538 set $so = (struct socket *)$pcb->inp_socket
6540 printf "[so=%p s=%ld r=%ld usecnt=%ld] ", $so, $so->so_snd.sb_cc, \
6541 $so->so_rcv.sb_cc, $so->so_usecount
6543 if ($pcb->inp_state == 0 || $pcb->inp_state == $INPCB_STATE_INUSE)
6546 if ($pcb->inp_state == $INPCB_STATE_CACHED)
6549 if ($pcb->inp_state == $INPCB_STATE_DEAD)
6552 printf "unknown (%d), ", $pcb->inp_state
6558 define _dump_inpcbport
6559 set $ppcb = (struct inpcbport *)$arg0
6560 printf "%p: lport ", $ppcb
6561 _print_ntohs $ppcb->phd_port
6566 define _dump_pcbinfo
6570 set $pcbi = (struct inpcbinfo *)$arg0
6571 printf "lastport %d lastlow %d lasthi %d\n", \
6572 $pcbi->lastport, $pcbi->lastlow, $pcbi->lasthi
6573 printf "active pcb count is %d\n", $pcbi->ipi_count
6574 set $hashsize = $pcbi->hashmask + 1
6575 printf "hash size is %d\n", $hashsize
6576 printf "hash base %p has the following inpcb(s):\n", $pcbi->hashbase
6578 printf "pcb prot source address port destination address port\n"
6579 printf "------------------ ---- --------------------------------------- ----- --------------------------------------- -----\n"
6581 printf "pcb prot source address port destination address port\n"
6582 printf "---------- ---- --------------------------------------- ----- --------------------------------------- -----\n"
6585 set $hashbase = $pcbi->hashbase
6586 set $head = *(uintptr_t *)$hashbase
6587 while $i < $hashsize
6589 set $pcb0 = (struct inpcb *)$head
6592 _dump_inpcb $pcb0 $arg1
6593 set $so = (struct socket *)$pcb->inp_socket
6595 set $snd_cc += $so->so_snd.sb_cc
6596 set $rcv_cc += $so-> so_rcv.sb_cc
6598 set $pcb0 = $pcb0->inp_hash.le_next
6604 set $head = *(uintptr_t *)$hashbase
6606 printf "total seen %ld snd_cc %ld rcv_cc %ld\n", $pcbseen, $snd_cc, $rcv_cc
6607 printf "port hash base is %p\n", $pcbi->porthashbase
6609 set $hashbase = $pcbi->porthashbase
6610 set $head = *(uintptr_t *)$hashbase
6611 while $i < $hashsize
6613 set $pcb0 = (struct inpcbport *)$head
6616 _dump_inpcbport $pcb0
6618 set $pcb0 = $pcb0->phd_hash.le_next
6623 set $head = *(uintptr_t *)$hashbase
6627 set $N_TIME_WAIT_SLOTS=128
6629 define show_tcp_timewaitslots
6636 set $slot = (int)$arg0
6639 printf "time wait slot size %d cur_tw_slot %ld\n", $N_TIME_WAIT_SLOTS, cur_tw_slot
6641 while $i < $N_TIME_WAIT_SLOTS
6643 set $head = (uintptr_t *)time_wait_slots[$i]
6644 if $i == $slot || $slot == -1
6646 set $pcb0 = (struct inpcb *)$head
6649 set $pcb0 = $pcb0->inp_list.le_next
6652 printf " slot %ld count %ld\n", $i, $perslot
6654 if $all || $i == $slot
6656 set $pcb0 = (struct inpcb *)$head
6659 _dump_inpcb $pcb0 $IPPROTO_TCP
6661 set $pcb0 = $pcb0->inp_list.le_next
6668 document show_tcp_timewaitslots
6669 Syntax: (gdb) show_tcp_timewaitslots
6670 | Print the list of TCP protocol control block in the TIMEWAIT state
6671 | Pass -1 to see the list of PCB for each slot
6672 | Pass a slot number to see information for that slot with the list of PCB
6675 define show_tcp_pcbinfo
6676 _dump_pcbinfo &tcbinfo $IPPROTO_TCP
6678 document show_tcp_pcbinfo
6679 Syntax: (gdb) show_tcp_pcbinfo
6680 | Print the list of TCP protocol control block information
6684 define show_udp_pcbinfo
6685 _dump_pcbinfo &udbinfo $IPPROTO_UDP
6687 document show_udp_pcbinfo
6688 Syntax: (gdb) show_udp_pcbinfo
6689 | Print the list of UDP protocol control block information
6694 while ($myi < bpf_dtab_size)
6695 if (bpf_dtab[$myi] != 0)
6696 printf "Address 0x%x, bd_next 0x%x\n", bpf_dtab[$myi], bpf_dtab[$myi]->bd_next
6697 print *bpf_dtab[$myi]
6703 define printvnodepathint_recur
6705 if ($arg0->v_flag & 0x000001) && ($arg0->v_mount != 0)
6706 if $arg0->v_mount->mnt_vnodecovered != 0
6707 printvnodepathint_recur $arg0->v_mount->mnt_vnodecovered $arg0->v_mount->mnt_vnodecovered->v_name
6710 printvnodepathint_recur $arg0->v_parent $arg0->v_parent->v_name
6716 define showvnodepath
6717 set $vp = (struct vnode *)$arg0
6719 if ($vp->v_flag & 0x000001) && ($vp->v_mount != 0) && ($vp->v_mount->mnt_flag & 0x00004000)
6722 printvnodepathint_recur $vp $vp->v_name
6728 document showvnodepath
6729 Syntax: (gdb) showvnodepath <vnode>
6730 | Prints the path for a vnode
6738 printf " mnt_devvp "
6740 printf " typename mountpoint\n"
6741 set $kgm_vol = (mount_t) mountlist.tqh_first
6745 showptr $kgm_vol->mnt_data
6747 showptr $kgm_vol->mnt_devvp
6749 if ($kgm_vol->mnt_vtable->vfc_name[0] == 'h') && \
6750 ($kgm_vol->mnt_vtable->vfc_name[1] == 'f') && \
6751 ($kgm_vol->mnt_vtable->vfc_name[2] == 's') && \
6752 ($kgm_vol->mnt_vtable->vfc_name[3] == '\0')
6753 set $kgm_hfsmount = \
6754 (struct hfsmount *) $kgm_vol->mnt_data
6755 if $kgm_hfsmount->hfs_freezing_proc != 0
6756 printf "FROZEN hfs "
6761 printf "%-10s ", $kgm_vol->mnt_vtable->vfc_name
6763 printf "%s\n", $kgm_vol->mnt_vfsstat.f_mntonname
6765 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6769 document showallvols
6770 Syntax: (gdb) showallvols
6771 | Display a summary of mounted volumes
6774 define showvnodeheader
6777 printf " usecount iocount v_data "
6779 printf " vtype parent "
6785 set $kgm_vnode = (vnode_t) $arg0
6787 printf " %8d ", $kgm_vnode->v_usecount
6788 printf "%7d ", $kgm_vnode->v_iocount
6789 # print information about clean/dirty blocks?
6790 showptr $kgm_vnode->v_data
6792 # print the vtype, using the enum tag
6793 set $kgm_vtype = $kgm_vnode->v_type
6794 if $kgm_vtype == VNON
6797 if $kgm_vtype == VREG
6800 if $kgm_vtype == VDIR
6803 if $kgm_vtype == VBLK
6806 if $kgm_vtype == VCHR
6809 if $kgm_vtype == VLNK
6812 if $kgm_vtype == VSOCK
6815 if $kgm_vtype == VFIFO
6818 if $kgm_vtype == VBAD
6821 if ($kgm_vtype < VNON) || ($kgm_vtype > VBAD)
6822 printf "%5d ", $kgm_vtype
6825 showptr $kgm_vnode->v_parent
6827 if $kgm_vnode->v_name != 0
6828 printf "%s\n", $kgm_vnode->v_name
6840 Syntax: (gdb) showvnode <vnode>
6841 | Display info about one vnode
6844 define showvolvnodes
6846 set $kgm_vol = (mount_t) $arg0
6847 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6849 showvnodeint $kgm_vnode
6850 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6854 document showvolvnodes
6855 Syntax: (gdb) showvolvnodes <mouont_t>
6856 | Display info about all vnodes of a given mount_t
6859 define showvolbusyvnodes
6861 set $kgm_vol = (mount_t) $arg0
6862 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6864 if $kgm_vnode->v_iocount != 0
6865 showvnodeint $kgm_vnode
6867 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6871 document showvolbusyvnodes
6872 Syntax: (gdb) showvolbusyvnodes <mount_t>
6873 | Display info about busy (iocount!=0) vnodes of a given mount_t
6876 define showallbusyvnodes
6878 set $kgm_vol = (mount_t) mountlist.tqh_first
6880 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6882 if $kgm_vnode->v_iocount != 0
6883 showvnodeint $kgm_vnode
6885 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6887 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6891 document showallbusyvnodes
6892 Syntax: (gdb) showallbusyvnodes <vnode>
6893 | Display info about all busy (iocount!=0) vnodes
6896 define showallvnodes
6898 set $kgm_vol = (mount_t) mountlist.tqh_first
6900 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6902 showvnodeint $kgm_vnode
6903 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6905 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6909 document showallvnodes
6910 Syntax: (gdb) showallvnodes
6911 | Display info about all vnodes
6914 define _showvnodelockheader
6915 printf "* type W held by lock type start end\n"
6916 printf "- ----- - ------------- --------- ------------------ ------------------\n"
6919 define _showvnodelock
6920 set $kgm_svl_lock = ((struct lockf *)$arg0)
6923 set $kgm_svl_flags = $kgm_svl_lock->lf_flags
6924 set $kgm_svl_type = $kgm_svl_lock->lf_type
6925 if ($kgm_svl_flags & 0x20)
6928 if ($kgm_svl_flags & 0x40)
6931 if ($kgm_svl_flags & 0x80)
6934 if ($kgm_svl_flags & 0x10)
6940 # POSIX file vs. advisory range locks
6941 if ($kgm_svl_flags & 0x40)
6942 set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id
6943 printf "PID %8d ", $kgm_svl_proc->p_pid
6945 printf "ID 0x%08x ", $kgm_svl_lock->lf_id
6949 if ($kgm_svl_type == 1)
6952 if ($kgm_svl_type == 3)
6955 if ($kgm_svl_type == 2)
6964 printf "0x%016x..", $kgm_svl_lock->lf_start
6965 printf "0x%016x ", $kgm_svl_lock->lf_end
6968 # Body of showvnodelocks, not including header
6969 define _showvnodelocks
6970 set $kgm_svl_vnode = ((vnode_t)$arg0)
6971 set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf
6972 while ($kgm_svl_lockiter != 0)
6973 # locks that are held
6975 _showvnodelock $kgm_svl_lockiter
6977 # and any locks blocked by them
6978 set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first
6979 while ($kgm_svl_blocker != 0)
6981 _showvnodelock $kgm_svl_blocker
6982 set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next
6985 # and on to the next one...
6986 set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next
6991 define showvnodelocks
6993 _showvnodelockheader
6994 _showvnodelocks $arg0
6996 printf "| Usage:\n|\n"
7001 document showvnodelocks
7002 Syntax: (gdb) showvnodelocks <vnode_t>
7003 | Given a vnodet pointer, display the list of advisory record locks for the
7004 | referenced pvnodes
7008 printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
7011 document showbootargs
7012 Syntax: showbootargs
7013 | Display boot arguments passed to the target kernel
7016 define showbootermemorymap
7017 if ($kgm_mtype == $kgm_mtype_i386)
7018 set $kgm_voffset = 0
7020 if ($kgm_mtype == $kgm_mtype_x86_64)
7021 set $kgm_voffset = 0xFFFFFF8000000000ULL
7023 echo showbootermemorymap not supported on this architecture
7027 set $kgm_boot_args = kernelBootArgs
7028 set $kgm_msize = kernelBootArgs->MemoryMapDescriptorSize
7029 set $kgm_mcount = kernelBootArgs->MemoryMapSize / $kgm_msize
7032 printf "Type Physical Start Number of Pages Virtual Start Attributes\n"
7033 while $kgm_i < $kgm_mcount
7034 set $kgm_mptr = (EfiMemoryRange *)((unsigned long)kernelBootArgs->MemoryMap + $kgm_voffset + $kgm_i * $kgm_msize)
7036 if $kgm_mptr->Type == 0
7039 if $kgm_mptr->Type == 1
7042 if $kgm_mptr->Type == 2
7045 if $kgm_mptr->Type == 3
7048 if $kgm_mptr->Type == 4
7051 if $kgm_mptr->Type == 5
7054 if $kgm_mptr->Type == 6
7057 if $kgm_mptr->Type == 7
7060 if $kgm_mptr->Type == 8
7063 if $kgm_mptr->Type == 9
7066 if $kgm_mptr->Type == 10
7069 if $kgm_mptr->Type == 11
7072 if $kgm_mptr->Type == 12
7075 if $kgm_mptr->Type == 13
7078 if $kgm_mptr->Type > 13
7082 printf " %016llx %016llx", $kgm_mptr->PhysicalStart, $kgm_mptr->NumberOfPages
7083 if $kgm_mptr->VirtualStart != 0
7084 printf " %016llx", $kgm_mptr->VirtualStart
7088 printf " %016llx\n", $kgm_mptr->Attribute
7089 set $kgm_i = $kgm_i + 1
7093 document showbootermemorymap
7094 Syntax: (gdb) showbootermemorymap
7095 | Prints out the phys memory map from kernelBootArgs
7099 define showstacksaftertask
7100 set $kgm_head_taskp = &default_pset.tasks
7101 set $kgm_taskp = (struct task *)$arg0
7102 while $kgm_taskp != $kgm_head_taskp
7104 showtaskint $kgm_taskp
7105 set $kgm_head_actp = &($kgm_taskp->threads)
7106 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
7107 while $kgm_actp != $kgm_head_actp
7109 if ($decode_wait_events > 0)
7110 showactint $kgm_actp 1
7112 showactint $kgm_actp 2
7114 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
7117 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
7120 document showstacksaftertask
7121 Syntax: (gdb) showstacksaftertask <task>
7122 | Routine to print out all stacks (as in showallstacks) starting after a given task
7123 | Useful if that gdb refuses to print a certain task's stack.
7126 define showpmworkqueueint
7127 set $kgm_pm_wq = (IOPMWorkQueue *)$arg0
7128 set $kgm_pm_node = (IOService *)$kgm_pm_wq->owner
7131 showptr $kgm_pm_node
7133 printf "%02d ", $kgm_pm_node->pwrMgt->CurrentPowerState
7134 printf "%02d ", $kgm_pm_node->pwrMgt->MachineState
7135 printf "%02d ", $kgm_pm_node->pwrMgt->WaitReason
7136 printf "%s\n", $kgm_pm_node->pwrMgt->Name
7137 set $kgm_pm_queue = &($kgm_pm_wq->fWorkQueue)
7138 set $kgm_pm_req = (IOPMRequest *)$kgm_pm_queue->next
7139 if ((queue_entry_t) $kgm_pm_req != (queue_entry_t) $kgm_pm_queue)
7143 printf " type next "
7147 printf " work_wait free_wait\n"
7148 while ((queue_entry_t) $kgm_pm_req != (queue_entry_t) $kgm_pm_queue)
7150 printf " 0x%02x ", $kgm_pm_req->fType
7151 showptr $kgm_pm_req->fRequestNext
7153 showptr $kgm_pm_req->fRequestRoot
7154 printf " 0x%08x 0x%08x\n", $kgm_pm_req->fWorkWaitCount, $kgm_pm_req->fFreeWaitCount
7157 showptr $kgm_pm_req->fArg0
7159 showptr $kgm_pm_req->fArg1
7161 showptr $kgm_pm_req->fArg2
7163 set $kgm_pm_req = (IOPMRequest *)$kgm_pm_req->fCommandChain.next
7169 define showallpmworkqueues
7170 set $kgm_pm_next = gIOPMWorkLoop->eventChain
7175 printf " ps ms wr name\n"
7176 while ( $kgm_pm_next )
7177 set $kgm_vt = *((void **) $kgm_pm_next)
7178 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
7179 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
7181 if ($kgm_vt == &_ZTV13IOPMWorkQueue)
7182 showpmworkqueueint $kgm_pm_next
7184 set $kgm_pm_next = $kgm_pm_next->eventChainNext
7188 document showallpmworkqueues
7189 Syntax: (gdb) showallpmworkqueues
7190 | Display info about all IOPMWorkQueue objects
7193 define showioservicepm
7194 set $kgm_iopmpriv = (IOServicePM *)$arg0
7196 printf "MachineState = %d (", $kgm_iopmpriv->MachineState
7197 if ( $kgm_iopmpriv->MachineState == 1 )
7198 printf "kIOPM_OurChangeTellClientsPowerDown"
7200 if ( $kgm_iopmpriv->MachineState == 2 )
7201 printf "kIOPM_OurChangeTellPriorityClientsPowerDown"
7203 if ( $kgm_iopmpriv->MachineState == 3 )
7204 printf "kIOPM_OurChangeNotifyInterestedDriversWillChange"
7206 if ( $kgm_iopmpriv->MachineState == 4 )
7207 printf "kIOPM_OurChangeSetPowerState"
7209 if ( $kgm_iopmpriv->MachineState == 5 )
7210 printf "kIOPM_OurChangeWaitForPowerSettle"
7212 if ( $kgm_iopmpriv->MachineState == 6 )
7213 printf "kIOPM_OurChangeNotifyInterestedDriversDidChange"
7215 if ( $kgm_iopmpriv->MachineState == 7 )
7216 printf "kIOPM_OurChangeFinish"
7218 if ( $kgm_iopmpriv->MachineState == 8 )
7219 printf "kIOPM_ParentDownTellPriorityClientsPowerDown"
7221 if ( $kgm_iopmpriv->MachineState == 9 )
7222 printf "kIOPM_ParentDownNotifyInterestedDriversWillChange"
7224 if ( $kgm_iopmpriv->MachineState == 10 )
7225 printf "Unused_MachineState_10"
7227 if ( $kgm_iopmpriv->MachineState == 11 )
7228 printf "kIOPM_ParentDownNotifyDidChangeAndAcknowledgeChange"
7230 if ( $kgm_iopmpriv->MachineState == 12 )
7231 printf "kIOPM_ParentDownSetPowerState"
7233 if ( $kgm_iopmpriv->MachineState == 13 )
7234 printf "kIOPM_ParentDownWaitForPowerSettle"
7236 if ( $kgm_iopmpriv->MachineState == 14 )
7237 printf "kIOPM_ParentDownAcknowledgeChange"
7239 if ( $kgm_iopmpriv->MachineState == 15)
7240 printf "kIOPM_ParentUpSetPowerState"
7242 if ( $kgm_iopmpriv->MachineState == 16)
7243 printf "Unused_MachineState_16"
7245 if ( $kgm_iopmpriv->MachineState == 17)
7246 printf "kIOPM_ParentUpWaitForSettleTime"
7248 if ( $kgm_iopmpriv->MachineState == 18)
7249 printf "kIOPM_ParentUpNotifyInterestedDriversDidChange"
7251 if ( $kgm_iopmpriv->MachineState == 19)
7252 printf "kIOPM_ParentUpAcknowledgePowerChange"
7254 if ( $kgm_iopmpriv->MachineState == 20)
7255 printf "kIOPM_Finished"
7257 if ( $kgm_iopmpriv->MachineState == 21)
7258 printf "kIOPM_DriverThreadCallDone"
7260 if ( $kgm_iopmpriv->MachineState == 22)
7261 printf "kIOPM_NotifyChildrenDone"
7286 if ( $kgm_iopmpriv->MachineState != 20 )
7287 printf "DriverTimer = %d, ",(unsigned int)$kgm_iopmpriv->DriverTimer
7288 printf "SettleTime = %d, ",(unsigned int)$kgm_iopmpriv->SettleTimeUS
7289 printf "HeadNoteFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteFlags
7290 printf "HeadNotePendingAcks = %x, ",(unsigned int)$kgm_iopmpriv->HeadNotePendingAcks
7293 if ( $kgm_iopmpriv->DeviceOverrides != 0 )
7294 printf"DeviceOverrides, "
7297 printf "DeviceDesire = %d, ",(unsigned int)$kgm_iopmpriv->DeviceDesire
7298 printf "DesiredPowerState = %d, ",(unsigned int)$kgm_iopmpriv->DesiredPowerState
7299 printf "PreviousRequest = %d }\n",(unsigned int)$kgm_iopmpriv->PreviousRequest
7302 document showioservicepm
7303 Syntax: (gdb) showioservicepm <IOServicePM pointer>
7304 | Routine to dump the IOServicePM object
7307 define showregistryentryrecursepmstate
7308 set $kgm_re = (IOService *)$arg1
7309 set $kgm$arg0_stack = (unsigned long long) $arg2
7312 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
7314 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
7317 dictget $kgm_re->fRegistryTable $kgm_childkey
7318 set $kgm$arg0_child_array = (OSArray *) $kgm_result
7320 if ($kgm$arg0_child_array)
7321 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
7323 set $kgm$arg0_child_count = 0
7326 if ($kgm$arg0_child_count)
7327 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
7329 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
7332 indent $kgm_reg_depth $kgm$arg0_stack
7335 dictget $kgm_re->fRegistryTable $kgm_namekey
7336 if ($kgm_result == 0)
7337 dictget $kgm_re->fRegistryTable gIONameKey
7339 if ($kgm_result == 0)
7340 dictget $kgm_re->fPropertyTable gIOClassKey
7343 if ($kgm_result != 0)
7344 printf "%s <%p>", ((OSString *)$kgm_result)->string, $kgm_re
7346 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
7347 printf "%s <", ((IOService*)$kgm_re)->pwrMgt->Name
7357 if (((IOService*)$kgm_re)->pwrMgt )
7358 printf " Current Power State: %ld ", ((IOService*)$kgm_re)->pwrMgt->CurrentPowerState
7359 #printf " Mach State %ld", ((IOService*)$kgm_re)->pwrMgt->MachineState
7360 showioservicepm ((IOService*)$kgm_re)->pwrMgt
7366 if ($kgm$arg0_child_count != 0)
7368 set $kgm_reg_depth = $kgm_reg_depth + 1
7369 set $kgm$arg0_child_idx = 0
7371 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
7372 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
7373 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
7374 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
7377 showregistryentryrecursepmstate _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
7380 set $kgm_reg_depth = $kgm_reg_depth - 1
7384 define showregistryentryintpmstate
7386 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
7390 printf "Please load kgmacros after KDP attaching to the target.\n"
7392 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
7393 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
7394 showregistryentryrecursepmstate _ $arg0 0 0
7398 define showregistrypmstate
7399 # setregistryplane gIOPowerPlane
7400 set $kgm_reg_depth = 0
7401 set $kgm_show_props = 1
7402 showregistryentryintpmstate gRegistryRoot
7405 document showregistrypmstate
7406 Syntax: (gdb) showregistrypmstate
7407 | Routine to dump the PM state of each IOPower registry entry
7410 define showstacksafterthread
7411 set $kgm_head_taskp = &default_pset.tasks
7412 set $kgm_actp = (struct thread *)$arg0
7413 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
7414 set $kgm_taskp = (struct task *)$kgm_actp->task
7415 while $kgm_taskp != $kgm_head_taskp
7417 showtaskint $kgm_taskp
7418 set $kgm_head_actp = &($kgm_taskp->threads)
7419 while $kgm_actp != $kgm_head_actp
7421 if ($decode_wait_events > 0)
7422 showactint $kgm_actp 1
7424 showactint $kgm_actp 2
7426 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
7429 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
7433 document showstacksafterthread
7434 Syntax: (gdb) showstacksafterthread <thread>
7435 | Routine to print out all stacks (as in showallstacks) starting after a given thread
7436 | Useful if that gdb refuses to print a certain task's stack.
7440 set kdp_reentry_deadline = ((unsigned) $arg0)*1000
7444 document kdp-reenter
7445 Syntax: (gdb) kdp-reenter <seconds>
7446 | Schedules reentry into the debugger after <seconds> seconds, and resumes
7447 | the target system.
7458 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7459 printf "Not available for current architecture.\n"
7462 _if_present mca_MCA_present
7463 printf ", control MSR"
7464 _if_present mca_control_MSR_present
7465 printf ", threshold status"
7466 _if_present mca_threshold_status_present
7467 printf "\n%d error banks, ", mca_error_bank_count
7468 printf "family code 0x%x, ", mca_family
7469 printf "machine-check dump state: %d\n", mca_dump_state
7471 while cpu_data_ptr[$kgm_cpu] != 0
7472 set $kgm_mcp = cpu_data_ptr[$kgm_cpu]->cpu_mca_state
7474 printf "CPU %d:", $kgm_cpu
7475 printf " mca_mcg_ctl: 0x%016llx", $kgm_mcp->mca_mcg_ctl
7476 printf " mca_mcg_status: 0x%016llx\n", $kgm_mcp->mca_mcg_status.u64
7478 printf "mca_mci_ctl "
7479 printf "mca_mci_status "
7480 printf "mca_mci_addr "
7481 printf "mca_mci_misc\n"
7483 while $kgm_bank < mca_error_bank_count
7484 set $kgm_bp = &$kgm_mcp->mca_error_bank[$kgm_bank]
7485 printf " %2d:", $kgm_bank
7486 printf " 0x%016llx", $kgm_bp->mca_mci_ctl
7487 printf " 0x%016llx", $kgm_bp->mca_mci_status.u64
7488 printf " 0x%016llx", $kgm_bp->mca_mci_addr
7489 printf " 0x%016llx\n", $kgm_bp->mca_mci_misc
7490 set $kgm_bank = $kgm_bank + 1
7493 set $kgm_cpu = $kgm_cpu + 1
7498 document showMCAstate
7499 Syntax: showMCAstate
7500 | Print machine-check register state after MC exception.
7505 # Step to lower-level page table and print attributes
7506 # $kgm_pt_paddr: current page table entry physical address
7507 # $kgm_pt_index: current page table entry index (0..511)
7509 # $kgm_pt_paddr: next level page table entry physical address
7510 # or null if invalid
7511 # $kgm_pt_valid: 1 if $kgm_pt_paddr is valid, 0 if the walk
7513 # $kgm_pt_large: 1 if kgm_pt_paddr is a page frame address
7514 # of a large page and not another page table entry
7515 # For $kgm_pt_verbose = 0: print nothing
7516 # 1: print basic information
7517 # 2: print basic information and hex table dump
7519 set $kgm_entryp = $kgm_pt_paddr + 8*$kgm_pt_index
7520 readphysint $kgm_entryp 64 $kgm_lcpu_self
7521 set $entry = $kgm_readphysint_result
7522 if $kgm_pt_verbose == 2
7523 set $kgm_pte_loop = 0
7524 while $kgm_pte_loop < 512
7525 set $kgm_pt_paddr_tmp = $kgm_pt_paddr + $kgm_pte_loop*8
7526 readphys64 $kgm_pt_paddr_tmp
7527 set $kgm_pte_loop = $kgm_pte_loop + 1
7530 set $kgm_paddr_mask = ~((0xfffULL<<52) | 0xfffULL)
7531 set $kgm_paddr_largemask = ~((0xfffULL<<52) | 0x1fffffULL)
7532 if $kgm_pt_verbose == 0
7533 if $entry & (0x1 << 0)
7534 set $kgm_pt_valid = 1
7535 if $entry & (0x1 << 7)
7536 set $kgm_pt_large = 1
7537 set $kgm_pt_paddr = $entry & $kgm_paddr_largemask
7539 set $kgm_pt_large = 0
7540 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
7543 set $kgm_pt_valid = 0
7544 set $kgm_pt_large = 0
7545 set $kgm_pt_paddr = 0
7548 printf "0x%016llx:\n\t0x%016llx\n\t", $kgm_entryp, $entry
7549 if $entry & (0x1 << 0)
7551 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
7552 set $kgm_pt_valid = 1
7555 set $kgm_pt_paddr = 0
7556 set $kgm_pt_valid = 0
7557 # stop decoding other bits
7560 if $entry & (0x1 << 1)
7565 if $entry & (0x1 << 2)
7568 printf " supervisor"
7570 if $entry & (0x1 << 3)
7573 if $entry & (0x1 << 4)
7576 if $entry & (0x1 << 5)
7579 if $entry & (0x1 << 6)
7582 if $entry & (0x1 << 7)
7584 set $kgm_pt_large = 1
7586 set $kgm_pt_large = 0
7588 if $entry & (0x1 << 8)
7591 if $entry & (0x3 << 9)
7592 printf " avail:0x%x", ($entry >> 9) & 0x3
7594 if $entry & (0x1 << 63)
7602 set $kgm_pmap = (pmap_t) $arg0
7603 set $kgm_vaddr = $arg1
7604 set $kgm_pt_paddr = $kgm_pmap->pm_cr3
7605 set $kgm_pt_valid = $kgm_pt_paddr != 0
7606 set $kgm_pt_large = 0
7607 set $kgm_pframe_offset = 0
7608 if $kgm_pt_valid && cpu_64bit
7609 # Look up bits 47:39 of the linear address in PML4T
7610 set $kgm_pt_index = ($kgm_vaddr >> 39) & 0x1ffULL
7611 set $kgm_pframe_offset = $kgm_vaddr & 0x7fffffffffULL
7613 printf "pml4 (index %d):\n", $kgm_pt_index
7618 # Look up bits 38:30 of the linear address in PDPT
7619 set $kgm_pt_index = ($kgm_vaddr >> 30) & 0x1ffULL
7620 set $kgm_pframe_offset = $kgm_vaddr & 0x3fffffffULL
7622 printf "pdpt (index %d):\n", $kgm_pt_index
7626 if $kgm_pt_valid && !$kgm_pt_large
7627 # Look up bits 29:21 of the linear address in PDT
7628 set $kgm_pt_index = ($kgm_vaddr >> 21) & 0x1ffULL
7629 set $kgm_pframe_offset = $kgm_vaddr & 0x1fffffULL
7631 printf "pdt (index %d):\n", $kgm_pt_index
7635 if $kgm_pt_valid && !$kgm_pt_large
7636 # Look up bits 20:21 of the linear address in PT
7637 set $kgm_pt_index = ($kgm_vaddr >> 12) & 0x1ffULL
7638 set $kgm_pframe_offset = $kgm_vaddr & 0xfffULL
7640 printf "pt (index %d):\n", $kgm_pt_index
7645 set $kgm_paddr = $kgm_pt_paddr + $kgm_pframe_offset
7646 readphysint $kgm_paddr 32 $kgm_lcpu_self
7647 set $kgm_value = $kgm_readphysint_result
7648 printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value
7651 printf "(no translation)\n"
7656 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7657 printf "Not available for current architecture.\n"
7660 printf "pmap_walk <pmap> <vaddr>\n"
7663 set $kgm_pt_verbose = 1
7665 if $kgm_pt_verbose != 2
7666 set $kgm_pt_verbose = 1
7669 _pmap_walk $arg0 $arg1
7675 Syntax: (gdb) pmap_walk <pmap> <virtual_address>
7676 | Perform a page-table walk in <pmap> for <virtual_address>.
7677 | Set $kgm_pt_verbose=2 for full hex dump of page tables.
7681 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7682 printf "Not available for current architecture.\n"
7685 printf "pmap_vtop <pamp> <vaddr>\n"
7687 set $kgm_pt_verbose = 0
7688 _pmap_walk $arg0 $arg1
7694 Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
7695 | For page-tables in <pmap> translate <virtual_address> to physical address.
7701 if (log_records == 0)
7703 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7713 printf "\n--------------- "
7715 if (zrecords[$index].z_opcode == 1)
7721 printf " 0x%x : index %d : ztime %d -------------\n", zrecords[$index].z_element, $index, zrecords[$index].z_time
7726 set $frame_pc = zrecords[$index].z_pc[$frame]
7733 set $frame = $frame + 1
7736 set $index = $index + 1
7737 set $count = $count - 1
7742 Syntax: (gdb) zstack <index> [<count>]
7743 | Zone leak debugging: print the stack trace of log element at <index>.
7744 | If a <count> is supplied, it prints <count> log elements starting at <index>.
7746 | The suggested usage is to look at indexes below zcurrent and look for common stack traces.
7747 | The stack trace that occurs the most is probably the cause of the leak. Find the pc of the
7748 | function calling into zalloc and use the countpcs kgmacro to find out how often that pc occurs in the log.
7749 | The pc occuring in a high percentage of records is most likely the source of the leak.
7751 | The findoldest kgmacro is also useful for leak debugging since it identifies the oldest record
7752 | in the log, which may indicate the leaker.
7757 set $count = log_records
7758 set $cur_min = 2000000000
7761 if (log_records == 0)
7762 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7766 if (zrecords[$index].z_element && zrecords[$index].z_time < $cur_min)
7767 set $cur_index = $index
7768 set $cur_min = zrecords[$index].z_time
7771 set $count = $count - 1
7772 set $index = $index + 1
7775 printf "oldest record is at log index %d:\n", $cur_index
7781 Syntax: (gdb) findoldest
7782 | Zone leak debugging: find and print the oldest record in the log. Note that this command
7783 | can take several minutes to run since it uses linear search.
7785 | Once it prints a stack trace, find the pc of the caller above all the zalloc, kalloc and
7786 | IOKit layers. Then use the countpcs kgmacro to see how often this caller has allocated
7787 | memory. A caller with a high percentage of records in the log is probably the leaker.
7791 set $target_pc = $arg0
7793 set $count = log_records
7796 if (log_records == 0)
7797 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7803 if (zrecords[$index].z_element != 0)
7805 if (zrecords[$index].z_pc[$frame] == $target_pc)
7806 set $found = $found + 1
7810 set $frame = $frame + 1
7814 set $index = $index + 1
7815 set $count = $count - 1
7818 printf "occurred %d times in log (%d%c of records)\n", $found, ($found * 100) / zrecorded, '%'
7823 Syntax: (gdb) countpcs <pc>
7824 | Zone leak debugging: search the log and print a count of all log entries that contain the given <pc>
7825 | in the stack trace. This is useful for verifying a suspected <pc> as being the source of
7826 | the leak. If a high percentage of the log entries contain the given <pc>, then it's most
7827 | likely the source of the leak. Note that this command can take several minutes to run.
7831 set $fe_index = zcurrent
7832 set $fe_count = log_records
7833 set $fe_elem = $arg0
7834 set $fe_prev_op = -1
7836 if (log_records == 0)
7837 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7841 if (zrecords[$fe_index].z_element == $fe_elem)
7844 if (zrecords[$fe_index].z_opcode == $fe_prev_op)
7845 printf "*************** DOUBLE OP! *********************\n
7848 set $fe_prev_op = zrecords[$fe_index].z_opcode
7851 set $fe_count = $fe_count - 1
7852 set $fe_index = $fe_index + 1
7854 if ($fe_index >= log_records)
7861 Syntax: (gdb) findelem <elem addr>
7862 | Zone corruption debugging: search the log and print out the stack traces for all log entries that
7863 | refer to the given zone element. When the kernel panics due to a corrupted zone element, get the
7864 | element address and use this macro. This will show you the stack traces of all logged zalloc and
7865 | zfree operations which tells you who touched the element in the recent past. This also makes
7866 | double-frees readily apparent.
7870 # This implements a shadowing scheme in kgmacros. If the
7871 # current user data can be accessed by simply changing kdp_pmap,
7872 # that is used. Otherwise, we copy data into a temporary buffer
7873 # in the kernel's address space and use that instead. Don't rely on
7874 # kdp_pmap between invocations of map/unmap. Since the shadow
7875 # codepath uses a manual KDP packet, request no more than 128 bytes.
7876 # Uses $kgm_lp64 for kernel address space size
7877 define _map_user_data_from_task
7878 set $kgm_map_user_taskp = (task_t)$arg0
7879 set $kgm_map_user_map = $kgm_map_user_taskp->map
7880 set $kgm_map_user_pmap = $kgm_map_user_map->pmap
7881 set $kgm_map_user_task_64 = ( $kgm_map_user_taskp->taskFeatures[0] & 0x80000000)
7882 set $kgm_map_user_window = 0
7883 set $kgm_map_switch_map = 0
7886 set $kgm_map_switch_map = 1
7888 if !$kgm_map_user_task_64
7889 set $kgm_map_switch_map = 1
7893 if ($kgm_map_switch_map)
7894 # switch the map safely
7895 set $kgm_map_user_window = $arg1
7896 set kdp_pmap = $kgm_map_user_pmap
7898 # requires shadowing/copying
7900 # set up the manual KDP packet
7901 set manual_pkt.input = 0
7902 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
7903 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
7904 set $kgm_pkt->hdr.request = KDP_READMEM64
7905 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
7906 set $kgm_pkt->hdr.is_reply = 0
7907 set $kgm_pkt->hdr.seq = 0
7908 set $kgm_pkt->hdr.key = 0
7909 set $kgm_pkt->address = (uint64_t)$arg1
7910 set $kgm_pkt->nbytes = (uint32_t)$arg2
7912 set kdp_pmap = $kgm_map_user_pmap
7913 set manual_pkt.input = 1
7914 # dummy to make sure manual packet is executed
7915 set $kgm_dummy = &_mh_execute_header
7916 # Go back to kernel map so that we can access buffer directly
7919 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
7920 if ($kgm_pkt->error == 0)
7921 set $kgm_map_user_window = $kgm_pkt->data
7923 set $kgm_map_user_window = 0
7929 define _unmap_user_data_from_task
7933 # uses $kgm_taskp. Maps 32 bytes at a time and prints it
7934 define _print_path_for_image
7935 set $kgm_print_path_address = (unsigned long long)$arg0
7936 set $kgm_path_str_notdone = 1
7938 while $kgm_path_str_notdone
7939 _map_user_data_from_task $kgm_taskp $kgm_print_path_address 32
7941 set $kgm_print_path_ptr = (char *)$kgm_map_user_window
7943 while ($kgm_path_i < 32 && $kgm_print_path_ptr[$kgm_path_i] != '\0')
7944 set $kgm_path_i = $kgm_path_i + 1
7946 printf "%.32s", $kgm_print_path_ptr
7948 _unmap_user_data_from_task $kgm_taskp
7950 # if we terminated on NUL, break out
7952 set $kgm_path_str_notdone = 0
7954 set $kgm_print_path_address = $kgm_print_path_address + 32
7959 # uses $kgm_taskp and $kgm_task_64
7960 define _print_image_info
7961 set $kgm_mh_image_address = (unsigned long long)$arg0
7962 set $kgm_mh_path_address = (unsigned long long)$arg1
7964 # 32 bytes enough for mach_header/mach_header_64
7965 _map_user_data_from_task $kgm_taskp $kgm_mh_image_address 32
7967 set $kgm_mh_ptr = (unsigned int*)$kgm_map_user_window
7968 set $kgm_mh_magic = $kgm_mh_ptr[0]
7969 set $kgm_mh_cputype = $kgm_mh_ptr[1]
7970 set $kgm_mh_cpusubtype = $kgm_mh_ptr[2]
7971 set $kgm_mh_filetype = $kgm_mh_ptr[3]
7972 set $kgm_mh_ncmds = $kgm_mh_ptr[4]
7973 set $kgm_mh_sizeofcmds = $kgm_mh_ptr[5]
7974 set $kgm_mh_flags = $kgm_mh_ptr[6]
7976 _unmap_user_data_from_task $kgm_taskp
7978 if $kgm_mh_magic == 0xfeedfacf
7980 set $kgm_lc_address = $kgm_mh_image_address + 32
7983 set $kgm_lc_address = $kgm_mh_image_address + 28
7987 set $kgm_uuid_data = 0
7988 while $kgm_lc_idx < $kgm_mh_ncmds
7990 # 24 bytes is size of uuid_command
7991 _map_user_data_from_task $kgm_taskp $kgm_lc_address 24
7993 set $kgm_lc_ptr = (unsigned int *)$kgm_map_user_window
7994 set $kgm_lc_cmd = $kgm_lc_ptr[0]
7995 set $kgm_lc_cmd_size = $kgm_lc_ptr[1]
7996 set $kgm_lc_data = (unsigned char *)$kgm_lc_ptr + 8
7998 if $kgm_lc_cmd == 0x1b
7999 set $kgm_uuid_data = $kgm_lc_data
8001 printf "0x%016llx ", $kgm_mh_image_address
8003 printf "0x%08x ", $kgm_mh_image_address
8006 set $kgm_printed_type = 0
8007 if $kgm_mh_filetype == 0x2
8008 printf "MH_EXECUTE "
8009 set $kgm_printed_type = 1
8011 if $kgm_mh_filetype == 0x6
8013 set $kgm_printed_type = 1
8015 if $kgm_mh_filetype == 0x7
8016 printf "MH_DYLINKER "
8017 set $kgm_printed_type = 1
8019 if $kgm_mh_filetype == 0x8
8021 set $kgm_printed_type = 1
8023 if !$kgm_printed_type
8026 printf "%02.2X%02.2X%02.2X%02.2X-", $kgm_uuid_data[0], $kgm_uuid_data[1], $kgm_uuid_data[2], $kgm_uuid_data[3]
8027 printf "%02.2X%02.2X-", $kgm_uuid_data[4], $kgm_uuid_data[5]
8028 printf "%02.2X%02.2X-", $kgm_uuid_data[6], $kgm_uuid_data[7]
8029 printf "%02.2X%02.2X-", $kgm_uuid_data[8], $kgm_uuid_data[9]
8030 printf "%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X", $kgm_uuid_data[10], $kgm_uuid_data[11], $kgm_uuid_data[12], $kgm_uuid_data[13], $kgm_uuid_data[14], $kgm_uuid_data[15]
8032 _unmap_user_data_from_task $kgm_taskp
8035 _print_path_for_image $kgm_mh_path_address
8040 _unmap_user_data_from_task $kgm_taskp
8043 set $kgm_lc_address = $kgm_lc_address + $kgm_lc_cmd_size
8044 set $kgm_lc_idx = $kgm_lc_idx + 1
8047 if (!$kgm_uuid_data)
8048 # didn't find LC_UUID, for a dylib, just print out basic info
8050 printf "0x%016llx ", $kgm_mh_image_address
8052 printf "0x%08x ", $kgm_mh_image_address
8054 set $kgm_printed_type = 0
8055 if $kgm_mh_filetype == 0x2
8056 printf "MH_EXECUTE "
8057 set $kgm_printed_type = 1
8059 if $kgm_mh_filetype == 0x6
8061 set $kgm_printed_type = 1
8063 if $kgm_mh_filetype == 0x7
8064 printf "MH_DYLINKER "
8065 set $kgm_printed_type = 1
8067 if $kgm_mh_filetype == 0x8
8069 set $kgm_printed_type = 1
8071 if !$kgm_printed_type
8077 _print_path_for_image $kgm_mh_path_address
8084 define _print_images_for_dyld_image_info
8085 set $kgm_taskp = $arg0
8086 set $kgm_task_64 = $arg1
8087 set $kgm_dyld_all_image_infos_address = (unsigned long long)$arg2
8089 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 16
8091 set $kgm_dyld_all_image_infos = (unsigned int *)$kgm_map_user_window
8092 if ($kgm_dyld_all_image_infos[0] != 6)
8093 printf "Invalid version number %d\n", $kgm_dyld_all_image_infos[0]
8095 set $kgm_image_info_count = $kgm_dyld_all_image_infos[1]
8098 set $kgm_image_info_size = 24
8099 set $kgm_image_info_array_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[1]
8101 set $kgm_image_info_size = 12
8102 set $kgm_image_info_array_address = ((unsigned int *)$kgm_dyld_all_image_infos)[2]
8105 _unmap_user_data_from_task $kgm_taskp
8107 set $kgm_image_info_i = 0
8108 while $kgm_image_info_i < $kgm_image_info_count
8110 set $kgm_image_info_address = $kgm_image_info_array_address + $kgm_image_info_size*$kgm_image_info_i
8112 _map_user_data_from_task $kgm_taskp $kgm_image_info_address $kgm_image_info_size
8114 set $kgm_image_info_addr = ((unsigned long long *)$kgm_map_user_window)[0]
8115 set $kgm_image_info_path = ((unsigned long long *)$kgm_map_user_window)[1]
8117 set $kgm_image_info_addr = ((unsigned int *)$kgm_map_user_window)[0]
8118 set $kgm_image_info_path = ((unsigned int *)$kgm_map_user_window)[1]
8120 _unmap_user_data_from_task $kgm_taskp
8122 # printf "[%d] = image address %llx path address %llx\n", $kgm_image_info_i, $kgm_image_info_addr, $kgm_image_info_path
8123 _print_image_info $kgm_image_info_addr $kgm_image_info_path
8125 set $kgm_image_info_i = $kgm_image_info_i + 1
8129 define showuserlibraries
8130 set $kgm_taskp = (task_t)$arg0
8131 set $kgm_dyld_image_info = $kgm_taskp->all_image_info_addr
8133 set $kgm_map = $kgm_taskp->map
8134 set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
8136 if ($kgm_dyld_image_info != 0)
8145 _print_images_for_dyld_image_info $kgm_taskp $kgm_task_64 $kgm_dyld_image_info
8147 printf "No dyld shared library information available for task\n"
8150 document showuserlibraries
8151 Syntax: (gdb) showuserlibraries <task_t>
8152 | For a given user task, inspect the dyld shared library state and print
8153 | information about all Mach-O images.
8156 define showkerneldebugheader
8159 printf "CPU Thread "
8161 printf "Timestamp S/E Class Sub Code Code Specific Info\n"
8164 define _printevflags
8185 printf "EV_RCLOSED "
8191 printf "EV_WCLOSED "
8206 printf "EV_TIMEOUT "
8210 define showkerneldebugbufferentry
8211 set $kgm_kdebug_entry = (kd_buf *) $arg0
8213 set $kgm_debugid = $kgm_kdebug_entry->debugid
8214 set $kgm_kdebug_arg1 = $kgm_kdebug_entry->arg1
8215 set $kgm_kdebug_arg2 = $kgm_kdebug_entry->arg2
8216 set $kgm_kdebug_arg3 = $kgm_kdebug_entry->arg3
8217 set $kgm_kdebug_arg4 = $kgm_kdebug_entry->arg4
8220 set $kgm_kdebug_cpu = $kgm_kdebug_entry->cpuid
8221 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0xFFFFFFFF
8222 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
8224 set $kgm_kdebug_cpu = ($kgm_kdebug_entry->timestamp >> 56)
8225 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0x00FFFFFF
8226 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
8229 set $kgm_kdebug_class = ($kgm_debugid >> 24) & 0x000FF
8230 set $kgm_kdebug_subclass = ($kgm_debugid >> 16) & 0x000FF
8231 set $kgm_kdebug_code = ($kgm_debugid >> 2) & 0x03FFF
8232 set $kgm_kdebug_qual = ($kgm_debugid ) & 0x00003
8234 if $kgm_kdebug_qual == 0
8235 set $kgm_kdebug_qual = '-'
8237 if $kgm_kdebug_qual == 1
8238 set $kgm_kdebug_qual = 'S'
8240 if $kgm_kdebug_qual == 2
8241 set $kgm_kdebug_qual = 'E'
8243 if $kgm_kdebug_qual == 3
8244 set $kgm_kdebug_qual = '?'
8252 showptr $kgm_kdebug_entry
8253 printf " %d ", $kgm_kdebug_cpu
8254 showptr $kgm_kdebug_entry->arg5
8255 printf " 0x%08X%08X %c ", $kgm_ts_hi, $kgm_ts_lo, $kgm_kdebug_qual
8259 if $kgm_kdebug_class == 1
8262 if $kgm_kdebug_class == 2
8265 if $kgm_kdebug_class == 3
8268 if $kgm_kdebug_class == 4
8271 if $kgm_kdebug_class == 5
8274 if $kgm_kdebug_class == 6
8277 if $kgm_kdebug_class == 7
8280 if $kgm_kdebug_class == 8
8283 if $kgm_kdebug_class == 8
8286 if $kgm_kdebug_class == 20
8289 if $kgm_kdebug_class == 31
8292 if $kgm_kdebug_class == 32
8295 if $kgm_kdebug_class == 33
8298 if $kgm_kdebug_class == 255
8301 printf "0x%02X", $kgm_kdebug_class
8319 printf " 0x%02X %5d ", $kgm_kdebug_subclass, $kgm_kdebug_code
8321 # space for debugid-specific processing
8323 # EVPROC from bsd/kern/sys_generic.c
8325 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT)
8326 if $kgm_debugid == 0x14100048
8328 if $kgm_kdebug_arg1 == 1
8329 printf "before sleep"
8331 if $kgm_kdebug_arg1 == 2
8332 printf "after sleep"
8334 printf "????????????"
8337 printf " chan=0x%08X ", $kgm_kdebug_arg2
8339 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_START)
8340 if $kgm_debugid == 0x14100049
8343 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_END)
8344 if $kgm_debugid == 0x1410004a
8345 printf "waitevent error=%d ", $kgm_kdebug_arg1
8346 printf "eqp=0x%08X ", $kgm_kdebug_arg4
8347 _printevflags $kgm_kdebug_arg3
8348 printf "er_handle=%d ", $kgm_kdebug_arg2
8350 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_START)
8351 if $kgm_debugid == 0x14100059
8352 printf "evprocdeque proc=0x%08X ", $kgm_kdebug_arg1
8353 if $kgm_kdebug_arg2 == 0
8354 printf "remove first "
8356 printf "remove 0x%08X ", $kgm_kdebug_arg2
8359 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_END)
8360 if $kgm_debugid == 0x1410005a
8361 printf "evprocdeque "
8362 if $kgm_kdebug_arg1 == 0
8363 printf "result=NULL "
8365 printf "result=0x%08X ", $kgm_kdebug_arg1
8368 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_START)
8369 if $kgm_debugid == 0x14100041
8371 _printevflags $kgm_kdebug_arg1
8373 # MISCDBG_CODE(DBG_EVENT,DBG_POST)
8374 if $kgm_debugid == 0x14100040
8376 printf "evq=0x%08X ", $kgm_kdebug_arg1
8377 printf "er_eventbits="
8378 _printevflags $kgm_kdebug_arg2
8380 _printevflags $kgm_kdebug_arg3
8382 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_END)
8383 if $kgm_debugid == 0x14100042
8386 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_START)
8387 if $kgm_debugid == 0x14100055
8388 printf "evprocenque eqp=0x%08d ", $kgm_kdebug_arg1
8389 if $kgm_kdebug_arg2 & 1
8392 _printevflags $kgm_kdebug_arg3
8395 # MISCDBG_CODE(DBG_EVENT,DBG_EWAKEUP)
8396 if $kgm_debugid == 0x14100050
8397 printf "evprocenque before wakeup eqp=0x%08d ", $kgm_kdebug_arg4
8399 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_END)
8400 if $kgm_debugid == 0x14100056
8401 printf "evprocenque "
8403 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_START)
8404 if $kgm_debugid == 0x1410004d
8407 # MISCDBG_CODE(DBG_EVENT,DBG_MOD)
8408 if $kgm_debugid == 0x1410004c
8409 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
8410 _printevflags $kgm_kdebug_arg2
8411 printf "evq=0x%08X ", $kgm_kdebug_arg3
8413 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_END)
8414 if $kgm_debugid == 0x1410004e
8415 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
8416 printf "ee_eventmask="
8417 _printevflags $kgm_kdebug_arg2
8418 printf "sp=0x%08X ", $kgm_kdebug_arg3
8420 _printevflags $kgm_kdebug_arg4
8422 printf "arg1=0x%08X ", $kgm_kdebug_arg1
8423 printf "arg2=0x%08X ", $kgm_kdebug_arg2
8424 printf "arg3=0x%08X ", $kgm_kdebug_arg3
8425 printf "arg4=0x%08X ", $kgm_kdebug_arg4
8446 define showkerneldebugbuffercpu
8447 set $kgm_cpu_number = (int) $arg0
8448 set $kgm_entry_count = (int) $arg1
8449 set $kgm_debugentriesfound = 0
8451 #if kdebug_flags & KDBG_BFINIT
8452 if (kdebug_flags & 0x80000000)
8453 showkerneldebugheader
8455 if $kgm_entry_count == 0
8456 printf "<count> is 0, dumping 50 entries\n"
8457 set $kgm_entry_count = 50
8460 if $kgm_cpu_number >= kd_cpus
8461 printf "cpu number too big\n"
8463 set $kgm_kdbp = &kdbip[$kgm_cpu_number]
8464 set $kgm_kdsp = $kgm_kdbp->kd_list_head
8465 while (($kgm_kdsp != 0) && ($kgm_entry_count > 0))
8466 if $kgm_kdsp->kds_readlast != $kgm_kdsp->kds_bufptr
8467 set $kgm_kds_bufptr = $kgm_kdsp->kds_bufptr
8468 while (($kgm_kds_bufptr > $kgm_kdsp->kds_readlast) && ($kgm_entry_count > 0))
8469 set $kgm_kds_bufptr = $kgm_kds_bufptr - 1
8470 set $kgm_entry_count = $kgm_entry_count - 1
8471 showkerneldebugbufferentry $kgm_kds_bufptr
8474 set $kgm_kdsp = $kgm_kdsp->kds_next
8478 printf "Trace buffer not enabled\n"
8482 document showkerneldebugbuffercpu
8483 Syntax: showkerneldebugbuffercpu <cpu> <count>
8484 | Prints the last N entries in the kernel debug buffer for CPU x.
8487 define showkerneldebugbuffer
8489 #if kdebug_flags & KDBG_BFINIT
8490 if (kdebug_flags & 0x80000000)
8492 set $kgm_entrycount = (int) $arg0
8494 if $kgm_entrycount == 0
8495 printf "<count> is 0, dumping 50 entries per cpu\n"
8496 set $kgm_entrycount = 50
8499 set $kgm_cpu = (int) 0
8501 while $kgm_cpu < kd_cpus
8502 showkerneldebugbuffercpu $kgm_cpu $kgm_entrycount
8503 set $kgm_cpu = $kgm_cpu + 1
8506 printf "Trace buffer not enabled\n"
8510 document showkerneldebugbuffer
8511 Syntax: showkerneldebugbuffer <count>
8512 | Prints the last N entries in the kernel debug buffer per cpu. i.e. showkerneldebugbuffer 50 will
8513 | display the last 50 entries in each CPU's debug buffer.
8516 define showallvmstats
8517 printf " pid command #ents wired vsize rsize max rsize\n"
8518 printf " (pages) (pages) (pages) (pages)\n"
8519 set $kgm_head_taskp = &tasks
8520 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
8521 while $kgm_taskp != $kgm_head_taskp
8522 set $kgm_procp = (struct proc *)($kgm_taskp->bsd_info)
8523 set $kgm_mapp = (struct _vm_map *)($kgm_taskp->map)
8524 printf "%8d %17s %8d %15d %15d %15d %15d\n", $kgm_procp->p_pid, $kgm_procp->p_comm, $kgm_mapp->hdr.nentries, $kgm_mapp->pmap->stats.wired_count, $kgm_mapp->size >> 12, $kgm_mapp->pmap->stats.resident_count, $kgm_mapp->pmap->stats.resident_max
8525 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
8529 document showallvmstats
8530 Syntax: showallvmstats
8531 | prints a summary of vm statistics in a table format
8534 define show_user_registers
8535 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
8536 set $kgm_thread = (thread_t)$arg0
8537 if ((*(thread_t)$kgm_thread)->machine.xxx_pcb.iss.flavor == 15)
8538 p/x ($kgm_thread)->machine.xxx_pcb.iss->uss.ss_64
8540 p/x ($kgm_thread)->machine.xxx_pcb.iss->uss.ss_32
8543 if ($kgm_mtype == $kgm_mtype_ppc)
8544 set $kgm_thread = (thread_t)$arg0
8545 p/x *($kgm_thread)->machine.pcb
8549 document show_user_registers
8550 Syntax: show_user_registers <thread_address>
8551 | Display user registers associated with a kernel thread
8552 | properly displays the 32 bit or 64 bit registers for intel architecture
8559 # check for end of string. cmp0 can be longer than cmp1. it
8562 set $kgm_strcmp_result = 0
8563 set $kgm_strcmp_done = 1
8566 if !$kgm_strcmp_done && $cmp0 == '\0'
8567 set $kgm_strcmp_result = -1
8568 set $kgm_strcmp_done = 1
8572 if !$kgm_strcmp_done
8573 set $kgm_strcmp_result = (uint8_t) $cmp0 - (uint8_t) $cmp1
8574 if $kgm_strcmp_result != 0
8575 set $kgm_strcmp_done = 1
8582 set $masked = $cmp & 0xFF
8583 _cmp $arg0[0] $masked
8585 if !$kgm_strcmp_done
8586 set $cmp = $cmp >> 8
8587 set $masked = $cmp & 0xFF
8588 _cmp $arg0[1] $masked
8590 if !$kgm_strcmp_done
8591 set $cmp = $cmp >> 8
8592 set $masked = $cmp & 0xFF
8593 _cmp $arg0[2] $masked
8595 if !$kgm_strcmp_done
8596 set $cmp = $cmp >> 8
8597 set $masked = $cmp & 0xFF
8598 _cmp $arg0[3] $masked
8600 if !$kgm_strcmp_done
8601 set $cmp = $cmp >> 8
8602 set $masked = $cmp & 0xFF
8603 _cmp $arg0[4] $masked
8605 if !$kgm_strcmp_done
8606 set $cmp = $cmp >> 8
8607 set $masked = $cmp & 0xFF
8608 _cmp $arg0[5] $masked
8610 if !$kgm_strcmp_done
8611 set $cmp = $cmp >> 8
8612 set $masked = $cmp & 0xFF
8613 _cmp $arg0[6] $masked
8615 if !$kgm_strcmp_done
8616 set $cmp = $cmp >> 8
8617 set $masked = $cmp & 0xFF
8618 _cmp $arg0[7] $masked
8622 define strcmp_arg_pack64
8623 set $kgm_strcmp_arg = ((((((((((((((uint64_t) $arg7 << 8) | $arg6) << 8) | $arg5) << 8) | $arg4) << 8) | $arg3) << 8) | $arg2) << 8) | $arg1) << 8) | $arg0
8626 document strcmp_arg_pack64
8627 Syntax: strcmp_arg_pack64 <a> <b> <c> <d> <e <f> <g> <h>
8628 | Packs a string given as 8 character arguments into a 64-bit int stored in
8629 | $kgm_strcmp_arg. Use 0 or '\0' for unused arguments. The encoded string
8630 | is suitable for use by strcmp_nomalloc and setfindregistrystr.
8631 | e.g., strcmp_arg_pack64 'H' 'e' 'l' 'l' 'o' 0 0 0
8632 | packs "Hello" into $kgm_strcmp_arg.
8636 define strcmp_nomalloc
8638 set $count = $argc - 1
8640 set $kgm_strcmp_result = 0
8641 set $kgm_strcmp_done = 0
8644 _cmp_arg64 $str $arg1
8646 if !$kgm_strcmp_done && $count > 1
8648 _cmp_arg64 $str $arg2
8650 if !$kgm_strcmp_done && $count > 2
8652 _cmp_arg64 $str $arg3
8654 if !$kgm_strcmp_done && $count > 3
8656 _cmp_arg64 $str $arg4
8658 if !$kgm_strcmp_done && $count > 4
8660 _cmp_arg64 $str $arg5
8662 if !$kgm_strcmp_done && $count > 5
8664 _cmp_arg64 $str $arg6
8666 if !$kgm_strcmp_done && $count > 6
8668 _cmp_arg64 $str $arg7
8670 if !$kgm_strcmp_done && $count > 7
8672 _cmp_arg64 $str $arg8
8674 if !$kgm_strcmp_done && $count > 8
8676 _cmp_arg64 $str $arg9
8680 document strcmp_nomalloc
8681 Syntax: strcmp_nomalloc <string> <a> [b] [c] [d] [e] [f] [g] [h] [i]
8682 | Given a pre-allocated <string>, perform a string compare with the
8683 | encoded string stored in arguments a - i. The result is stored in
8684 | $kgm_strcmp_result.
8686 | For example, the following will result in $kgm_strcmp_result == 0:
8687 | strcmp_arg_pack64 'D' 'a' 'r' 'w' 'i' 'n' ' ' 'K'
8688 | strcmp_nomalloc version $kgm_strcmp_arg
8691 # _pci_cfg_addr_value $addr $size
8692 define _pci_cfg_addr_value
8693 readphysint $arg0 $arg1 $kgm_lcpu_self
8694 set $kgm_pci_cfg_value = $kgm_readphysint_result
8698 set $kgm_pci_cfg_init = 0
8699 define _pci_cfg_init
8700 # get this from the registry if it exists there
8701 if $kgm_pci_cfg_init == 0
8702 strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
8703 set $AppleACP = $kgm_strcmp_arg
8704 strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
8705 set $IPlatfor = $kgm_strcmp_arg
8706 strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
8707 set $mExpert = $kgm_strcmp_arg
8708 setfindregistrystr $AppleACP $IPlatfor $mExpert
8710 set $olddepth = $kgm_reg_depth_max
8711 set $kgm_reg_depth_max = 2
8713 set $kgm_reg_depth_max = $olddepth
8715 if $kgm_registry_entry
8716 strcmp_arg_pack64 'a' 'c' 'p' 'i' '-' 'm' 'm' 'c'
8717 set $acpi_mmc = $kgm_strcmp_arg
8718 strcmp_arg_pack64 'f' 'g' '-' 's' 'e' 'g' '0' 0
8719 set $fg_seg0 = $kgm_strcmp_arg
8720 setfindregistrystr $acpi_mmc $fg_seg0
8722 _findregistryprop $kgm_registry_entry
8723 if $kgm_registry_value
8724 set $kgm_pci_cfg_base = ((OSNumber *) $kgm_registry_value)->value
8725 set $kgm_pci_cfg_init = 1
8730 # if the above fails, search for 0:0:0 in likely places.
8731 if $kgm_pci_cfg_init == 0
8732 set $kgm_pci_cfg_base = 0xF0000000
8733 while $kgm_pci_cfg_init == 0 && $kgm_pci_cfg_base > 0xA0000000
8734 _pci_cfg_addr_value $kgm_pci_cfg_base 8
8735 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xFF
8736 set $kgm_pci_cfg_init = 1
8738 set $kgm_pci_cfg_base = $kgm_pci_cfg_base - 0x10000000
8744 # _pci_cfg_addr $bus $dev $fcn $off
8745 define _pci_cfg_addr
8752 set $kgm_pci_cfg_addr = $kgm_pci_cfg_base | ($bus << 20) | ($dev << 15) | ($fcn << 12) | $off
8755 define _pci_cfg_value
8756 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8757 _pci_cfg_addr_value $kgm_pci_cfg_addr $arg4
8760 define pci_cfg_read8
8761 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 8
8762 printf "%08X: %02X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8765 define pci_cfg_read16
8766 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 16
8767 printf "%08X: %04X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8770 define pci_cfg_read32
8771 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 32
8772 printf "%08X: %08X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8775 document pci_cfg_read8
8776 Syntax: (gdb) pci_cfg_read8 <bus> <dev> <fcn> <off>
8777 | read 8 bits for the given <off> of the pci device located at
8778 | <bus>:<dev>:<fcn>.
8781 document pci_cfg_read16
8782 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
8783 | read 16 bits for the given <off> of the pci device located at
8784 | <bus>:<dev>:<fcn>.
8787 document pci_cfg_read32
8788 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
8789 | read 32 bits for the given <off> of the pci device located at
8790 | <bus>:<dev>:<fcn>.
8793 define pci_cfg_write8
8794 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8795 writephysint $kgm_pci_cfg_addr 8 $arg4 $kgm_lcpu_self
8798 define pci_cfg_write16
8799 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8800 writephysint $kgm_pci_cfg_addr 16 $arg4 $kgm_lcpu_self
8803 define pci_cfg_write32
8804 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8805 writephysint $kgm_pci_cfg_addr 32 $arg4 $kgm_lcpu_self
8808 document pci_cfg_write8
8809 Syntax: (gdb) pci_cfg_write8 <bus> <dev> <fcn> <off> <value>
8810 | write an 8-bit <value> into the given <off> of the pci device located at
8811 | <bus>:<dev>:<fcn>.
8814 document pci_cfg_write16
8815 Syntax: (gdb) pci_cfg_write16 <bus> <dev> <fcn> <off> <value>
8816 | write a 16-bit <value> into the given <off> of the pci device located at
8817 | <bus>:<dev>:<fcn>.
8820 document pci_cfg_write32
8821 Syntax: (gdb) pci_cfg_write32 <bus> <dev> <fcn> <off> <value>
8822 | write a 32-bit <value> into the given <off> of the pci device located at
8823 | <bus>:<dev>:<fcn>.
8833 # check for a valid pci device
8834 _pci_cfg_value $bus $dev $fcn $off 8
8835 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xff
8836 printf " address: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
8837 printf "---------------------------------------------------------"
8840 _pci_cfg_value $bus $dev $fcn $off 32
8841 if ($off & 0xF) == 0
8842 printf "\n%08X: ", $kgm_pci_cfg_addr
8844 printf "%02X %02X %02X %02X ", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF
8849 # check for pcie extended capability config space
8850 _pci_cfg_value $bus $dev $fcn $off 8
8851 if $kgm_pci_cfg_value < 0xff
8853 _pci_cfg_value $bus $dev $fcn $off 32
8854 if ($off & 0xF) == 0
8855 printf "\n%08X: ", $kgm_pci_cfg_addr
8857 printf "%02X %02X %02X %02X ", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF
8865 document pci_cfg_dump
8866 Syntax: (gdb) pci_cfg_dump <bus> <dev> <fcn>
8867 | dump config space for the pci device located at <bus>:<dev>:<fcn>
8868 | if you specify an invalid/inaccessible pci device, nothing will be
8872 set $kgm_pci_cfg_bus_start = 0
8873 set $kgm_pci_cfg_bus_max = 8
8874 set $kgm_pci_cfg_device_max = 32
8875 set $kgm_pci_cfg_function_max = 8
8876 define _pci_cfg_scan
8879 set $bus = $kgm_pci_cfg_bus_start
8880 while $bus < $kgm_pci_cfg_bus_max
8881 # check for bus:0:0 to see if we should
8882 # probe this bus further
8883 _pci_cfg_value $bus 0x0 0x0 0x0 32
8884 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
8887 while $dev < $kgm_pci_cfg_device_max
8890 while $fcn < $kgm_pci_cfg_function_max
8891 _pci_cfg_value $bus $dev $fcn 0x0 32
8892 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
8894 printf "%03X:%03X:%03X: %02X%02X %02X%02X", $bus, $dev, $fcn, ($kgm_pci_cfg_value >> 8) & 0xFF, $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF
8895 _pci_cfg_value $bus $dev $fcn 0x8 32
8896 printf " %02X | %02X%02X%02X\n", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF
8898 printf " device: %03X:%03X:%03X\n", $bus, $dev, $fcn
8899 pci_cfg_dump $bus $dev $fcn
8912 define pci_cfg_dump_all
8916 document pci_cfg_dump_all
8917 Syntax: (gdb) pci_cfg_dump_all
8918 | dump config spaces for scanned pci devices. the number of busses to scan
8919 | is stored in $kgm_pci_cfg_bus_max. the default for that is 8. you can also
8920 | specify the starting bus with $kgm_pci_cfg_bus_start.
8924 printf "bus:dev:fcn: vendor device rev | class\n"
8925 printf "---------------------------------------\n"
8929 document pci_cfg_scan
8930 Syntax: (gdb) pci_cfg_scan
8931 | scan for pci devices. the number of busses to scan is stored in
8932 | $kgm_pci_cfg_bus_max. the default for that is 8. you can also specify the
8933 | starting bus with $kgm_pci_cfg_bus_start.
8936 define readioportint
8937 set $kgm_readioportint_result = 0xBAD10AD
8938 # set up the manual KDP packet
8939 set manual_pkt.input = 0
8940 set manual_pkt.len = sizeof(kdp_readioport_req_t)
8941 set $kgm_pkt = (kdp_readioport_req_t *)&manual_pkt.data
8942 set $kgm_pkt->hdr.request = KDP_READIOPORT
8943 set $kgm_pkt->hdr.len = sizeof(kdp_readioport_req_t)
8944 set $kgm_pkt->hdr.is_reply = 0
8945 set $kgm_pkt->hdr.seq = 0
8946 set $kgm_pkt->hdr.key = 0
8947 set $kgm_pkt->address = (uint16_t)$arg0
8948 set $kgm_pkt->nbytes = $arg1 >> 3
8949 set $kgm_pkt->lcpu = (uint16_t)$arg2
8950 set manual_pkt.input = 1
8951 # dummy to make sure manual packet is executed
8952 set $kgm_dummy = &_mh_execute_header
8953 set $kgm_pkt = (kdp_readioport_reply_t *)&manual_pkt.data
8954 if ($kgm_pkt->error == 0)
8956 set $kgm_readioportint_result = *((uint8_t *) $kgm_pkt->data)
8959 set $kgm_readioportint_result = *((uint16_t *) $kgm_pkt->data)
8962 set $kgm_readioportint_result = *((uint32_t *) $kgm_pkt->data)
8968 set $lcpu = $kgm_lcpu_self
8972 readioportint $arg0 8 $lcpu
8974 printf ":\t0x%02hhx\n", $kgm_readioportint_result
8978 set $lcpu = $kgm_lcpu_self
8982 readioportint $arg0 16 $lcpu
8984 printf ":\t0x%04hx\n", $kgm_readioportint_result
8988 set $lcpu = $kgm_lcpu_self
8992 readioportint $arg0 32 $lcpu
8994 printf ":\t0x%08x\n", $kgm_readioportint_result
8997 document readioport8
9001 document readioport16
9005 document readioport32
9006 Syntax: (gdb) readioport32 <port> [lcpu (kernel's numbering convention)]
9007 | Read value stored in the specified IO port. The CPU can be optionally
9008 | specified as well.
9011 define writeioportint
9012 # set up the manual KDP packet
9013 set manual_pkt.input = 0
9014 set manual_pkt.len = sizeof(kdp_writeioport_req_t)
9015 set $kgm_pkt = (kdp_writeioport_req_t *)&manual_pkt.data
9016 set $kgm_pkt->hdr.request = KDP_WRITEIOPORT
9017 set $kgm_pkt->hdr.len = sizeof(kdp_writeioport_req_t)
9018 set $kgm_pkt->hdr.is_reply = 0
9019 set $kgm_pkt->hdr.seq = 0
9020 set $kgm_pkt->hdr.key = 0
9021 set $kgm_pkt->address = (uint16_t)$arg0
9022 set $kgm_pkt->nbytes = $arg1 >> 3
9023 set $kgm_pkt->lcpu = (uint16_t)$arg3
9025 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
9028 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
9031 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
9033 set manual_pkt.input = 1
9034 # dummy to make sure manual packet is executed
9035 set $kgm_dummy = &_mh_execute_header
9036 set $kgm_pkt = (kdp_writeioport_reply_t *)&manual_pkt.data
9037 set $kgm_writeioportint_result = $kgm_pkt->error
9041 set $lcpu = $kgm_lcpu_self
9045 writeioportint $arg0 8 $arg1 $lcpu
9048 define writeioport16
9049 set $lcpu = $kgm_lcpu_self
9053 writeioportint $arg0 16 $arg1 $lcpu
9056 define writeioport32
9057 set $lcpu = $kgm_lcpu_self
9061 writeioportint $arg0 32 $arg1 $lcpu
9064 document writeioport8
9065 | See writeioport32.
9068 document writeioport16
9069 | See writeioport32.
9072 document writeioport32
9073 Syntax: (gdb) writeioport32 <port> <value> [lcpu (kernel's numbering convention)]
9074 | Write the value to the specified IO port. The size of the value is
9075 | determined by the name of the command. The CPU used can be optionally
9080 set $kgm_readmsr64int_result = 0xBAD10AD
9081 # set up the manual KDP packet
9082 set manual_pkt.input = 0
9083 set manual_pkt.len = sizeof(kdp_readmsr64_req_t)
9084 set $kgm_pkt = (kdp_readmsr64_req_t *)&manual_pkt.data
9085 set $kgm_pkt->hdr.request = KDP_READMSR64
9086 set $kgm_pkt->hdr.len = sizeof(kdp_readmsr64_req_t)
9087 set $kgm_pkt->hdr.is_reply = 0
9088 set $kgm_pkt->hdr.seq = 0
9089 set $kgm_pkt->hdr.key = 0
9090 set $kgm_pkt->address = (uint32_t)$arg0
9091 set $kgm_pkt->lcpu = (uint16_t)$arg1
9092 set manual_pkt.input = 1
9093 # dummy to make sure manual packet is executed
9094 set $kgm_dummy = &_mh_execute_header
9095 set $kgm_pkt = (kdp_readmsr64_reply_t *)&manual_pkt.data
9096 if ($kgm_pkt->error == 0)
9097 set $kgm_readmsr64int_result = *((uint64_t *) $kgm_pkt->data)
9102 set $lcpu = $kgm_lcpu_self
9106 readmsr64int $arg0 $lcpu
9108 printf ":\t0x%016llx\n", $kgm_readmsr64int_result
9111 define writemsr64int
9112 # set up the manual KDP packet
9113 set manual_pkt.input = 0
9114 set manual_pkt.len = sizeof(kdp_writemsr64_req_t)
9115 set $kgm_pkt = (kdp_writemsr64_req_t *)&manual_pkt.data
9116 set $kgm_pkt->hdr.request = KDP_WRITEMSR64
9117 set $kgm_pkt->hdr.len = sizeof(kdp_writemsr64_req_t)
9118 set $kgm_pkt->hdr.is_reply = 0
9119 set $kgm_pkt->hdr.seq = 0
9120 set $kgm_pkt->hdr.key = 0
9121 set $kgm_pkt->address = (uint32_t)$arg0
9122 set $kgm_pkt->lcpu = (uint16_t)$arg2
9123 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg1
9124 set manual_pkt.input = 1
9125 # dummy to make sure manual packet is executed
9126 set $kgm_dummy = &_mh_execute_header
9127 set $kgm_pkt = (kdp_writemsr64_reply_t *)&manual_pkt.data
9128 set $kgm_writemsr64int_result = $kgm_pkt->error
9132 set $lcpu = $kgm_lcpu_self
9136 writemsr64int $arg0 $arg1 $lcpu
9140 Syntax: (gdb) writemsr64 <msr> <value> [lcpu (kernel's numbering convention)]
9141 | Write <value> to the specified MSR. The CPU can be optionally specified.
9145 Syntax: (gdb) readmsr64 <msr> [lcpu (kernel's numbering convention)]
9146 | Read the specified MSR. The CPU can be optionally specified.
9149 # default if we can't find a registry entry
9150 set $kgm_ioapic_addr = 0xFEC00000
9151 set $kgm_ioapic_init = 0
9153 set $_ioapic_index_off = 0x00
9154 set $_ioapic_data_off = 0x10
9155 set $_ioapic_eoi_off = 0x40
9157 set $_ioapic_index_id = 0x00
9158 set $_ioapic_index_ver = 0x01
9159 set $_ioapic_index_redir_base = 0x10
9161 set $_apic_vector_mask = 0xFF
9162 set $_apic_masked = 0x10000
9163 set $_apic_trigger_level = 0x08000
9164 set $_apic_polarity_high = 0x02000
9165 set $_apic_pending = 0x01000
9168 if $kgm_ioapic_init == 0
9169 strcmp_arg_pack64 'i' 'o' '-' 'a' 'p' 'i' 'c' 0
9170 setfindregistrystr $kgm_strcmp_arg
9172 set $olddepth = $kgm_reg_depth_max
9173 set $kgm_reg_depth_max = 3
9175 set $kgm_reg_depth_max = $olddepth
9177 if $kgm_registry_entry
9178 strcmp_arg_pack64 'P' 'h' 'y' 's' 'i' 'c' 'a' 'l'
9179 set $Physical = $kgm_strcmp_arg
9180 strcmp_arg_pack64 ' ' 'A' 'd' 'd' 'r' 'e' 's' 's'
9181 set $_Address = $kgm_strcmp_arg
9182 setfindregistrystr $Physical $_Address
9184 _findregistryprop $kgm_registry_entry
9185 if $kgm_registry_value
9186 set $kgm_ioapic_addr = ((OSNumber *) $kgm_registry_value)->value
9189 set $kgm_ioapic_index_addr = $kgm_ioapic_addr + $_ioapic_index_off
9190 set $kgm_ioapic_data_addr = $kgm_ioapic_addr + $_ioapic_data_off
9191 set $kgm_ioapic_init = 1
9195 define _ioapic_addr_value
9197 writephysint $kgm_ioapic_index_addr 8 $arg0 $kgm_lcpu_self
9199 writephysint $kgm_ioapic_data_addr 32 $arg1 $kgm_lcpu_self
9201 readphysint $kgm_ioapic_data_addr 32 $kgm_lcpu_self
9202 set $kgm_ioapic_value = $kgm_readphysint_result
9209 printf "[VEC=%3d ", $value & $_apic_vector_mask
9210 if $value & $_apic_masked
9216 if $value & $_apic_trigger_level
9217 printf "TRIG=level "
9222 if $value & $_apic_polarity_high
9228 if $value & $_apic_pending
9229 printf " PEND=yes]\n"
9231 printf " PEND=no ]\n"
9235 define ioapic_read32
9236 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9237 printf "ioapic_read32 not supported on this architecture.\n"
9239 _ioapic_addr_value $arg0
9240 printf "IOAPIC[0x%02X]: 0x%08X\n", $arg0, $kgm_ioapic_value
9244 document ioapic_read32
9245 Syntax: (gdb) ioapic_read <offset>
9246 | Read the IOAPIC register at the offset specified.
9249 define ioapic_write32
9250 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9251 printf "ioapic_write32 not supported on this architecture.\n"
9253 _ioapic_addr_value $arg0 $arg1
9257 document ioapic_write32
9258 Syntax: (gdb) ioapic_write32 <offset> <value>
9259 | Write the IOAPIC register at the offset specified.
9263 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9264 printf "ioapic_dump not supported on this architecture.\n"
9267 _ioapic_addr_value $_ioapic_index_id
9268 printf "IOAPIC[0x%02X] ID: 0x%08X\n", $_ioapic_index_id, $kgm_ioapic_value
9271 _ioapic_addr_value $_ioapic_index_ver
9272 set $maxredir = (($kgm_ioapic_value & 0xFF0000) >> 16) + 1
9274 printf "IOAPIC[0x%02X] VERSION: 0x%08X [", $_ioapic_index_ver, $kgm_ioapic_value
9275 printf "MAXREDIR=%02d PRQ=%d VERSION=0x%02X]\n", $maxredir, ($kgm_ioapic_value >> 15) & 0x1, $kgm_ioapic_value & 0xFF
9277 # all the redir entries
9279 while $i < $maxredir
9280 set $addr0 = $_ioapic_index_redir_base + ($i << 1)
9281 set $addr1 = $addr0 + 1
9282 _ioapic_addr_value $addr1
9283 printf "IOAPIC[0x%02X] IOREDIR%02d: 0x%08X", $addr0, $i, $kgm_ioapic_value
9285 _ioapic_addr_value $addr0
9286 printf "%08X ", $kgm_ioapic_value
9287 _apic_print $kgm_ioapic_value
9293 document ioapic_dump
9294 Syntax: (gdb) ioapic_dump
9295 | Dump all the IOAPIC entries.
9299 set $_lapic_base_addr = 0xFEE00000
9300 set $_lapic_id = 0x20
9301 set $_lapic_version = 0x30
9302 set $_lapic_tpr = 0x80
9303 set $_lapic_apr = 0x90
9304 set $_lapic_ppr = 0xA0
9305 set $_lapic_eoi = 0xB0
9306 set $_lapic_ldr = 0xD0
9307 set $_lapic_dfr = 0xE0
9308 set $_lapic_sivr = 0xF0
9310 set $_lapic_isr_size = 0x10
9311 set $_lapic_isr_num = 8
9312 set $_lapic_isr0 = 0x100
9313 set $_lapic_tmr0 = 0x180
9314 set $_lapic_irr0 = 0x200
9316 set $_lapic_esr = 0x280
9317 set $_lapic_esr_register = 0x80
9318 set $_lapic_esr_recv_vect = 0x40
9319 set $_lapic_esr_send_vect = 0x20
9321 set $_lapic_icr0 = 0x300
9322 set $_lapic_icr1 = 0x310
9324 set $_lapic_lvt_timer = 0x320
9325 set $_lapic_lvt_thermal = 0x330
9326 set $_lapic_lvt_pmcr = 0x340
9327 set $_lapic_lvt_lint0 = 0x350
9328 set $_lapic_lvt_lint1 = 0x360
9329 set $_lapic_lvt_error = 0x370
9331 set $_lapic_icr = 0x380
9332 set $_lapic_ccr = 0x390
9333 set $_lapic_dcr = 0x3E0
9335 set $_apic_cfg_msr = 0x1B
9336 set $_apic_cfg_msr_x2EN = 0x00000C00
9337 set $_x2apic_enabled = -1
9339 # _lapic_addr $offset returns the actual address to use
9341 if $_x2apic_enabled < 0
9342 readmsr64int $_apic_cfg_msr $kgm_lcpu_self
9343 if ($kgm_readmsr64int_result & $_apic_cfg_msr_x2EN) == $_apic_cfg_msr_x2EN
9344 set $_x2apic_enabled = 1
9346 set $_x2apic_enabled = 0
9351 # x2APIC addresses are MSRs that use xAPIC offsets that
9353 set $kgm_lapic_addr = $arg0 >> 4
9355 set $kgm_lapic_addr = $_lapic_base_addr + $arg0
9359 # _lapic_addr_value $offset $lcpu
9360 define _lapic_addr_value
9363 readmsr64int $kgm_lapic_addr $arg1
9364 set $kgm_lapic_value = $kgm_readmsr64int_result
9366 readphysint $kgm_lapic_addr 32 $arg1
9367 set $kgm_lapic_value = $kgm_readphysint_result
9371 # lapic_read32 $offset [$lcpu]
9373 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9374 printf "lapic_read32 not supported on this architecture.\n"
9376 set $lcpu = $kgm_lcpu_self
9380 _lapic_addr_value $arg0 $lcpu
9381 printf "LAPIC[0x%03X]: 0x%08X\n", $arg0, $kgm_lapic_value
9385 document lapic_read32
9386 Syntax: (gdb) apic_read32_cpu <offset> [lcpu (kernel's numbering convention)]
9387 | Read the LAPIC register at the offset specified. The CPU can be optionally
9391 # lapic_write32 $offset $value [$lcpu]
9392 define lapic_write32
9393 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9394 printf "lapic_write32_cpu not supported on this architecture.\n"
9396 set $lcpu = $kgm_lcpu_self
9403 writemsr64int $kgm_lapic_addr $arg1 $lcpu
9405 writephysint $kgm_lapic_addr 32 $arg1 $lcpu
9410 document lapic_write32
9411 Syntax: (gdb) lapic_write32 <offset> <value> [lcpu (kernel's numbering convention)]
9412 | Write the LAPIC register at the offset specified. The CPU can be optionally
9418 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9419 printf "lapic_dump not supported on this architecture.\n"
9421 set $lcpu = $kgm_lcpu_self
9426 _lapic_addr_value $_lapic_id $lcpu
9428 # the above also figures out if we're using an xAPIC or an x2APIC
9429 printf "LAPIC operating mode: "
9436 printf "LAPIC[0x%03X] ID: 0x%08X\n", $_lapic_id, $kgm_lapic_value
9438 _lapic_addr_value $_lapic_version $lcpu
9439 set $lvt_num = ($kgm_lapic_value >> 16) + 1
9440 printf "LAPIC[0x%03X] VERSION: 0x%08X [VERSION=%d MaxLVT=%d]\n", $_lapic_version, $kgm_lapic_value, $kgm_lapic_value & 0xFF, $lvt_num
9442 _lapic_addr_value $_lapic_tpr $lcpu
9443 printf "LAPIC[0x%03X] TASK PRIORITY: 0x%08X\n", $_lapic_tpr, $kgm_lapic_value
9445 _lapic_addr_value $_lapic_ppr $lcpu
9446 printf "LAPIC[0x%03X] PROCESSOR PRIORITY: 0x%08X\n", $_lapic_ppr, $kgm_lapic_value
9448 _lapic_addr_value $_lapic_ldr $lcpu
9449 printf "LAPIC[0x%03X] LOGICAL DEST: 0x%08X\n", $_lapic_ldr, $kgm_lapic_value
9451 _lapic_addr_value $_lapic_dfr $lcpu
9452 printf "LAPIC[0x%03X] DEST FORMAT: 0x%08X\n", $_lapic_dfr, $kgm_lapic_value
9454 _lapic_addr_value $_lapic_sivr $lcpu
9455 printf "LAPIC[0x%03X] SPURIOUS VECTOR: 0x%08X [VEC=%3d ENABLED=%d]\n", $_lapic_sivr, $kgm_lapic_value, $kgm_lapic_value & $_apic_vector_mask, ($kgm_lapic_value & 0x100) >> 8,
9458 while $i < $_lapic_isr_num
9459 set $addr = $_lapic_isr0 + $i * $_lapic_isr_size
9460 _lapic_addr_value $addr $lcpu
9461 printf "LAPIC[0x%03X] ISR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9466 while $i < $_lapic_isr_num
9467 set $addr = $_lapic_tmr0 + $i * $_lapic_isr_size
9468 _lapic_addr_value $addr $lcpu
9469 printf "LAPIC[0x%03X] TMR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9474 while $i < $_lapic_isr_num
9475 set $addr = $_lapic_irr0 + $i * $_lapic_isr_size
9476 _lapic_addr_value $addr $lcpu
9477 printf "LAPIC[0x%03X] IRR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9481 _lapic_addr_value $_lapic_esr $lcpu
9482 printf "LAPIC[0x%03X] ERROR STATUS: 0x%08X ", $_lapic_esr, $kgm_lapic_value
9486 if $kgm_lapic_value & $_lapic_esr_register
9489 if $kgm_lapic_value & $_lapic_esr_recv_vect
9490 printf "Received Vector "
9492 if $kgm_lapic_value & $_lapic_esr_send_vect
9493 printf "Send Vector"
9500 _lapic_addr_value $_lapic_icr1 $lcpu
9501 printf "LAPIC[0x%03X] Interrupt Command: 0x%08X [DEST=%d]\n", $_lapic_icr0, $kgm_lapic_value, $kgm_lapic_value >> 24
9502 _lapic_addr_value $_lapic_icr0 $lcpu
9503 printf " 0x%08X ", $kgm_lapic_value
9504 _apic_print $kgm_lapic_value
9507 _lapic_addr_value $_lapic_lvt_timer $lcpu
9508 printf "LAPIC[0x%03X] LVT Timer: 0x%08X ", $_lapic_lvt_timer, $kgm_lapic_value
9509 _apic_print $kgm_lapic_value
9513 _lapic_addr_value $_lapic_lvt_lint0 $lcpu
9514 printf "LAPIC[0x%03X] LVT LINT0: 0x%08X ", $_lapic_lvt_lint0, $kgm_lapic_value
9515 _apic_print $kgm_lapic_value
9519 _lapic_addr_value $_lapic_lvt_lint1 $lcpu
9520 printf "LAPIC[0x%03X] LVT LINT1: 0x%08X ", $_lapic_lvt_lint1, $kgm_lapic_value
9521 _apic_print $kgm_lapic_value
9525 _lapic_addr_value $_lapic_lvt_error $lcpu
9526 printf "LAPIC[0x%03X] LVT Error: 0x%08X ", $_lapic_lvt_error, $kgm_lapic_value
9527 _apic_print $kgm_lapic_value
9531 _lapic_addr_value $_lapic_lvt_pmcr $lcpu
9532 printf "LAPIC[0x%03X] LVT PerfMon: 0x%08X ", $_lapic_lvt_pmcr, $kgm_lapic_value
9533 _apic_print $kgm_lapic_value
9537 _lapic_addr_value $_lapic_lvt_thermal $lcpu
9538 printf "LAPIC[0x%03X] LVT Thermal: 0x%08X ", $_lapic_lvt_thermal, $kgm_lapic_value
9539 _apic_print $kgm_lapic_value
9542 _lapic_addr_value $_lapic_dcr $lcpu
9543 printf "LAPIC[0x%03X] Timer Divide: 0x%08X [Divide by ", $_lapic_dcr, $kgm_lapic_value
9544 set $kgm_lapic_value = ($kgm_lapic_value & 0x8) >> 1 | $kgm_lapic_value & 0x3
9545 if $kgm_lapic_value == 0x7
9548 printf "%d]\n", 2 << $kgm_lapic_value
9551 _lapic_addr_value $_lapic_icr $lcpu
9552 printf "LAPIC[0x%03X] Timer Init Count: 0x%08X\n", $_lapic_icr, $kgm_lapic_value
9554 _lapic_addr_value $_lapic_ccr $lcpu
9555 printf "LAPIC[0x%03X] Timer Cur Count: 0x%08X\n", $_lapic_ccr, $kgm_lapic_value
9560 Syntax: (gdb) lapic_dump [lcpu (kernel's numbering convention)]
9561 | Dump all the LAPIC entries. The CPU can be optionally specified.
9564 define showknoteheader
9565 printf " knote filter ident kn_ptr status\n"
9569 set $kgm_knotep = ((struct knote *) $arg0)
9573 set $kgm_filt = -$kgm_knotep->kn_kevent.filter
9575 printf "EVFILT_READ "
9578 printf "EVFILT_WRITE "
9581 printf "EVFILT_AIO "
9584 printf "EVFILT_VNODE "
9587 printf "EVFILT_PROC "
9590 printf "EVFILT_SIGNAL "
9593 printf "EVFILT_TIMER "
9596 printf "EVFILT_MACHPORT"
9601 if ($kgm_filt == 10)
9602 printf "EVFILT_USER "
9604 if ($kgm_filt == 11)
9605 printf "EVFILT_SESSION "
9607 printf "%7d ", $kgm_knotep->kn_kevent.ident
9608 showptr $kgm_knotep->kn_ptr.p_fp
9610 if ($kgm_knotep->kn_status == 0)
9613 if ($kgm_knotep->kn_status & 0x01)
9616 if ($kgm_knotep->kn_status & 0x02)
9619 if ($kgm_knotep->kn_status & 0x04)
9622 if ($kgm_knotep->kn_status & 0x08)
9625 if ($kgm_knotep->kn_status & 0x10)
9628 if ($kgm_knotep->kn_status & 0x20)
9631 if ($kgm_knotep->kn_status & 0x40)
9638 define showprocknotes
9640 set $kgm_fdp = ((proc_t)$arg0)->p_fd
9641 set $kgm_knlist = $kgm_fdp->fd_knlist
9643 while (($i < $kgm_fdp->fd_knlistsize) && ($kgm_knlist != 0))
9644 set $kgm_kn = ((struct knote *)$kgm_knlist[$i].slh_first)
9645 while ($kgm_kn != 0)
9646 showknoteint $kgm_kn
9647 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
9651 set $kgm_knhash = $kgm_fdp->fd_knhash
9653 while (($i < $kgm_fdp->fd_knhashmask + 1) && ($kgm_knhash != 0))
9654 set $kgm_kn = ((struct knote *)$kgm_knhash[$i].slh_first)
9655 while ($kgm_kn != 0)
9656 showknoteint $kgm_kn
9657 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
9663 define showallknotes
9664 set $kgm_head_taskp = &tasks
9665 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9666 while $kgm_taskp != $kgm_head_taskp
9668 showtaskint $kgm_taskp
9669 showprocknotes $kgm_taskp->bsd_info
9670 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9673 document showprocknotes
9674 Syntax: showprocknotes <proc>
9675 | Displays filter and status information for every kevent registered for
9680 # Device node related debug macros
9684 set $kgm_tty = (struct tty *) $arg0
9685 printf "tty struct at "
9688 printf "-last input to raw queue:\n"
9689 p $kgm_tty->t_rawq->c_cs
9690 printf "-last input to canonical queue:\n"
9691 p $kgm_tty->t_canq->c_cs
9692 printf "-last output data:\n"
9693 p $kgm_tty->t_outq->c_cs
9695 if ($kgm_tty->t_state & 0x00000001)
9696 printf " TS_SO_OLOWAT (Wake up when output <= low water)\n"
9698 if ($kgm_tty->t_state & 0x00000002)
9699 printf " TS_ASYNC (async I/O mode)\n"
9701 printf " - (synchronous I/O mode)\n"
9703 if ($kgm_tty->t_state & 0x00000004)
9704 printf " TS_BUSY (Draining output)\n"
9706 if ($kgm_tty->t_state & 0x00000008)
9707 printf " TS_CARR_ON (Carrier is present)\n"
9709 printf " - (Carrier is NOT present)\n"
9711 if ($kgm_tty->t_state & 0x00000010)
9712 printf " TS_FLUSH (Outq has been flushed during DMA)\n"
9714 if ($kgm_tty->t_state & 0x00000020)
9715 printf " TS_ISOPEN (Open has completed)\n"
9717 printf " - (Open has NOT completed)\n"
9719 if ($kgm_tty->t_state & 0x00000040)
9720 printf " TS_TBLOCK (Further input blocked)\n"
9722 if ($kgm_tty->t_state & 0x00000080)
9723 printf " TS_TIMEOUT (Wait for output char processing)\n"
9725 if ($kgm_tty->t_state & 0x00000100)
9726 printf " TS_TTSTOP (Output paused)\n"
9728 if ($kgm_tty->t_state & 0x00000200)
9729 printf " TS_WOPEN (Open in progress)\n"
9731 if ($kgm_tty->t_state & 0x00000400)
9732 printf " TS_XCLUDE (Tty requires exclusivity)\n"
9734 if ($kgm_tty->t_state & 0x00000800)
9735 printf " TS_BKSL (State for lowercase \\ work)\n"
9737 if ($kgm_tty->t_state & 0x00001000)
9738 printf " TS_CNTTB (Counting tab width, ignore FLUSHO)\n"
9740 if ($kgm_tty->t_state & 0x00002000)
9741 printf " TS_ERASE (Within a \\.../ for PRTRUB)\n"
9743 if ($kgm_tty->t_state & 0x00004000)
9744 printf " TS_LNCH (Next character is literal)\n"
9746 if ($kgm_tty->t_state & 0x00008000)
9747 printf " TS_TYPEN (Retyping suspended input (PENDIN))\n"
9749 if ($kgm_tty->t_state & 0x00010000)
9750 printf " TS_CAN_BYPASS_L_RINT (Device in "raw" mode)\n"
9752 if ($kgm_tty->t_state & 0x00020000)
9753 printf " TS_CONNECTED (Connection open)\n"
9755 printf " - (Connection NOT open)\n"
9757 if ($kgm_tty->t_state & 0x00040000)
9758 printf " TS_SNOOP (Device is being snooped on)\n"
9760 if ($kgm_tty->t_state & 0x80000)
9761 printf " TS_SO_OCOMPLETE (Wake up when output completes)\n"
9763 if ($kgm_tty->t_state & 0x00100000)
9764 printf " TS_ZOMBIE (Connection lost)\n"
9766 if ($kgm_tty->t_state & 0x00200000)
9767 printf " TS_CAR_OFLOW (For MDMBUF - handle in driver)\n"
9769 if ($kgm_tty->t_state & 0x00400000)
9770 printf " TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)\n"
9772 if ($kgm_tty->t_state & 0x00800000)
9773 printf " TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)\n"
9775 # xxx todo: do we care about decoding flags?
9776 printf "flags: 0x%08x\n", $kgm_tty->t_flags
9777 printf "foreground process group: "
9778 showptr $kgm_tty->t_pgrp
9780 printf "enclosing session: "
9781 showptr $kgm_tty->t_session
9784 # XXX todo: decode these flags, someday
9785 printf " Input flags: 0x%08x\n", $kgm_tty->t_termios.c_iflag
9786 printf " Output flags: 0x%08x\n", $kgm_tty->t_termios.c_oflag
9787 printf " Control flags: 0x%08x\n", $kgm_tty->t_termios.c_cflag
9788 printf " Local flags: 0x%08x\n", $kgm_tty->t_termios.c_lflag
9789 printf " Input speed: %d\n", $kgm_tty->t_termios.c_ispeed
9790 printf " Output speed: %d\n", $kgm_tty->t_termios.c_ospeed
9791 # XXX todo: useful to decode t_winsize? t_iokit? c_cc? anything else?
9792 printf "high watermark: %d bytes\n", $kgm_tty->t_hiwat
9793 printf "low watermark: %d bytes\n", $kgm_tty->t_lowat
9797 # _showwhohas <major> <minor>
9807 set $kgm_swh_devnode_dev = (((int) $arg0) << 24) | (int) $arg1
9808 # iterate all tasks to iterate all processes to iterate all
9809 # open files in each process to see who has a given major/minor
9811 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9812 while $kgm_taskp != $kgm_head_taskp
9813 set $kgm_procp = (proc_t) $kgm_taskp->bsd_info
9814 set $kgm_spf_filedesc = $kgm_procp->p_fd
9815 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
9816 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
9817 set $kgm_spf_count = 0
9818 while (($kgm_spf_ofiles != 0) && ($kgm_spf_count <= $kgm_spf_last))
9819 # only files currently open
9820 if ($kgm_spf_ofiles[$kgm_spf_count] != 0)
9821 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
9822 if ($kgm_spf_fg->fg_type == 1)
9823 # display fd #, fileglob & vnode address, proc name
9824 set $kgm_swh_m_vnode = (vnode_t) $kgm_spf_fg->fg_data
9825 set $kgm_swh_m_vtype = (enum vtype) $kgm_swh_m_vnode->v_type
9826 if (($kgm_swh_m_vtype == VBLK) || ($kgm_swh_m_vtype == VCHR)) && ((((devnode_t *)$kgm_swh_m_vnode->v_data)->dn_typeinfo.dev) == $kgm_swh_devnode_dev)
9827 printf "%-5d ", $kgm_spf_count
9830 showptr $kgm_swh_m_vnode
9833 printf " %s\n", $kgm_procp->p_comm
9837 set $kgm_spf_count = $kgm_spf_count + 1
9840 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9844 define _showvnodedev_cpty
9845 set $kgm_ptmx_major = (int) $arg0
9846 set $kgm_ptmx_minor = (int) $arg1
9847 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
9848 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
9849 printf " ptmx_ioctl struct at "
9850 showptr $kgm_ptmx_ioctl
9853 if ($kgm_ptmx_ioctl->pt_flags & 0x0008)
9854 printf " PF_PKT (packet mode)\n"
9856 if ($kgm_ptmx_ioctl->pt_flags & 0x0010)
9857 printf " PF_STOPPED (user told stopped)\n"
9859 if ($kgm_ptmx_ioctl->pt_flags & 0x0020)
9860 printf " PF_REMOTE (remote and flow controlled input)\n"
9862 if ($kgm_ptmx_ioctl->pt_flags & 0x0040)
9865 if ($kgm_ptmx_ioctl->pt_flags & 0x0080)
9866 printf " PF_UCNTL (user control mode)\n"
9868 if ($kgm_ptmx_ioctl->pt_flags & 0x0100)
9869 printf " PF_UNLOCKED (slave unlock - master open resets)\n"
9871 if ($kgm_ptmx_ioctl->pt_flags & 0x0200)
9872 printf " PF_OPEN_M (master is open)\n"
9873 # XXX we should search for who has the master open, but
9874 # XXX each master gets the same minor, even though it
9875 # XXX gets a different vnode. we chold probably change
9876 # XXX this, but to do it we would need some way of
9877 # XXX expressing the information in the vnode structure
9878 # XXX somewhere. If we *did* change it, it would buy us
9879 # XXX the ability to determine who has the corresponding
9880 # XXX master end of the pty open
9882 printf " PF_OPEN_M (master is closed)\n"
9884 if ($kgm_ptmx_ioctl->pt_flags & 0x0400)
9885 printf " PF_OPEN_S (slave is open)\n"
9886 printf "---vvvvv--- fds open on this device ---vvvvv---\n"
9887 _showwhohas ($kgm_ptmx_major) ($kgm_ptmx_minor)
9888 printf "---^^^^^--- fds open on this device ---^^^^^---\n"
9890 printf " - (slave is closed)\n"
9892 printf "TTY Specific Information\n"
9893 _showtty $kgm_ptmx_ioctl->pt_tty
9898 set $kgm_vnode = (vnode_t) $arg0
9899 set $kgm_vtype = (enum vtype) $kgm_vnode->v_type
9900 if (($kgm_vtype == VBLK) || ($kgm_vtype == VCHR))
9901 set $kgm_devnode = (devnode_t *) $kgm_vnode->v_data
9902 set $kgm_devnode_dev = $kgm_devnode->dn_typeinfo.dev
9903 set $kgm_devnode_major = ($kgm_devnode_dev >> 24) & 0xff
9904 set $kgm_devnode_minor = $kgm_devnode_dev & 0x00ffffff
9906 # boilerplate device information for a vnode
9907 printf "Device Info:\n"
9912 if ($kgm_vtype == VBLK)
9915 if ($kgm_vtype == VCHR)
9919 printf " name: %s\n", $kgm_vnode->v_name
9920 printf " major, minor: %d, %d\n", $kgm_devnode_major, $kgm_devnode_minor
9921 printf " mode 0%o\n", $kgm_devnode->dn_mode
9922 printf " owner (u,g): %d %d", $kgm_devnode->dn_uid, $kgm_devnode->dn_gid
9925 # decode device specific data
9926 printf "Device Specific Information: "
9927 if ($kgm_vtype == VBLK)
9928 printf " Sorry, I do not know how to decode block devices yet!\n"
9929 printf " Maybe you can write me!"
9931 if ($kgm_vtype == VCHR)
9932 # Device information; this is scanty
9934 if ($kgm_devnode_major > 42) || ($kgm_devnode_major < 0)
9935 printf "Invalid major #\n"
9937 # static assignments in conf
9938 if ($kgm_devnode_major == 0)
9939 printf "Console mux device\n"
9941 if ($kgm_devnode_major == 2)
9942 printf "Current tty alias\n"
9944 if ($kgm_devnode_major == 3)
9945 printf "NULL device\n"
9947 if ($kgm_devnode_major == 4)
9948 printf "Old pty slave\n"
9950 if ($kgm_devnode_major == 5)
9951 printf "Old pty master\n"
9953 if ($kgm_devnode_major == 6)
9954 printf "Kernel log\n"
9956 if ($kgm_devnode_major == 12)
9957 printf "Memory devices\n"
9959 # Statically linked dynamic assignments
9960 if cdevsw[$kgm_devnode_major].d_open == ptmx_open
9961 printf "Cloning pty master\n"
9962 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
9964 if cdevsw[$kgm_devnode_major].d_open == ptsd_open
9965 printf "Cloning pty slave\n"
9966 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
9968 printf "RESERVED SLOT\n"
9982 printf " is not a device\n"
9985 printf "| Usage:\n|\n"
9989 document showvnodedev
9990 Syntax: (gdb) showvnodedev <vnode>
9991 | showvnodedev Display information about a device vnode
9998 printf "| Usage:\n|\n"
10003 Syntax: (gdb) showtty <tty struct>
10004 | showtty Display information about a struct tty
10007 define showeventsourceobject
10008 set $kgm_vt = *((void **) $arg1)
10010 set $kgm_vt = $kgm_vt - 16
10014 document showeventsourceobject
10015 Syntax: (gdb) showeventsourceobject <prefix> <object>
10016 | Routine to display information about an IOEventSource subclass.
10019 define showworkloopeventsources
10020 set $kgm_eventsource = (struct IOEventSource*)$arg0
10021 while $kgm_eventsource != 0
10023 printf "EventSource:\t"
10024 showptr $kgm_eventsource
10025 printf " Description: "
10026 showeventsourceobject _ $kgm_eventsource
10028 if $kgm_eventsource->action != 0
10030 printf "Action: \t"
10031 pcprint $kgm_eventsource->action
10034 if $kgm_eventsource->owner != 0
10037 showptr $kgm_eventsource->owner
10038 printf " Description: "
10039 showeventsourceobject _ $kgm_eventsource->owner
10042 set $kgm_eventsource = $kgm_eventsource->eventChainNext
10046 document showworkloopeventsources
10047 Syntax: (gdb) showworkloopeventsources
10048 | Routine to walk an IOEventSource chain associated with an IOWorkLoop and print information
10049 | about each event source in the chain.
10052 define showworkloopheader
10055 printf " workloop "
10057 printf " pri state\tLockGroupName\n"
10059 document showworkloopheader
10060 Syntax: (gdb) showworkloopheader
10061 | Routine to print out header info about an IOKit workloop.
10064 define showworkloop
10065 set $kgm_workloopthread = (struct thread*)$arg0
10066 set $kgm_workloop = (struct IOWorkLoop*)$arg1
10067 showptr $kgm_workloopthread
10069 showptr $kgm_workloop
10070 printf " %3d ", $kgm_workloopthread.sched_pri
10071 set $kgm_state = $kgm_workloopthread.state
10072 if $kgm_state & 0x80
10075 if $kgm_state & 0x40
10078 if $kgm_state & 0x20
10081 if $kgm_state & 0x10
10084 if $kgm_state & 0x08
10087 if $kgm_state & 0x04
10090 if $kgm_state & 0x02
10093 if $kgm_state & 0x01
10097 set $kgm_gateLock = ( struct _IORecursiveLock *)$kgm_workloop->gateLock
10098 set $kgm_lockGroup = (struct _lck_grp_*)($kgm_gateLock->group)
10099 printf "%s", $kgm_lockGroup->lck_grp_name
10101 showworkloopeventsources $kgm_workloop->eventChain
10103 document showworkloop
10104 Syntax: (gdb) showworkloop <thread> <workloop>
10105 | Routine to print out info about an IOKit workloop.
10108 define showallworkloopthreads
10109 set $kgm_head_taskp = &tasks
10110 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
10111 set $kgm_head_actp = &($kgm_taskp->threads)
10112 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
10113 while $kgm_actp != $kgm_head_actp
10114 if ($kgm_actp->continuation == _ZN10IOWorkLoop10threadMainEv)
10116 showworkloop $kgm_actp $kgm_actp->parameter
10118 if ($kgm_actp->kernel_stack != 0)
10119 if ($kgm_mtype == $kgm_mtype_x86_64)
10120 #Warning: Grokking stack looking for hopeful workloops until we squirrel some info in thread_t.
10121 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0xB8))
10123 if ($kgm_mtype == $kgm_mtype_i386)
10124 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0x3C))
10127 if ($kgm_workloop != 0)
10128 set $kgm_vt = *((void **) $kgm_workloop)
10130 set $kgm_vt = $kgm_vt - 16
10132 if ($kgm_vt == &_ZTV10IOWorkLoop)
10134 showworkloop $kgm_actp $kgm_workloop
10139 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
10143 document showallworkloopthreads
10144 Syntax: (gdb) showallworkloopthreads
10145 | Routine to print out info about all IOKit workloop threads in the system. This macro will find
10146 | all IOWorkLoop threads blocked in continuations and on i386 and x86_64 systems will make a
10147 | best-effort guess to find any workloops that are actually not blocked in a continuation. For a
10148 | complete list, it is best to compare the output of this macro against the output of 'showallstacks'.
10151 define showthreadfortid
10152 set $kgm_id_found = 0
10154 set $kgm_head_taskp = &tasks
10155 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
10156 while $kgm_taskp != $kgm_head_taskp
10157 set $kgm_head_actp = &($kgm_taskp->threads)
10158 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
10159 while $kgm_actp != $kgm_head_actp
10160 set $kgm_thread = *(struct thread *)$kgm_actp
10161 set $kgm_thread_id = $kgm_thread.thread_id
10162 if ($kgm_thread_id == $arg0)
10165 set $kgm_id_found = 1
10168 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
10170 if ($kgm_id_found == 1)
10173 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
10175 if ($kgm_id_found == 0)
10176 printf "Not a valid thread_id\n"
10180 document showthreadfortid
10181 Syntax: showthreadfortid <thread_id>
10182 |The thread structure contains a unique thread_id value for each thread.
10183 |This command is used to retrieve the address of the thread structure(thread_t)
10184 |corresponding to a given thread_id.
10187 define showtaskbusyports
10188 set $kgm_isp = ((task_t)$arg0)->itk_space
10189 set $kgm_iindex = 0
10190 while ( $kgm_iindex < $kgm_isp->is_table_size )
10191 set $kgm_iep = &($kgm_isp->is_table[$kgm_iindex])
10192 if $kgm_iep->ie_bits & 0x00020000
10193 set $kgm_port = ((ipc_port_t)$kgm_iep->ie_object)
10194 if $kgm_port->ip_messages.data.port.msgcount > 0
10198 set $kgm_iindex = $kgm_iindex + 1
10202 document showtaskbusyports
10203 Syntax: showtaskbusyports <task>
10204 |Routine to print information about receive rights belonging to this task that
10205 |have enqueued messages. This is often a sign of a blocked or hung process.
10208 define showallbusyports
10209 set $kgm_head_taskp = &tasks
10210 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
10211 while $kgm_cur_taskp != $kgm_head_taskp
10212 showtaskbusyports $kgm_cur_taskp
10213 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
10217 document showallbusyports
10218 Syntax: showallbusyports
10219 |Routine to print information about all receive rights on the system that
10220 |have enqueued messages.
10227 printf "Attempting to attach to localhost...\n"
10228 kdp-reattach localhost
10232 document kdp-connect
10233 Syntax: (gdb) kdpconnect <address-of-remote-host>
10234 | Attach to the machine with given hostname or IP address, or 'localhost' if blank