]> git.saurik.com Git - apple/xnu.git/blob - kgmacros
xnu-1456.1.26.tar.gz
[apple/xnu.git] / kgmacros
1 # Kernel gdb macros
2 #
3 # These gdb macros should be useful during kernel development in
4 # determining what's going on in the kernel.
5 #
6 # All the convenience variables used by these macros begin with $kgm_
7
8 set print asm-demangle on
9 set cp-abi gnu-v2
10
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
15
16 echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n
17
18 define kgm
19 printf ""
20 echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n
21 end
22
23 document kgm
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>
29 |
30 | The following macros are available in this package:
31 | showversion Displays a string describing the remote kernel version
32 |
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
44 |
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)
51 |
52 | setfindregistrystr Set the encoded string for matching with
53 | findregistryentry or findregistryprop (created from
54 | strcmp_arg_pack64)
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
58 | the encoded string
59 |
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 | showtaskbusyports Display all of the task's ports with unread messages
68 |
69 | showact Display info about a thread specified by activation
70 | showactstack Display the stack for a thread specified by activation
71 |
72 | showmap Display info about the specified vm_map
73 | showmapvme Display a summary list of the specified vm_map's entries
74 |
75 | showipc Display info about the specified ipc space
76 | showrights Display a summary list of all the rights in an ipc space
77 |
78 | showpid Display info about the process identified by pid
79 | showproc Display info about the process identified by proc struct
80 | showprocinfo Display detailed info about the process identified by proc struct
81 | showprocfiles Given a proc_t pointer, display the list of open file descriptors
82 | showproclocks Given a proc_t pointer, display the list of advisory file locks
83 | zombproc Print out all procs in the zombie list
84 | allproc Print out all process in the system not in the zombie list
85 | zombstacks Print out all stacks of tasks that are exiting
86 |
87 | showinitchild Print out all processes in the system which are children of init process
88 |
89 | showkmod Display info about a kernel module
90 | showkmodaddr Given an address, display the kernel module and offset
91 |
92 | dumpcallqueue Dump out all the entries given a queue head
93 |
94 | showallmtx Display info about mutexes usage
95 | showallrwlck Display info about reader/writer locks usage
96 |
97 | zprint Display info about the memory zones
98 | showioalloc Display info about iokit allocations
99 | paniclog Display the panic log info
100 |
101 | switchtoact Switch to different context specified by activation
102 | switchtoctx Switch to different context
103 | showuserstack Display numeric backtrace of the user stack for an
104 | activation
105 |
106 | switchtouserthread Switch to the user context of the specified thread
107 | resetstacks Return to the original kernel context
108 |
109 | resetctx Reset context
110 | resume_on Resume when detaching from gdb
111 | resume_off Don't resume when detaching from gdb
112 |
113 | sendcore Configure kernel to send a coredump to the specified IP
114 | disablecore Configure the kernel to disable coredump transmission
115 | switchtocorethread Corefile version of "switchtoact"
116 | resetcorectx Corefile version of "resetctx"
117 |
118 | readphys8 Reads the specified untranslated address (8-bit read)
119 | readphys16 Reads the specified untranslated address (16-bit read)
120 | readphys32 Reads the specified untranslated address (32-bit read)
121 | readphys64 Reads the specified untranslated address (64-bit read)
122 | writephys8 Writes to the specified untranslated address (8-bit write)
123 | writephys16 Writes to the specified untranslated address (16-bit write)
124 | writephys32 Writes to the specified untranslated address (32-bit write)
125 | writephys64 Writes to the specified untranslated address (64-bit write)
126 |
127 | readioport8 Read 8-bits from the specified I/O Port
128 | readioport16 Read 16-bits from the specified I/O Port
129 | readioport32 Read 32-bits from the specified I/O Port
130 | writeioport8 Write 8-bits into the specified I/O Port
131 | writeioport16 Write 16-bits into the specified I/O Port
132 | writeioport32 Write 32-bits into the specified I/O Port
133 |
134 | readmsr64 Read 64-bits from the specified MSR
135 | writemsr64 Write 64-bits into the specified MSR
136 |
137 | rtentry_showdbg Print the debug information of a route entry
138 | rtentry_trash Walk the list of trash route entries
139 |
140 | inifa_showdbg Print the debug information of an IPv4 interface address
141 | in6ifa_showdbg Print the debug information of an IPv6 interface address
142 |
143 | mbuf_walkpkt Walk the mbuf packet chain (m_nextpkt)
144 | mbuf_walk Walk the mbuf chain (m_next)
145 | mbuf_buf2slab Find the slab structure of the corresponding buffer
146 | mbuf_buf2mca Find the mcache audit structure of the corresponding mbuf
147 | mbuf_showmca Print the contents of an mbuf mcache audit structure
148 | mbuf_showactive Print all active/in-use mbuf objects
149 | mbuf_showinactive Print all freed/in-cache mbuf objects
150 | mbuf_showall Print all mbuf objects
151 | mbuf_slabs Print all slabs in the group
152 | mbuf_slabstbl Print slabs table
153 | mbuf_stat Print extended mbuf allocator statistics
154 |
155 | mcache_walkobj Walk the mcache object chain (obj_next)
156 | mcache_stat Print all mcaches in the system
157 | mcache_showcache Display the number of objects in the cache
158 |
159 | showbootargs Display boot arguments passed to the target kernel
160 | showbootermemorymap Dump phys memory map from EFI
161 |
162 | systemlog Display the kernel's printf ring buffer
163 |
164 | hexdump Show the contents of memory as a hex/ASCII dump
165 |
166 | showvnodepath Print the path for a vnode
167 | showvnodelocks Display list of advisory locks held/blocked on a vnode
168 | showvnodedev Display information about a device vnode
169 | showtty Display information about a struct tty
170 | showallvols Display a summary of mounted volumes
171 | showvnode Display info about one vnode
172 | showvolvnodes Display info about all vnodes of a given volume
173 | showvolbusyvnodes Display info about busy (iocount!=0) vnodes of a given volume
174 | showallbusyvnodes Display info about all busy (iocount!=0) vnodes
175 | showallvnodes Display info about all vnodes
176 | print_vnode Print out the fields of a vnode struct
177 | showprocvnodes Print out all the open fds which are vnodes in a process
178 | showallprocvnodes Print out all the open fds which are vnodes in any process
179 | showmountvnodes Print the vnode list
180 | showmountallvnodes Print the vnode inactive list
181 | showworkqvnodes Print the vnode worker list
182 | shownewvnodes Print the new vnode list
183 |
184 | ifconfig display ifconfig-like output
185 | showifaddrs show the list of addresses for the given ifp
186 | showifmultiaddrs show the list of multicast addresses for the given ifp
187 |
188 | showsocket Display information about a socket
189 | showprocsockets Given a proc_t pointer, display information about its sockets
190 | showallprocsockets Display information about the sockets of all the processes
191 |
192 | show_tcp_pcbinfo Display the list of the TCP protocol control blocks
193 | show_tcp_timewaitslots Display the list of the TCP protocol control blocks in TIMEWAIT
194 | show_udp_pcbinfo Display the list of UDP protocol control blocks
195 |
196 | show_rt_inet Display the IPv4 routing table
197 | show_rt_inet6 Display the IPv6 routing table
198 |
199 | showallpmworkqueues Display info about all IOPMWorkQueue objects
200 | showregistrypmstate Display power management state for all IOPower registry entries
201 | showioservicepm Display the IOServicePM object
202 | showstacksaftertask showallstacks starting after a given task
203 | showstacksafterthread showallstacks starting after a given thread
204 |
205 | showMCAstate Print machine-check register state after MC exception.
206 |
207 | showallgdbstacks Cause GDB to trace all thread stacks
208 | showallgdbcorestacks Corefile equivalent of "showallgdbstacks"
209 | kdp-reenter Schedule reentry into the debugger and continue.
210 | kdp-reboot Restart remote target
211 |
212 | zstack Print zalloc caller stack (zone leak debugging)
213 | findoldest Find oldest zone leak debugging record
214 | countpcs Print how often a pc occurs in the zone leak log
215 |
216 | pmap_walk Perform a page-table walk
217 | pmap_vtop Translate a virtual address to physical address
218 |
219 | showuserlibraries Show binary images known by dyld in the target task
220 |
221 | showthreadfortid Displays the address of the thread structure for a given thread_id value.
222 |
223 | strcmp_nomalloc A version of strcmp that avoids the use of malloc
224 | through the use of encoded strings created via
225 | strcmp_arg_pack64.
226 | strcmp_arg_pack64 Pack a string into a 64-bit quantity for use by
227 | strcmp_nomalloc
228 |
229 | pci_cfg_read8 Read 8-bits from a PCI config space register
230 | pci_cfg_read16 Read 16-bits from a PCI config space register
231 | pci_cfg_read32 Read 32-bits from a PCI config space register
232 | pci_cfg_write8 Write 8-bits into a PCI config space register
233 | pci_cfg_write16 Write 16-bits into a PCI config space register
234 | pci_cfg_write32 Write 32-bits into a PCI config space register
235 | pci_cfg_dump Dump entire config space for a PCI device
236 | pci_cfg_scan Perform a scan for PCI devices
237 | pci_cfg_dump_all Dump config spaces for all detected PCI devices
238 |
239 | lapic_read32 Read APIC entry
240 | lapic_write32 Write APIC entry
241 | lapic_dump Dump APIC entries
242 |
243 | ioapic_read32 Read IOAPIC entry
244 | ioapic_write32 Write IOAPIC entry
245 | ioapic_dump Dump IOAPIC entries
246 |
247 | Type "help <macro>" for more specific help on a particular macro.
248 | Type "show user <macro>" to see what the macro is really doing.
249 end
250
251 # This macro should appear before any symbol references, to facilitate
252 # a gdb "source" without a loaded symbol file.
253 define showversion
254 kdp-kernelversion
255 end
256
257 document showversion
258 Syntax: showversion
259 | Read the kernel version string from a fixed address in low
260 | memory. Useful if you don't know which kernel is on the other end,
261 | and need to find the appropriate symbols. Beware that if you've
262 | loaded a symbol file, but aren't connected to a remote target,
263 | the version string from the symbol file will be displayed instead.
264 | This macro expects to be connected to the remote kernel to function
265 | correctly.
266 end
267
268 set $kgm_mtype_ppc = 0x00000012
269 set $kgm_mtype_arm = 0x0000000C
270
271 set $kgm_mtype_i386 = 0x00000007
272 set $kgm_mtype_x86_64 = 0x01000007
273 set $kgm_mtype_x86_any = $kgm_mtype_i386
274 set $kgm_mtype_x86_mask = 0xFEFFFFFF
275
276 set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
277 set $kgm_lp64 = $kgm_mtype & 0x01000000
278
279 set $kgm_lcpu_self = 0xFFFE
280
281 set $kgm_reg_depth = 0
282 set $kgm_reg_depth_max = 0xFFFF
283 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
284 set $kgm_namekey = (OSSymbol *) 0
285 set $kgm_childkey = (OSSymbol *) 0
286
287 set $kgm_show_object_addrs = 0
288 set $kgm_show_object_retain = 0
289 set $kgm_show_props = 0
290 set $kgm_show_data_alwaysbytes = 0
291
292 set $kgm_show_kmod_syms = 0
293
294 # Print a pointer
295 define showptr
296 if $kgm_lp64
297 printf "0x%016llx", $arg0
298 else
299 printf "0x%08x", $arg0
300 end
301 end
302
303 # for headers, leave 8 chars for LP64 pointers
304 define showptrhdrpad
305 if $kgm_lp64
306 printf " "
307 end
308 end
309
310 define showkmodheader
311 printf "kmod "
312 showptrhdrpad
313 printf " address "
314 showptrhdrpad
315 printf " size "
316 showptrhdrpad
317 printf " id refs version name\n"
318 end
319
320 define showkmodint
321 set $kgm_kmodp = (struct kmod_info *)$arg0
322 showptr $kgm_kmodp
323 printf " "
324 showptr $kgm_kmodp->address
325 printf " "
326 showptr $kgm_kmodp->size
327 printf " "
328 printf "%3d ", $kgm_kmodp->id
329 printf "%5d ", $kgm_kmodp->reference_count
330 printf "%10s ", $kgm_kmodp->version
331 printf "%s\n", $kgm_kmodp->name
332 end
333
334 # cached info of the last kext found, to speed up subsequent lookups
335 set $kgm_pkmod = 0
336 set $kgm_pkmodst = 0
337 set $kgm_pkmoden = 0
338
339 define showkmodaddrint
340 showptr $arg0
341 if ((unsigned long)$arg0 >= (unsigned long)$kgm_pkmodst) && ((unsigned long)$arg0 < (unsigned long)$kgm_pkmoden)
342 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_pkmodst)
343 printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off
344 else
345 set $kgm_kmodp = (struct kmod_info *)kmod
346 if ($kgm_mtype == $kgm_mtype_x86_64) && ($arg0 >= (unsigned long)&_mh_execute_header)
347 # kexts are loaded below the kernel for x86_64
348 set $kgm_kmodp = 0
349 end
350 while $kgm_kmodp
351 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_kmodp->address)
352 if ($kgm_kmodp->address <= $arg0) && ($kgm_off < $kgm_kmodp->size)
353 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off
354 set $kgm_pkmod = $kgm_kmodp
355 set $kgm_pkmodst = $kgm_kmodp->address
356 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmodp->size
357 set $kgm_kmodp = 0
358 else
359 set $kgm_kmodp = $kgm_kmodp->next
360 end
361 end
362 end
363 end
364
365 define showkmodaddr
366 showkmodaddrint $arg0
367 end
368
369 document showkmodaddr
370 Syntax: (gdb) showkmodaddr <addr>
371 | Given an address, print the offset and name for the kmod containing it
372 end
373
374 define showkmod
375 showkmodheader
376 showkmodint $arg0
377 end
378 document showkmod
379 Syntax: (gdb) showkmod <kmod>
380 | Routine to print info about a kernel module
381 end
382
383 define showallkmods
384 showkmodheader
385 set $kgm_kmodp = (struct kmod_info *)kmod
386 while $kgm_kmodp
387 showkmodint $kgm_kmodp
388 set $kgm_kmodp = $kgm_kmodp->next
389 end
390 end
391 document showallkmods
392 Syntax: (gdb) showallkmods
393 | Routine to print a summary listing of all the kernel modules
394 end
395
396 define showactheader
397 printf " "
398 showptrhdrpad
399 printf " thread "
400 showptrhdrpad
401 printf " thread_id "
402 showptrhdrpad
403 printf " processor "
404 showptrhdrpad
405 printf " pri io_policy state wait_queue"
406 showptrhdrpad
407 printf " wait_event\n"
408 end
409
410
411 define showactint
412 printf " "
413 showptrhdrpad
414 set $kgm_thread = *(struct thread *)$arg0
415 showptr $arg0
416 if ($kgm_thread.static_param)
417 printf "[WQ]"
418 else
419 printf " "
420 end
421 printf " %7ld ", $kgm_thread.thread_id
422 showptr $kgm_thread.last_processor
423 printf " %3d ", $kgm_thread.sched_pri
424 if ($kgm_thread.uthread != 0)
425 set $kgm_printed = 0
426 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
427 if ($kgm_uthread->uu_flag & 0x400)
428 printf "RAGE "
429 else
430 printf " "
431 end
432 if ($kgm_uthread->uu_iopol_disk == 1)
433 printf "NORM "
434 set $kgm_printed = 1
435 end
436 if ($kgm_uthread->uu_iopol_disk == 2)
437 printf "PASS "
438 set $kgm_printed = 1
439 end
440 if ($kgm_uthread->uu_iopol_disk == 3)
441 printf "THROT "
442 set $kgm_printed = 1
443 end
444 if ($kgm_printed == 0)
445 printf " "
446 end
447 end
448 set $kgm_state = $kgm_thread.state
449 if $kgm_state & 0x80
450 printf "I"
451 end
452 if $kgm_state & 0x40
453 printf "P"
454 end
455 if $kgm_state & 0x20
456 printf "A"
457 end
458 if $kgm_state & 0x10
459 printf "H"
460 end
461 if $kgm_state & 0x08
462 printf "U"
463 end
464 if $kgm_state & 0x04
465 printf "R"
466 end
467 if $kgm_state & 0x02
468 printf "S"
469 end
470 if $kgm_state & 0x01
471 printf "W"
472 printf "\t "
473 showptr $kgm_thread.wait_queue
474 printf " "
475 if (((unsigned long)$kgm_thread.wait_event > (unsigned long)&last_kernel_symbol) \
476 && ($arg1 != 2) && ($kgm_show_kmod_syms == 0))
477 showkmodaddr $kgm_thread.wait_event
478 else
479 output /a $kgm_thread.wait_event
480 end
481 if ($kgm_thread.uthread != 0)
482 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
483 if ($kgm_uthread->uu_wmesg != 0)
484 printf "\t \"%s\"", $kgm_uthread->uu_wmesg
485 end
486 end
487 end
488 if $arg1 != 0
489 if ($kgm_thread.kernel_stack != 0)
490 if ($kgm_thread.reserved_stack != 0)
491 printf "\n "
492 showptrhdrpad
493 printf " reserved_stack="
494 showptr $kgm_thread.reserved_stack
495 end
496 printf "\n "
497 showptrhdrpad
498 printf " kernel_stack="
499 showptr $kgm_thread.kernel_stack
500 if ($kgm_mtype == $kgm_mtype_ppc)
501 set $mysp = $kgm_thread.machine.pcb->save_r1
502 end
503 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
504 set $kgm_statep = (struct x86_kernel_state *) \
505 ($kgm_thread->kernel_stack + kernel_stack_size \
506 - sizeof(struct x86_kernel_state))
507 if ($kgm_mtype == $kgm_mtype_i386)
508 set $mysp = $kgm_statep->k_ebp
509 else
510 set $mysp = $kgm_statep->k_rbp
511 end
512 end
513 if ($kgm_mtype == $kgm_mtype_arm)
514 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
515 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
516 set $mysp = $r7
517 else
518 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
519 set $mysp = $kgm_statep->r[7]
520 end
521 end
522 set $prevsp = $mysp - 16
523 printf "\n "
524 showptrhdrpad
525 printf " stacktop="
526 showptr $mysp
527 if ($kgm_mtype == $kgm_mtype_ppc)
528 set $stkmask = 0xf
529 else
530 set $stkmask = 0x3
531 end
532 set $kgm_return = 0
533 while ($mysp != 0) && (($mysp & $stkmask) == 0) \
534 && ($mysp != $prevsp) \
535 && ((((unsigned long) $mysp ^ (unsigned long) $prevsp) < 0x2000) \
536 || (((unsigned long)$mysp < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
537 && ((unsigned long)$mysp > (unsigned long) ($kgm_thread->kernel_stack))))
538 printf "\n "
539 showptrhdrpad
540 printf " "
541 showptr $mysp
542 printf " "
543 if ($kgm_mtype == $kgm_mtype_ppc)
544 set $kgm_return = *($mysp + 8)
545 end
546 if ($kgm_mtype == $kgm_mtype_i386)
547 set $kgm_return = *($mysp + 4)
548 end
549 if ($kgm_mtype == $kgm_mtype_x86_64)
550 set $kgm_return = *(unsigned long *)($mysp + 8)
551 end
552 if ($kgm_mtype == $kgm_mtype_arm)
553 set $kgm_return = *($mysp + 4)
554 end
555 if (((unsigned long) $kgm_return < (unsigned long) &_mh_execute_header || \
556 (unsigned long) $kgm_return >= (unsigned long) &last_kernel_symbol ) \
557 && ($kgm_show_kmod_syms == 0))
558 showkmodaddr $kgm_return
559 else
560 output /a $kgm_return
561 end
562 set $prevsp = $mysp
563 set $mysp = *(unsigned long *)$mysp
564 end
565 set $kgm_return = 0
566 printf "\n "
567 showptrhdrpad
568 printf " stackbottom="
569 showptr $prevsp
570 else
571 printf "\n "
572 showptrhdrpad
573 printf " continuation="
574 output /a $kgm_thread.continuation
575 end
576 printf "\n"
577 else
578 printf "\n"
579 end
580 end
581
582 define showact
583 showactheader
584 showactint $arg0 0
585 end
586 document showact
587 Syntax: (gdb) showact <activation>
588 | Routine to print out the state of a specific thread.
589 end
590
591
592 define showactstack
593 showactheader
594 showactint $arg0 1
595 end
596 document showactstack
597 Syntax: (gdb) showactstack <activation>
598 | Routine to print out the stack of a specific thread.
599 end
600
601
602 define showallthreads
603 set $kgm_head_taskp = &tasks
604 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
605 while $kgm_taskp != $kgm_head_taskp
606 showtaskheader
607 showtaskint $kgm_taskp
608 showactheader
609 set $kgm_head_actp = &($kgm_taskp->threads)
610 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
611 while $kgm_actp != $kgm_head_actp
612 showactint $kgm_actp 0
613 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
614 end
615 printf "\n"
616 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
617 end
618 end
619 document showallthreads
620 Syntax: (gdb) showallthreads
621 | Routine to print out info about all threads in the system.
622 end
623
624 define showcurrentthreads
625 set $kgm_prp = (struct processor *)processor_list
626 while $kgm_prp != 0
627 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_id
628 if ($kgm_prp)->active_thread != 0
629 set $kgm_actp = ($kgm_prp)->active_thread
630 showtaskheader
631 showtaskint ($kgm_actp)->task
632 showactheader
633 showactint $kgm_actp 0
634 printf "\n"
635 end
636 set $kgm_prp = ($kgm_prp)->processor_list
637 end
638 end
639 document showcurrentthreads
640 Syntax: (gdb) showcurrentthreads
641 | Routine to print out info about the thread running on each cpu.
642 end
643
644 set $decode_wait_events = 0
645 define showallstacks
646 set $kgm_head_taskp = &tasks
647 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
648 while $kgm_taskp != $kgm_head_taskp
649 showtaskheader
650 showtaskint $kgm_taskp
651 set $kgm_head_actp = &($kgm_taskp->threads)
652 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
653 while $kgm_actp != $kgm_head_actp
654 showactheader
655 if ($decode_wait_events > 0)
656 showactint $kgm_actp 1
657 else
658 showactint $kgm_actp 2
659 end
660 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
661 end
662 printf "\n"
663 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
664 end
665 end
666
667 document showallstacks
668 Syntax: (gdb) showallstacks
669 | Routine to print out the stack for each thread in the system.
670 | If the variable $decode_wait_events is non-zero, the routine attempts to
671 | interpret thread wait_events as kernel module offsets, which can add to
672 | processing time.
673 end
674
675 define showcurrentstacks
676 set $kgm_prp = processor_list
677 while $kgm_prp != 0
678 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_id
679 if ($kgm_prp)->active_thread != 0
680 set $kgm_actp = ($kgm_prp)->active_thread
681 showtaskheader
682 showtaskint ($kgm_actp)->task
683 showactheader
684 showactint $kgm_actp 1
685 printf "\n"
686 end
687 set $kgm_prp = ($kgm_prp)->processor_list
688 end
689 end
690
691 document showcurrentstacks
692 Syntax: (gdb) showcurrentstacks
693 | Routine to print out the thread running on each cpu (incl. its stack)
694 end
695
696 define showwaiterheader
697 printf "waiters thread "
698 printf "processor pri state wait_queue wait_event\n"
699 end
700
701 define showwaitqwaiters
702 set $kgm_w_waitqp = (WaitQueue*)$arg0
703 set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue)
704 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_linksp->next
705 set $kgm_w_found = 0
706 while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp)
707 if ($kgm_w_wqe->wqe_type != &_wait_queue_link)
708 if !$kgm_w_found
709 set $kgm_w_found = 1
710 showwaiterheader
711 end
712 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe
713 showactint $kgm_w_shuttle 0
714 end
715 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_wqe->wqe_links.next
716 end
717 end
718
719 define showwaitqwaitercount
720 set $kgm_wc_waitqp = (WaitQueue*)$arg0
721 set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue)
722 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_linksp->next
723 set $kgm_wc_count = 0
724 while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp)
725 if ($kgm_wc_wqe->wqe_type != &_wait_queue_link)
726 set $kgm_wc_count = $kgm_wc_count + 1
727 end
728 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_wqe->wqe_links.next
729 end
730 printf "0x%08x ", $kgm_wc_count
731 end
732
733 define showwaitqmembercount
734 set $kgm_mc_waitqsetp = (WaitQueueSet*)$arg0
735 set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks)
736 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_setlinksp->next
737 set $kgm_mc_count = 0
738 while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp)
739 set $kgm_mc_count = $kgm_mc_count + 1
740 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_wql->wql_setlinks.next
741 end
742 printf "0x%08x ", $kgm_mc_count
743 end
744
745
746 define showwaitqmemberheader
747 printf "set-members wait_queue interlock "
748 printf "pol type member_cnt waiter_cnt\n"
749 end
750
751 define showwaitqmemberint
752 set $kgm_m_waitqp = (WaitQueue*)$arg0
753 printf " 0x%08x ", $kgm_m_waitqp
754 printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data
755 if ($kgm_m_waitqp->wq_fifo)
756 printf "Fifo "
757 else
758 printf "Prio "
759 end
760 if ($kgm_m_waitqp->wq_type == 0xf1d1)
761 printf "Set "
762 showwaitqmembercount $kgm_m_waitqp
763 else
764 printf "Que 0x00000000 "
765 end
766 showwaitqwaitercount $kgm_m_waitqp
767 printf "\n"
768 end
769
770
771 define showwaitqmemberofheader
772 printf "member-of wait_queue interlock "
773 printf "pol type member_cnt waiter_cnt\n"
774 end
775
776 define showwaitqmemberof
777 set $kgm_mo_waitqp = (WaitQueue*)$arg0
778 set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue)
779 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_linksp->next
780 set $kgm_mo_found = 0
781 while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp)
782 if ($kgm_mo_wqe->wqe_type == &_wait_queue_link)
783 if !$kgm_mo_found
784 set $kgm_mo_found = 1
785 showwaitqmemberofheader
786 end
787 set $kgm_mo_wqlp = (WaitQueueLink *)$kgm_mo_wqe
788 set $kgm_mo_wqsetp = (WaitQueue*)($kgm_mo_wqlp->wql_setqueue)
789 showwaitqmemberint $kgm_mo_wqsetp
790 end
791 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_wqe->wqe_links.next
792 end
793 end
794
795 define showwaitqmembers
796 set $kgm_ms_waitqsetp = (WaitQueueSet*)$arg0
797 set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks)
798 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_setlinksp->next
799 set $kgm_ms_found = 0
800 while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp)
801 set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue
802 if !$kgm_ms_found
803 showwaitqmemberheader
804 set $kgm_ms_found = 1
805 end
806 showwaitqmemberint $kgm_ms_waitqp
807 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_wql->wql_setlinks.next
808 end
809 end
810
811 define showwaitqheader
812 printf "wait_queue ref_count interlock "
813 printf "pol type member_cnt waiter_cnt\n"
814 end
815
816 define showwaitqint
817 set $kgm_waitqp = (WaitQueue*)$arg0
818 printf "0x%08x ", $kgm_waitqp
819 if ($kgm_waitqp->wq_type == 0xf1d1)
820 printf "0x%08x ", ((WaitQueueSet*)$kgm_waitqp)->wqs_refcount
821 else
822 printf "0x00000000 "
823 end
824 printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data
825 if ($kgm_waitqp->wq_fifo)
826 printf "Fifo "
827 else
828 printf "Prio "
829 end
830 if ($kgm_waitqp->wq_type == 0xf1d1)
831 printf "Set "
832 showwaitqmembercount $kgm_waitqp
833 else
834 printf "Que 0x00000000 "
835 end
836 showwaitqwaitercount $kgm_waitqp
837 printf "\n"
838 end
839
840 define showwaitq
841 set $kgm_waitq1p = (WaitQueue*)$arg0
842 showwaitqheader
843 showwaitqint $kgm_waitq1p
844 if ($kgm_waitq1p->wq_type == 0xf1d1)
845 showwaitqmembers $kgm_waitq1p
846 else
847 showwaitqmemberof $kgm_waitq1p
848 end
849 showwaitqwaiters $kgm_waitq1p
850 end
851
852 define showmapheader
853 printf "vm_map "
854 showptrhdrpad
855 printf " pmap "
856 showptrhdrpad
857 printf " vm_size "
858 showptrhdrpad
859 printf " #ents rpage hint "
860 showptrhdrpad
861 printf " first_free\n"
862 end
863
864 define showvmeheader
865 printf " entry "
866 showptrhdrpad
867 printf " start prot #page object "
868 showptrhdrpad
869 printf " offset\n"
870 end
871
872 define showvmint
873 set $kgm_mapp = (vm_map_t)$arg0
874 set $kgm_map = *$kgm_mapp
875 showptr $arg0
876 printf " "
877 showptr $kgm_map.pmap
878 printf " "
879 showptr $kgm_map.size
880 printf " %3d ", $kgm_map.hdr.nentries
881 if $kgm_map.pmap
882 printf "%5d ", $kgm_map.pmap->stats.resident_count
883 else
884 printf "<n/a> "
885 end
886 showptr $kgm_map.hint
887 printf " "
888 showptr $kgm_map.first_free
889 printf "\n"
890 if $arg1 != 0
891 showvmeheader
892 set $kgm_head_vmep = &($kgm_mapp->hdr.links)
893 set $kgm_vmep = $kgm_map.hdr.links.next
894 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
895 set $kgm_vme = *$kgm_vmep
896 printf " "
897 showptr $kgm_vmep
898 printf " 0x%016llx ", $kgm_vme.links.start
899 printf "%1x", $kgm_vme.protection
900 printf "%1x", $kgm_vme.max_protection
901 if $kgm_vme.inheritance == 0x0
902 printf "S"
903 end
904 if $kgm_vme.inheritance == 0x1
905 printf "C"
906 end
907 if $kgm_vme.inheritance == 0x2
908 printf "-"
909 end
910 if $kgm_vme.inheritance == 0x3
911 printf "D"
912 end
913 if $kgm_vme.is_sub_map
914 printf "s "
915 else
916 if $kgm_vme.needs_copy
917 printf "n "
918 else
919 printf " "
920 end
921 end
922 printf "%6d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
923 showptr $kgm_vme.object.vm_object
924 printf " 0x%016llx\n", $kgm_vme.offset
925 set $kgm_vmep = $kgm_vme.links.next
926 end
927 end
928 printf "\n"
929 end
930
931
932 define showmapvme
933 showmapheader
934 showvmint $arg0 1
935 end
936 document showmapvme
937 Syntax: (gdb) showmapvme <vm_map>
938 | Routine to print out a summary listing of all the entries in a vm_map
939 end
940
941
942 define showmap
943 showmapheader
944 showvmint $arg0 0
945 end
946 document showmap
947 Syntax: (gdb) showmap <vm_map>
948 | Routine to print out info about the specified vm_map
949 end
950
951 define showallvm
952 set $kgm_head_taskp = &tasks
953 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
954 while $kgm_taskp != $kgm_head_taskp
955 showtaskheader
956 showmapheader
957 showtaskint $kgm_taskp
958 showvmint $kgm_taskp->map 0
959 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
960 end
961 end
962 document showallvm
963 Syntax: (gdb) showallvm
964 | Routine to print a summary listing of all the vm maps
965 end
966
967
968 define showallvme
969 set $kgm_head_taskp = &tasks
970 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
971 while $kgm_taskp != $kgm_head_taskp
972 showtaskheader
973 showmapheader
974 showtaskint $kgm_taskp
975 showvmint $kgm_taskp->map 1
976 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
977 end
978 end
979 document showallvme
980 Syntax: (gdb) showallvme
981 | Routine to print a summary listing of all the vm map entries
982 end
983
984
985 define showipcheader
986 printf "ipc_space "
987 showptrhdrpad
988 printf " is_table "
989 showptrhdrpad
990 printf " table_next"
991 showptrhdrpad
992 printf " flags tsize splaytree splaybase\n"
993 end
994
995 define showipceheader
996 printf " name object "
997 showptrhdrpad
998 printf " rite urefs destname destination\n"
999 end
1000
1001 define showipceint
1002 set $kgm_ie = *(ipc_entry_t)$arg0
1003 printf " 0x%08x ", $arg1
1004 showptr $kgm_ie.ie_object
1005 printf " "
1006 if $kgm_ie.ie_bits & 0x00100000
1007 printf "Dead "
1008 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1009 else
1010 if $kgm_ie.ie_bits & 0x00080000
1011 printf "SET "
1012 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1013 else
1014 if $kgm_ie.ie_bits & 0x00010000
1015 if $kgm_ie.ie_bits & 0x00020000
1016 printf " SR"
1017 else
1018 printf " S"
1019 end
1020 else
1021 if $kgm_ie.ie_bits & 0x00020000
1022 printf " R"
1023 end
1024 end
1025 if $kgm_ie.ie_bits & 0x00040000
1026 printf " O"
1027 end
1028 if $kgm_ie.index.request
1029 printf "n"
1030 else
1031 printf " "
1032 end
1033 if $kgm_ie.ie_bits & 0x00800000
1034 printf "c"
1035 else
1036 printf " "
1037 end
1038 printf "%5d ", $kgm_ie.ie_bits & 0xffff
1039 showportdest $kgm_ie.ie_object
1040 end
1041 end
1042 end
1043
1044 define showipcint
1045 set $kgm_isp = (ipc_space_t)$arg0
1046 set $kgm_is = *$kgm_isp
1047 showptr $arg0
1048 printf " "
1049 showptr $kgm_is.is_table
1050 printf " "
1051 showptr $kgm_is.is_table_next
1052 printf " "
1053 if $kgm_is.is_growing != 0
1054 printf "G"
1055 else
1056 printf " "
1057 end
1058 if $kgm_is.is_fast != 0
1059 printf "F"
1060 else
1061 printf " "
1062 end
1063 if $kgm_is.is_active != 0
1064 printf "A "
1065 else
1066 printf " "
1067 end
1068 printf "%5d ", $kgm_is.is_table_size
1069 printf "0x%08x ", $kgm_is.is_tree_total
1070 showptr &$kgm_isp->is_tree
1071 printf "\n"
1072 if $arg1 != 0
1073 showipceheader
1074 set $kgm_iindex = 0
1075 set $kgm_iep = $kgm_is.is_table
1076 set $kgm_destspacep = (ipc_space_t)0
1077 while ( $kgm_iindex < $kgm_is.is_table_size )
1078 set $kgm_ie = *$kgm_iep
1079 if $kgm_ie.ie_bits & 0x001f0000
1080 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24))
1081 showipceint $kgm_iep $kgm_name
1082 end
1083 set $kgm_iindex = $kgm_iindex + 1
1084 set $kgm_iep = &($kgm_is.is_table[$kgm_iindex])
1085 end
1086 if $kgm_is.is_tree_total
1087 printf "Still need to write tree traversal\n"
1088 end
1089 end
1090 printf "\n"
1091 end
1092
1093
1094 define showipc
1095 set $kgm_isp = (ipc_space_t)$arg0
1096 showipcheader
1097 showipcint $kgm_isp 0
1098 end
1099 document showipc
1100 Syntax: (gdb) showipc <ipc_space>
1101 | Routine to print the status of the specified ipc space
1102 end
1103
1104 define showrights
1105 set $kgm_isp = (ipc_space_t)$arg0
1106 showipcheader
1107 showipcint $kgm_isp 1
1108 end
1109 document showrights
1110 Syntax: (gdb) showrights <ipc_space>
1111 | Routine to print a summary list of all the rights in a specified ipc space
1112 end
1113
1114
1115 define showtaskipc
1116 set $kgm_taskp = (task_t)$arg0
1117 showtaskheader
1118 showipcheader
1119 showtaskint $kgm_taskp
1120 showipcint $kgm_taskp->itk_space 0
1121 end
1122 document showtaskipc
1123 Syntax: (gdb) showtaskipc <task>
1124 | Routine to print info about the ipc space for a task
1125 end
1126
1127
1128 define showtaskrights
1129 set $kgm_taskp = (task_t)$arg0
1130 showtaskheader
1131 showipcheader
1132 showtaskint $kgm_taskp
1133 showipcint $kgm_taskp->itk_space 1
1134 end
1135 document showtaskrights
1136 Syntax: (gdb) showtaskrights <task>
1137 | Routine to print info about the ipc rights for a task
1138 end
1139
1140 define showallipc
1141 set $kgm_head_taskp = &tasks
1142 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1143 while $kgm_cur_taskp != $kgm_head_taskp
1144 showtaskheader
1145 showipcheader
1146 showtaskint $kgm_cur_taskp
1147 showipcint $kgm_cur_taskp->itk_space 0
1148 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1149 end
1150 end
1151 document showallipc
1152 Syntax: (gdb) showallipc
1153 | Routine to print a summary listing of all the ipc spaces
1154 end
1155
1156
1157 define showallrights
1158 set $kgm_head_taskp = &tasks
1159 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1160 while $kgm_cur_taskp != $kgm_head_taskp
1161 showtaskheader
1162 showipcheader
1163 showtaskint $kgm_cur_taskp
1164 showipcint $kgm_cur_taskp->itk_space 1
1165 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1166 end
1167 end
1168 document showallrights
1169 Syntax: (gdb) showallrights
1170 | Routine to print a summary listing of all the ipc rights
1171 end
1172
1173
1174 define showtaskvm
1175 set $kgm_taskp = (task_t)$arg0
1176 showtaskheader
1177 showmapheader
1178 showtaskint $kgm_taskp
1179 showvmint $kgm_taskp->map 0
1180 end
1181 document showtaskvm
1182 Syntax: (gdb) showtaskvm <task>
1183 | Routine to print out info about a task's vm_map
1184 end
1185
1186 define showtaskvme
1187 set $kgm_taskp = (task_t)$arg0
1188 showtaskheader
1189 showmapheader
1190 showtaskint $kgm_taskp
1191 showvmint $kgm_taskp->map 1
1192 end
1193 document showtaskvme
1194 Syntax: (gdb) showtaskvme <task>
1195 | Routine to print out info about a task's vm_map_entries
1196 end
1197
1198
1199 define showtaskheader
1200 printf "task "
1201 showptrhdrpad
1202 printf " vm_map "
1203 showptrhdrpad
1204 printf " ipc_space "
1205 showptrhdrpad
1206 printf " #acts "
1207 showprocheader
1208 end
1209
1210
1211 define showtaskint
1212 set $kgm_taskp = (struct task *)$arg0
1213 showptr $arg0
1214 printf " "
1215 showptr $kgm_taskp->map
1216 printf " "
1217 showptr $kgm_taskp->itk_space
1218 printf " %5d ", $kgm_taskp->thread_count
1219 showprocint $kgm_taskp->bsd_info
1220 end
1221
1222 define showtask
1223 showtaskheader
1224 showtaskint $arg0
1225 end
1226 document showtask
1227 Syntax (gdb) showtask <task>
1228 | Routine to print out info about a task.
1229 end
1230
1231
1232 define showtaskthreads
1233 showtaskheader
1234 set $kgm_taskp = (struct task *)$arg0
1235 showtaskint $kgm_taskp
1236 showactheader
1237 set $kgm_head_actp = &($kgm_taskp->threads)
1238 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1239 while $kgm_actp != $kgm_head_actp
1240 showactint $kgm_actp 0
1241 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1242 end
1243 end
1244 document showtaskthreads
1245 Syntax: (gdb) showtaskthreads <task>
1246 | Routine to print info about the threads in a task.
1247 end
1248
1249
1250 define showtaskstacks
1251 showtaskheader
1252 set $kgm_taskp = (struct task *)$arg0
1253 showtaskint $kgm_taskp
1254 set $kgm_head_actp = &($kgm_taskp->threads)
1255 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1256 while $kgm_actp != $kgm_head_actp
1257 showactheader
1258 showactint $kgm_actp 1
1259 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1260 end
1261 end
1262 document showtaskstacks
1263 Syntax: (gdb) showtaskstacks <task>
1264 | Routine to print out the stack for each thread in a task.
1265 end
1266
1267
1268 define showalltasks
1269 showtaskheader
1270 set $kgm_head_taskp = &tasks
1271 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1272 while $kgm_taskp != $kgm_head_taskp
1273 showtaskint $kgm_taskp
1274 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1275 end
1276 end
1277 document showalltasks
1278 Syntax: (gdb) showalltasks
1279 | Routine to print a summary listing of all the tasks
1280 | wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
1281 | if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
1282 | io_policy -> RAGE - rapid aging of vnodes requested
1283 | NORM - normal I/O explicitly requested (this is the default)
1284 | PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
1285 | THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
1286 end
1287
1288 define showprocheader
1289 printf " pid process io_policy wq_state"
1290 showptrhdrpad
1291 printf " command\n"
1292 end
1293
1294 define showprocint
1295 set $kgm_procp = (struct proc *)$arg0
1296 if $kgm_procp != 0
1297 set $kgm_printed = 0
1298 printf "%5d ", $kgm_procp->p_pid
1299 showptr $kgm_procp
1300 if ($kgm_procp->p_lflag & 0x400000)
1301 printf " RAGE "
1302 else
1303 printf " "
1304 end
1305 if ($kgm_procp->p_iopol_disk == 1)
1306 printf "NORM "
1307 set $kgm_printed = 1
1308 end
1309 if ($kgm_procp->p_iopol_disk == 2)
1310 printf "PASS "
1311 set $kgm_printed = 1
1312 end
1313 if ($kgm_procp->p_iopol_disk == 3)
1314 printf "THROT "
1315 set $kgm_printed = 1
1316 end
1317 if ($kgm_printed == 0)
1318 printf " "
1319 end
1320 set $kgm_wqp = (struct workqueue *)$kgm_procp->p_wqptr
1321 if $kgm_wqp != 0
1322 printf " %2d %2d %2d ", $kgm_wqp->wq_nthreads, $kgm_wqp->wq_thidlecount, $kgm_wqp->wq_itemcount
1323 else
1324 printf " "
1325 end
1326 printf " %s\n", $kgm_procp->p_comm
1327 else
1328 printf " *0* "
1329 showptr 0
1330 printf " --\n"
1331 end
1332 end
1333
1334 define showpid
1335 showtaskheader
1336 set $kgm_head_taskp = &tasks
1337 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1338 while $kgm_taskp != $kgm_head_taskp
1339 set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info
1340 if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0))
1341 showtaskint $kgm_taskp
1342 set $kgm_taskp = $kgm_head_taskp
1343 else
1344 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1345 end
1346 end
1347 end
1348 document showpid
1349 Syntax: (gdb) showpid <pid>
1350 | Routine to print a single process by pid
1351 end
1352
1353 define showproc
1354 showtaskheader
1355 set $kgm_procp = (struct proc *)$arg0
1356 showtaskint $kgm_procp->task
1357 end
1358
1359
1360 define kdb
1361 set switch_debugger=1
1362 continue
1363 end
1364 document kdb
1365 | kdb - Switch to the inline kernel debugger
1366 |
1367 | usage: kdb
1368 |
1369 | The kdb macro allows you to invoke the inline kernel debugger.
1370 end
1371
1372 define showpsetheader
1373 printf "portset waitqueue recvname "
1374 printf "flags refs recvname process\n"
1375 end
1376
1377 define showportheader
1378 printf "port mqueue recvname "
1379 printf "flags refs recvname process\n"
1380 end
1381
1382 define showportmemberheader
1383 printf "members port recvname "
1384 printf "flags refs mqueue msgcount\n"
1385 end
1386
1387 define showkmsgheader
1388 printf "messages kmsg size "
1389 printf "disp msgid remote-port local-port\n"
1390 end
1391
1392 define showkmsgint
1393 printf " 0x%08x ", $arg0
1394 set $kgm_kmsgh = ((ipc_kmsg_t)$arg0)->ikm_header
1395 printf "0x%08x ", $kgm_kmsgh.msgh_size
1396 if (($kgm_kmsgh.msgh_bits & 0xff) == 19)
1397 printf "rC"
1398 else
1399 printf "rM"
1400 end
1401 if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 << 8))
1402 printf "lC"
1403 else
1404 printf "lM"
1405 end
1406 if ($kgm_kmsgh.msgh_bits & 0xf0000000)
1407 printf "c"
1408 else
1409 printf "s"
1410 end
1411 printf "%5d ", $kgm_kmsgh.msgh_id
1412 printf "0x%08x ", $kgm_kmsgh.msgh_remote_port
1413 printf "0x%08x\n", $kgm_kmsgh.msgh_local_port
1414 end
1415
1416
1417
1418 define showkobject
1419 set $kgm_portp = (struct ipc_port *)$arg0
1420 showptr $kgm_portp->ip_kobject
1421 printf " kobject("
1422 set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff)
1423 if ($kgm_kotype == 1)
1424 printf "THREAD"
1425 end
1426 if ($kgm_kotype == 2)
1427 printf "TASK"
1428 end
1429 if ($kgm_kotype == 3)
1430 printf "HOST"
1431 end
1432 if ($kgm_kotype == 4)
1433 printf "HOST_PRIV"
1434 end
1435 if ($kgm_kotype == 5)
1436 printf "PROCESSOR"
1437 end
1438 if ($kgm_kotype == 6)
1439 printf "PSET"
1440 end
1441 if ($kgm_kotype == 7)
1442 printf "PSET_NAME"
1443 end
1444 if ($kgm_kotype == 8)
1445 printf "TIMER"
1446 end
1447 if ($kgm_kotype == 9)
1448 printf "PAGER_REQ"
1449 end
1450 if ($kgm_kotype == 10)
1451 printf "DEVICE"
1452 end
1453 if ($kgm_kotype == 11)
1454 printf "XMM_OBJECT"
1455 end
1456 if ($kgm_kotype == 12)
1457 printf "XMM_PAGER"
1458 end
1459 if ($kgm_kotype == 13)
1460 printf "XMM_KERNEL"
1461 end
1462 if ($kgm_kotype == 14)
1463 printf "XMM_REPLY"
1464 end
1465 if ($kgm_kotype == 15)
1466 printf "NOTDEF 15"
1467 end
1468 if ($kgm_kotype == 16)
1469 printf "NOTDEF 16"
1470 end
1471 if ($kgm_kotype == 17)
1472 printf "HOST_SEC"
1473 end
1474 if ($kgm_kotype == 18)
1475 printf "LEDGER"
1476 end
1477 if ($kgm_kotype == 19)
1478 printf "MASTER_DEV"
1479 end
1480 if ($kgm_kotype == 20)
1481 printf "ACTIVATION"
1482 end
1483 if ($kgm_kotype == 21)
1484 printf "SUBSYSTEM"
1485 end
1486 if ($kgm_kotype == 22)
1487 printf "IO_DONE_QUE"
1488 end
1489 if ($kgm_kotype == 23)
1490 printf "SEMAPHORE"
1491 end
1492 if ($kgm_kotype == 24)
1493 printf "LOCK_SET"
1494 end
1495 if ($kgm_kotype == 25)
1496 printf "CLOCK"
1497 end
1498 if ($kgm_kotype == 26)
1499 printf "CLOCK_CTRL"
1500 end
1501 if ($kgm_kotype == 27)
1502 printf "IOKIT_SPARE"
1503 end
1504 if ($kgm_kotype == 28)
1505 printf "NAMED_MEM"
1506 end
1507 if ($kgm_kotype == 29)
1508 printf "IOKIT_CON"
1509 end
1510 if ($kgm_kotype == 30)
1511 printf "IOKIT_OBJ"
1512 end
1513 if ($kgm_kotype == 31)
1514 printf "UPL"
1515 end
1516 printf ")\n"
1517 end
1518
1519 define showportdestproc
1520 set $kgm_portp = (struct ipc_port *)$arg0
1521 set $kgm_spacep = $kgm_portp->data.receiver
1522 # check against the previous cached value - this is slow
1523 if ($kgm_spacep != $kgm_destspacep)
1524 set $kgm_destprocp = (struct proc *)0
1525 set $kgm_head_taskp = &tasks
1526 set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next)
1527 while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp))
1528 set $kgm_destspacep = $kgm_desttaskp->itk_space
1529 if ($kgm_destspacep == $kgm_spacep)
1530 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info
1531 else
1532 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->tasks.next)
1533 end
1534 end
1535 end
1536 if $kgm_destprocp != 0
1537 printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid
1538 else
1539 printf "task "
1540 showptr $kgm_desttaskp
1541 printf "\n"
1542 end
1543 end
1544
1545 define showportdest
1546 set $kgm_portp = (struct ipc_port *)$arg0
1547 set $kgm_spacep = $kgm_portp->data.receiver
1548 if ($kgm_spacep == ipc_space_kernel)
1549 showkobject $kgm_portp
1550 else
1551 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1552 showptr $kgm_portp->ip_messages.data.port.receiver_name
1553 printf " "
1554 showportdestproc $kgm_portp
1555 else
1556 showptr $kgm_portp
1557 printf " inactive-port\n"
1558 end
1559 end
1560 end
1561
1562 define showportmember
1563 printf " 0x%08x ", $arg0
1564 set $kgm_portp = (struct ipc_port *)$arg0
1565 printf "0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
1566 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1567 printf "A"
1568 else
1569 printf " "
1570 end
1571 printf "Port"
1572 printf "%5d ", $kgm_portp->ip_object.io_references
1573 printf "0x%08x ", &($kgm_portp->ip_messages)
1574 printf "0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount
1575 end
1576
1577 define showportint
1578 printf "0x%08x ", $arg0
1579 set $kgm_portp = (struct ipc_port *)$arg0
1580 printf "0x%08x ", &($kgm_portp->ip_messages)
1581 printf "0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
1582 if ($kgm_portp->ip_object.io_bits & 0x80000000)
1583 printf "A"
1584 else
1585 printf "D"
1586 end
1587 printf "Port"
1588 printf "%5d ", $kgm_portp->ip_object.io_references
1589 set $kgm_destspacep = (struct ipc_space *)0
1590 showportdest $kgm_portp
1591 set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base
1592 if $arg1 && $kgm_kmsgp
1593 showkmsgheader
1594 showkmsgint $kgm_kmsgp
1595 set $kgm_kmsgheadp = $kgm_kmsgp
1596 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
1597 while $kgm_kmsgp != $kgm_kmsgheadp
1598 showkmsgint $kgm_kmsgp
1599 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
1600 end
1601 end
1602 end
1603
1604 define showpsetint
1605 printf "0x%08x ", $arg0
1606 set $kgm_psetp = (struct ipc_pset *)$arg0
1607 printf "0x%08x ", &($kgm_psetp->ips_messages)
1608 printf "0x%08x ", $kgm_psetp->ips_messages.data.pset.local_name
1609 if ($kgm_psetp->ips_object.io_bits & 0x80000000)
1610 printf "A"
1611 else
1612 printf "D"
1613 end
1614 printf "Set "
1615 printf "%5d ", $kgm_psetp->ips_object.io_references
1616 printf "0x%08x ", $kgm_psetp->ips_messages.data.pset.local_name
1617 set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.set_queue.wqs_setlinks)
1618 set $kgm_wql = (WaitQueueLink *)$kgm_setlinksp->next
1619 set $kgm_found = 0
1620 while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp)
1621 set $kgm_portp = (struct ipc_port *)((int)($kgm_wql->wql_element->wqe_queue) - ((int)$kgm_portoff))
1622 if !$kgm_found
1623 set $kgm_destspacep = (struct ipc_space *)0
1624 showportdestproc $kgm_portp
1625 showportmemberheader
1626 set $kgm_found = 1
1627 end
1628 showportmember $kgm_portp 0
1629 set $kgm_wql = (WaitQueueLink *)$kgm_wql->wql_setlinks.next
1630 end
1631 if !$kgm_found
1632 printf "--n/e--\n"
1633 end
1634 end
1635
1636 define showpset
1637 showpsetheader
1638 showpsetint $arg0 1
1639 end
1640
1641 define showport
1642 showportheader
1643 showportint $arg0 1
1644 end
1645
1646 define showipcobject
1647 set $kgm_object = (ipc_object_t)$arg0
1648 if ($kgm_objectp->io_bits & 0x7fff0000)
1649 showpset $kgm_objectp
1650 else
1651 showport $kgm_objectp
1652 end
1653 end
1654
1655 define showmqueue
1656 set $kgm_mqueue = *(struct ipc_mqueue *)$arg0
1657 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d1)
1658 set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages)
1659 set $kgm_pset = (((long)$arg0) - ((long)$kgm_psetoff))
1660 showpsetheader
1661 showpsetint $kgm_pset 1
1662 end
1663 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d0)
1664 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
1665 set $kgm_port = (((long)$arg0) - ((long)$kgm_portoff))
1666 showportheader
1667 showportint $kgm_port 1
1668 end
1669 end
1670
1671 define zprint_one
1672 set $kgm_zone = (struct zone *)$arg0
1673
1674 showptr $kgm_zone
1675 printf " %6d ",$kgm_zone->count
1676 printf "%8x ",$kgm_zone->cur_size
1677 printf "%8x ",$kgm_zone->max_size
1678 printf "%6d ",$kgm_zone->elem_size
1679 printf "%8x ",$kgm_zone->alloc_size
1680 printf "%s ",$kgm_zone->zone_name
1681
1682 if ($kgm_zone->exhaustible)
1683 printf "H"
1684 end
1685 if ($kgm_zone->collectable)
1686 printf "C"
1687 end
1688 if ($kgm_zone->expandable)
1689 printf "X"
1690 end
1691 printf "\n"
1692 end
1693
1694
1695 define zprint
1696 printf "ZONE "
1697 showptrhdrpad
1698 printf " COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n"
1699 set $kgm_zone_ptr = (struct zone *)first_zone
1700 while ($kgm_zone_ptr != 0)
1701 zprint_one $kgm_zone_ptr
1702 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
1703 end
1704 printf "\n"
1705 end
1706 document zprint
1707 Syntax: (gdb) zprint
1708 | Routine to print a summary listing of all the kernel zones
1709 end
1710
1711 define showmtxgrp
1712 set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0
1713
1714 if ($kgm_mtxgrp->lck_grp_mtxcnt)
1715 showptr $kgm_mtxgrp
1716 printf " %8d ",$kgm_mtxgrp->lck_grp_mtxcnt
1717 printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
1718 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
1719 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
1720 printf "%s ",&$kgm_mtxgrp->lck_grp_name
1721 printf "\n"
1722 end
1723 end
1724
1725
1726 define showallmtx
1727 printf "LCK GROUP "
1728 showptrhdrpad
1729 printf " CNT UTIL MISS WAIT NAME\n"
1730 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1731 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
1732 while ($kgm_mtxgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
1733 showmtxgrp $kgm_mtxgrp_ptr
1734 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
1735 end
1736 printf "\n"
1737 end
1738 document showallmtx
1739 Syntax: (gdb) showallmtx
1740 | Routine to print a summary listing of all mutexes
1741 end
1742
1743 define showrwlckgrp
1744 set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0
1745
1746 if ($kgm_rwlckgrp->lck_grp_rwcnt)
1747 showptr $kgm_rwlckgrp
1748 printf " %8d ",$kgm_rwlckgrp->lck_grp_rwcnt
1749 printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
1750 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
1751 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
1752 printf "%s ",&$kgm_rwlckgrp->lck_grp_name
1753 printf "\n"
1754 end
1755 end
1756
1757
1758 define showallrwlck
1759 printf "LCK GROUP "
1760 showptrhdrpad
1761 printf " CNT UTIL MISS WAIT NAME\n"
1762 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1763 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1764 while ($kgm_rwlckgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
1765 showrwlckgrp $kgm_rwlckgrp_ptr
1766 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1767 end
1768 printf "\n"
1769 end
1770 document showallrwlck
1771 Syntax: (gdb) showallrwlck
1772 | Routine to print a summary listing of all read/writer locks
1773 end
1774
1775 set $kdp_act_counter = 0
1776
1777 set $r0_save = 0
1778 set $r1_save = 0
1779 set $r2_save = 0
1780 set $r3_save = 0
1781 set $r4_save = 0
1782 set $r5_save = 0
1783 set $r6_save = 0
1784 set $r7_save = 0
1785 set $r8_save = 0
1786 set $r9_save = 0
1787 set $r10_save = 0
1788 set $r11_save = 0
1789 set $r12_save = 0
1790 set $sp_save = 0
1791 set $lr_save = 0
1792 set $pc_save = 0
1793
1794 define showcontext_int
1795 echo Context switched, current instruction pointer:
1796 output/a $pc
1797 echo \n
1798 end
1799
1800 define switchtoact
1801 set $newact = (struct thread *) $arg0
1802 select 0
1803 if ($newact->kernel_stack == 0)
1804 echo This activation does not have a stack.\n
1805 echo continuation:
1806 output/a (unsigned) $newact.continuation
1807 echo \n
1808 else
1809 if ($kgm_mtype == $kgm_mtype_ppc)
1810 if ($kdp_act_counter == 0)
1811 set $kdpstate = (struct savearea *) kdp.saved_state
1812 end
1813 set $kdp_act_counter = $kdp_act_counter + 1
1814 set (struct savearea *) kdp.saved_state=$newact->machine->pcb
1815 flushregs
1816 flushstack
1817 set $pc=$newact->machine->pcb.save_srr0
1818 update
1819 end
1820 if ($kgm_mtype == $kgm_mtype_i386)
1821 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
1822 if ($kdp_act_counter == 0)
1823 set $kdpstate = *($kdpstatep)
1824 end
1825 set $kdp_act_counter = $kdp_act_counter + 1
1826
1827 set $kgm_statep = (struct x86_kernel_state *) \
1828 ($newact->kernel_stack + kernel_stack_size \
1829 - sizeof(struct x86_kernel_state))
1830 set $kdpstatep->ebx = $kgm_statep->k_ebx
1831 set $kdpstatep->ebp = $kgm_statep->k_ebp
1832 set $kdpstatep->edi = $kgm_statep->k_edi
1833 set $kdpstatep->esi = $kgm_statep->k_esi
1834 set $kdpstatep->eip = $kgm_statep->k_eip
1835 flushregs
1836 flushstack
1837 set $pc = $kgm_statep->k_eip
1838 update
1839 end
1840 if ($kgm_mtype == $kgm_mtype_x86_64)
1841 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
1842 if ($kdp_act_counter == 0)
1843 set $kdpstate = *($kdpstatep)
1844 end
1845 set $kdp_act_counter = $kdp_act_counter + 1
1846
1847 set $kgm_statep = (struct x86_kernel_state *) \
1848 ($newact->kernel_stack + kernel_stack_size \
1849 - sizeof(struct x86_kernel_state))
1850 set $kdpstatep->rbx = $kgm_statep->k_rbx
1851 set $kdpstatep->rbp = $kgm_statep->k_rbp
1852 set $kdpstatep->r12 = $kgm_statep->k_r12
1853 set $kdpstatep->r13 = $kgm_statep->k_r13
1854 set $kdpstatep->r14 = $kgm_statep->k_r14
1855 set $kdpstatep->r15 = $kgm_statep->k_r15
1856 set $kdpstatep->isf.rsp = $kgm_statep->k_rsp
1857 flushregs
1858 flushstack
1859 set $pc = $kgm_statep->k_rip
1860 update
1861 end
1862 if ($kgm_mtype == $kgm_mtype_arm)
1863 set $r0_save = $r0
1864 set $r1_save = $r1
1865 set $r2_save = $r2
1866 set $r3_save = $r3
1867 set $r4_save = $r4
1868 set $r5_save = $r5
1869 set $r6_save = $r6
1870 set $r7_save = $r7
1871 set $r8_save = $r8
1872 set $r9_save = $r9
1873 set $r10_save = $r10
1874 set $r11_save = $r11
1875 set $r12_save = $r12
1876 set $sp_save = $sp
1877 set $lr_save = $lr
1878 set $pc_save = $pc
1879 set $pc_ctx = load_reg+8
1880 set $kgm_statep = (struct arm_saved_state *)((struct thread*)$arg0)->machine.kstackptr
1881 set $r0 = $kgm_statep->r[0]
1882 set $r1 = $kgm_statep->r[1]
1883 set $r2 = $kgm_statep->r[2]
1884 set $r3 = $kgm_statep->r[3]
1885 set $r4 = $kgm_statep->r[4]
1886 set $r5 = $kgm_statep->r[5]
1887 set $r6 = $kgm_statep->r[6]
1888 set $r8 = $kgm_statep->r[8]
1889 set $r9 = $kgm_statep->r[9]
1890 set $r10 = $kgm_statep->r[10]
1891 set $r11 = $kgm_statep->r[11]
1892 set $r12 = $kgm_statep->r[12]
1893 set $sp = $kgm_statep->sp
1894 set $lr = $kgm_statep->lr
1895 set $pc = $pc_ctx
1896 set $r7 = $kgm_statep->r[7]
1897 flushregs
1898 flushstack
1899 end
1900 end
1901 showcontext_int
1902 end
1903
1904 document switchtoact
1905 Syntax: switchtoact <address of activation>
1906 | This command allows gdb to examine the execution context and call
1907 | stack for the specified activation. For example, to view the backtrace
1908 | for an activation issue "switchtoact <address>", followed by "bt".
1909 | Before resuming execution, issue a "resetctx" command, to
1910 | return to the original execution context.
1911 end
1912
1913 define switchtoctx
1914 select 0
1915 if ($kgm_mtype == $kgm_mtype_ppc)
1916 if ($kdp_act_counter == 0)
1917 set $kdpstate = (struct savearea *) kdp.saved_state
1918 end
1919 set $kdp_act_counter = $kdp_act_counter + 1
1920 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0
1921 flushregs
1922 flushstack
1923 set $pc=((struct savearea *) $arg0)->save_srr0
1924 update
1925 else
1926 if ($kgm_mtype == $kgm_mtype_arm)
1927 set arm disassembler std
1928 select-frame 0
1929 set $r0_save = $r0
1930 set $r1_save = $r1
1931 set $r2_save = $r2
1932 set $r3_save = $r3
1933 set $r4_save = $r4
1934 set $r5_save = $r5
1935 set $r6_save = $r6
1936 set $r7_save = $r7
1937 set $r8_save = $r8
1938 set $r9_save = $r9
1939 set $r10_save = $r10
1940 set $r11_save = $r11
1941 set $r12_save = $r12
1942 set $sp_save = $sp
1943 set $lr_save = $lr
1944 set $pc_save = $pc
1945 set $kgm_statep = (struct arm_saved_state *)$arg0
1946 set $r0 = $kgm_statep->r[0]
1947 set $r1 = $kgm_statep->r[1]
1948 set $r2 = $kgm_statep->r[2]
1949 set $r3 = $kgm_statep->r[3]
1950 set $r4 = $kgm_statep->r[4]
1951 set $r5 = $kgm_statep->r[5]
1952 set $r6 = $kgm_statep->r[6]
1953 set $r8 = $kgm_statep->r[8]
1954 set $r9 = $kgm_statep->r[9]
1955 set $r10 = $kgm_statep->r[10]
1956 set $r11 = $kgm_statep->r[11]
1957 set $r12 = $kgm_statep->r[12]
1958 set $sp = $kgm_statep->sp
1959 set $lr = $kgm_statep->lr
1960 set $r7 = $kgm_statep->r[7]
1961 set $pc = $kgm_statep->pc
1962 flushregs
1963 flushstack
1964 update
1965 else
1966 echo switchtoctx not implemented for this architecture.\n
1967 end
1968 end
1969
1970 document switchtoctx
1971 Syntax: switchtoctx <address of pcb>
1972 | This command allows gdb to examine an execution context and dump the
1973 | backtrace for this execution context.
1974 | Before resuming execution, issue a "resetctx" command, to
1975 | return to the original execution context.
1976 end
1977
1978 define resetctx
1979 select 0
1980 if ($kdp_act_counter != 0)
1981 if ($kgm_mtype == $kgm_mtype_ppc)
1982 set (struct savearea *)kdp.saved_state=$kdpstate
1983 flushregs
1984 flushstack
1985 set $pc=((struct savearea *) kdp.saved_state)->save_srr0
1986 update
1987 set $kdp_act_counter = 0
1988 end
1989 if ($kgm_mtype == $kgm_mtype_i386)
1990 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
1991 set *($kdpstatep)=$kdpstate
1992 flushregs
1993 flushstack
1994 set $pc=$kdpstatep->eip
1995 update
1996 set $kdp_act_counter = 0
1997 end
1998 if ($kgm_mtype == $kgm_mtype_x86_64)
1999 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
2000 set *($kdpstatep)=$kdpstate
2001 flushregs
2002 flushstack
2003 set $pc=$kdpstatep->isf.rip
2004 update
2005 set $kdp_act_counter = 0
2006 end
2007 if ($kgm_mtype == $kgm_mtype_arm)
2008 set $r0 = $r0_save
2009 flushregs
2010 set $r1 = $r1_save
2011 flushregs
2012 set $r2 = $r2_save
2013 flushregs
2014 set $r3 = $r3_save
2015 flushregs
2016 set $r4 = $r4_save
2017 flushregs
2018 set $r5 = $r5_save
2019 flushregs
2020 set $r6 = $r6_save
2021 flushregs
2022 set $r8 = $r8_save
2023 flushregs
2024 set $r9 = $r9_save
2025 flushregs
2026 set $r10 = $r10_save
2027 flushregs
2028 set $r11 = $r11_save
2029 flushregs
2030 set $r12 = $r12_save
2031 flushregs
2032 set $sp = $sp_save
2033 flushregs
2034 set $lr = $lr_save
2035 flushregs
2036 set $pc = $pc_save
2037 flushregs
2038 set $r7 = $r7_save
2039 flushregs
2040 end
2041 showcontext_int
2042 end
2043 end
2044
2045 document resetctx
2046 | Syntax: resetctx
2047 | Returns to the original execution context. This command should be
2048 | issued if you wish to resume execution after using the "switchtoact"
2049 | or "switchtoctx" commands.
2050 end
2051
2052 # This is a pre-hook for the continue command, to prevent inadvertent attempts
2053 # to resume from the context switched to for examination.
2054 define hook-continue
2055 resetctx
2056 end
2057
2058 # This is a pre-hook for the detach command, to prevent inadvertent attempts
2059 # to resume from the context switched to for examination.
2060 define hook-detach
2061 resetctx
2062 end
2063
2064 define resume_on
2065 set noresume_on_disconnect = 0
2066 end
2067
2068 document resume_on
2069 | Syntax: resume_on
2070 | The target system will resume when detaching or exiting from gdb.
2071 | This is the default behavior.
2072 end
2073
2074 define resume_off
2075 set noresume_on_disconnect = 1
2076 end
2077
2078 document resume_off
2079 | Syntax: resume_off
2080 | The target system won't resume after detaching from gdb and
2081 | can be attached with a new gdb session
2082 end
2083
2084 define paniclog
2085 set $kgm_panic_bufptr = debug_buf
2086 set $kgm_panic_bufptr_max = debug_buf_ptr
2087 while $kgm_panic_bufptr < $kgm_panic_bufptr_max
2088 if *(char *)$kgm_panic_bufptr == 10
2089 printf "\n"
2090 else
2091 printf "%c", *(char *)$kgm_panic_bufptr
2092 end
2093 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1
2094 end
2095 end
2096
2097 document paniclog
2098 | Syntax: paniclog
2099 | Display the panic log information
2100 |
2101 end
2102
2103 define dumpcallqueue
2104 set $kgm_callhead = $arg0
2105 set $kgm_callentry = $kgm_callhead->next
2106 set $kgm_i = 0
2107 while $kgm_callentry != $kgm_callhead
2108 set $kgm_call = (struct call_entry *)$kgm_callentry
2109 printf "0x%08x ", $kgm_call
2110 printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1
2111 output $kgm_call->deadline
2112 printf "\t"
2113 output $kgm_call->func
2114 printf "\n"
2115 set $kgm_i = $kgm_i + 1
2116 set $kgm_callentry = $kgm_callentry->next
2117 end
2118 printf "%d entries\n", $kgm_i
2119 end
2120
2121 document dumpcallqueue
2122 | Syntax: dumpcallqueue <queue head>
2123 | Displays the contents of the specified call_entry queue.
2124 end
2125
2126 define showtaskacts
2127 showtaskthreads $arg0
2128 end
2129 document showtaskacts
2130 | See help showtaskthreads.
2131 end
2132
2133 define showallacts
2134 showallthreads
2135 end
2136 document showallacts
2137 | See help showallthreads.
2138 end
2139
2140
2141 define resetstacks
2142 _kgm_flush_loop
2143 set kdp_pmap = 0
2144 _kgm_flush_loop
2145 resetctx
2146 _kgm_flush_loop
2147 _kgm_update_loop
2148 resetctx
2149 _kgm_update_loop
2150 end
2151
2152 document resetstacks
2153 | Syntax: resetstacks
2154 | Internal kgmacro routine used by the "showuserstack" macro
2155 | to reset the target pmap to the kernel pmap.
2156 end
2157
2158 #Barely effective hacks to work around bugs in the "flush" and "update"
2159 #gdb commands in Tiger (up to 219); these aren't necessary with Panther
2160 #gdb, but do no harm.
2161 define _kgm_flush_loop
2162 set $kgm_flush_loop_ctr = 0
2163 while ($kgm_flush_loop_ctr < 30)
2164 flushregs
2165 flushstack
2166 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1
2167 end
2168 end
2169
2170 define _kgm_update_loop
2171 set $kgm_update_loop_ctr = 0
2172 while ($kgm_update_loop_ctr < 30)
2173 update
2174 set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1
2175 end
2176 end
2177 # Internal routine used by "_loadfrom" to read from 64-bit addresses
2178 # on 32-bit kernels
2179 define _loadk32m64
2180 # set up the manual KDP packet
2181 set manual_pkt.input = 0
2182 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
2183 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
2184 set $kgm_pkt->hdr.request = KDP_READMEM64
2185 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
2186 set $kgm_pkt->hdr.is_reply = 0
2187 set $kgm_pkt->hdr.seq = 0
2188 set $kgm_pkt->hdr.key = 0
2189 set $kgm_pkt->address = (uint64_t)$arg0
2190 set $kgm_pkt->nbytes = sizeof(uint64_t)
2191 set manual_pkt.input = 1
2192 # dummy to make sure manual packet is executed
2193 set $kgm_dummy = &_mh_execute_header
2194 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
2195 if ($kgm_pkt->error == 0)
2196 set $kgm_k32read64 = *(uint64_t *)$kgm_pkt->data
2197 else
2198 set $kgm_k32read64 = 0
2199 end
2200 end
2201
2202 # Internal routine used by "showx86backtrace" to abstract possible loads from
2203 # user space
2204 define _loadfrom
2205 if (kdp_pmap == 0)
2206 set $kgm_loadval = *(uintptr_t *)$arg0
2207 else
2208 if ($kgm_x86_abi == 0xe)
2209 set $kgm_loadval = *(uint32_t *)$arg0
2210 else
2211 if ($kgm_x86_abi == 0xf)
2212 if ($kgm_mtype == $kgm_mtype_i386)
2213 _loadk32m64 $arg0
2214 set $kgm_loadval = $kgm_k32read64
2215 else
2216 set $kgm_loadval = *(uint64_t *)$arg0
2217 end
2218 end
2219 end
2220 end
2221 end
2222
2223
2224 #This is necessary since gdb often doesn't do backtraces on x86 correctly
2225 #in the absence of symbols.The code below in showuserstack and
2226 #showx86backtrace also contains several workarouds for the gdb bug where
2227 #gdb stops macro evaluation because of spurious "Cannot read memory"
2228 #errors on x86. These errors appear on ppc as well, but they don't
2229 #always stop macro evaluation.
2230
2231 set $kgm_cur_frame = 0
2232 set $kgm_cur_pc = 0
2233 set $kgm_x86_abi = 0
2234 define showx86backtrace
2235 if ($kgm_mtype == $kgm_mtype_i386)
2236 set $kgm_frame_reg = $ebp
2237 set $kgm_pc = $eip
2238 set $kgm_ret_off = 4
2239 end
2240 if ($kgm_mtype == $kgm_mtype_x86_64)
2241 set $kgm_frame_reg = $rbp
2242 set $kgm_pc = $rip
2243 set $kgm_ret_off = 8
2244 end
2245
2246 if ($kgm_x86_abi == 0xe)
2247 set $kgm_ret_off = 4
2248 end
2249 if ($kgm_x86_abi == 0xf)
2250 set $kgm_ret_off = 8
2251 end
2252
2253 if ($kgm_cur_frame == 0)
2254 set $kgm_cur_frame = $kgm_frame_reg
2255 end
2256 if ($kgm_cur_pc == 0)
2257 set $kgm_cur_pc = $kgm_pc
2258 end
2259 printf "0: Frame: 0x%016llx PC: 0x%016llx\n", $kgm_cur_frame, $kgm_cur_pc
2260 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
2261 x/i $kgm_cur_pc
2262 end
2263 set $kgm_tmp_frame = $kgm_cur_frame
2264 set $kgm_cur_frame = 0
2265 set $kgm_cur_pc = 0
2266 _loadfrom ($kgm_tmp_frame)
2267 set $kgm_prev_frame = $kgm_loadval
2268 _loadfrom ($kgm_tmp_frame+$kgm_ret_off)
2269 set $kgm_prev_pc = $kgm_loadval
2270 set $kgm_frameno = 1
2271 while $kgm_prev_frame != 0
2272 printf "%d: Saved frame: 0x%016llx Saved PC: 0x%016llx\n", $kgm_frameno, $kgm_prev_frame, $kgm_prev_pc
2273 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
2274 x/i $kgm_prev_pc
2275 end
2276 _loadfrom ($kgm_prev_frame+$kgm_ret_off)
2277 set $kgm_prev_pc = $kgm_loadval
2278 _loadfrom ($kgm_prev_frame)
2279 set $kgm_prev_frame = $kgm_loadval
2280 set $kgm_frameno = $kgm_frameno + 1
2281 end
2282 set kdp_pmap = 0
2283 set $kgm_x86_abi = 0
2284 end
2285
2286 define showx86backtrace2
2287 set $kgm_cur_frame = $arg0
2288 set $kgm_cur_pc = $arg1
2289 showx86backtrace
2290 end
2291
2292 define showuserstack
2293 select 0
2294 if ($kgm_mtype == $kgm_mtype_ppc)
2295 if ($kdp_act_counter == 0)
2296 set $kdpstate = (struct savearea *) kdp.saved_state
2297 end
2298 set $kdp_act_counter = $kdp_act_counter + 1
2299 set $newact = (struct thread *) $arg0
2300 _kgm_flush_loop
2301 set $checkpc = $newact->machine->upcb.save_srr0
2302 if ($checkpc == 0)
2303 echo This activation does not appear to have
2304 echo \20 a valid user context.\n
2305 else
2306 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
2307 set $pc = $checkpc
2308 #flush and update seem to be executed lazily by gdb on Tiger, hence the
2309 #repeated invocations - see 3743135
2310 _kgm_flush_loop
2311 # This works because the new pmap is used only for reads
2312 set kdp_pmap = $newact->task->map->pmap
2313 _kgm_flush_loop
2314 _kgm_update_loop
2315 bt
2316 resetstacks
2317 _kgm_flush_loop
2318 _kgm_update_loop
2319 resetstacks
2320 _kgm_flush_loop
2321 _kgm_update_loop
2322 end
2323 else
2324 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
2325 set $newact = (struct thread *) $arg0
2326 set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
2327 set $kgm_x86_abi = $newiss.flavor
2328 if ($newiss.flavor == 0xf)
2329 set $checkpc = $newiss.uss.ss_64.isf.rip
2330 set $checkframe = $newiss.uss.ss_64.rbp
2331
2332 else
2333 set $checkpc = $newiss.uss.ss_32.eip
2334 set $checkframe = $newiss.uss.ss_32.ebp
2335 end
2336
2337 if ($checkpc == 0)
2338 echo This activation does not appear to have
2339 echo \20 a valid user context.\n
2340 else
2341 set $kgm_cur_frame = $checkframe
2342 set $kgm_cur_pc = $checkpc
2343 printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread ("
2344 showptr $arg0
2345 printf "); you can also examine memory locations in this address space (pmap "
2346 showptr $newact->task->map->pmap
2347 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"
2348 set kdp_pmap = $newact->task->map->pmap
2349 _kgm_flush_loop
2350 _kgm_update_loop
2351 end
2352 else
2353 echo showuserstack not supported on this architecture\n
2354 end
2355 end
2356 end
2357 document showuserstack
2358 Syntax: showuserstack <address of thread activation>
2359 |This command displays a numeric backtrace for the user space stack of
2360 |the given thread activation. It may, of course, fail to display a
2361 |complete backtrace if portions of the user stack are not mapped in.
2362 |Symbolic backtraces can be obtained either by running gdb on the
2363 |user space binary, or a tool such as "symbolicate".
2364 |Note that while this command works on Panther's gdb, an issue
2365 |with Tiger gdb (3743135) appears to hamper the evaluation of this
2366 |macro in some cases.
2367 end
2368
2369 #Stopgap until gdb can generate the HOSTREBOOT packet
2370 define kdp-reboot
2371 #Alternatively, set *(*(unsigned **) 0x2498) = 1 (or 0x5498 on PPC)
2372 set flag_kdp_trigger_reboot = 1
2373 continue
2374 end
2375
2376 document kdp-reboot
2377 Syntax: kdp-reboot
2378 |Reboot the remote target machine; not guaranteed to succeed. Requires symbols
2379 |until gdb support for the HOSTREBOOT packet is implemented.
2380 end
2381
2382 define sendcore
2383 set kdp_trigger_core_dump = 1
2384 set kdp_flag |= 0x40
2385 set panicd_ip_str = "$arg0"
2386 set panicd_specified = 1
2387 set disable_debug_output = 0
2388 set disableConsoleOutput = 0
2389 set logPanicDataToScreen = 1
2390 set reattach_wait = 1
2391 resume_off
2392 end
2393
2394 document sendcore
2395 Syntax: sendcore <IP address>
2396 |Configure the kernel to transmit a kernel coredump to a server (kdumpd)
2397 |at the specified IP address. This is useful when the remote target has
2398 |not been previously configured to transmit coredumps, and you wish to
2399 |preserve kernel state for later examination. NOTE: You must issue a "continue"
2400 |command after using this macro to trigger the kernel coredump. The kernel
2401 |will resume waiting in the debugger after completion of the coredump. You
2402 |may disable coredumps by executing the "disablecore" macro.
2403 end
2404
2405 define disablecore
2406 set kdp_trigger_core_dump = 0
2407 set kdp_flag |= 0x40
2408 set kdp_flag &= ~0x10
2409 set panicd_specified = 0
2410 end
2411
2412 document disablecore
2413 Syntax: disablecore
2414 |Reconfigures the kernel so that it no longer transmits kernel coredumps. This
2415 |complements the "sendcore" macro, but it may be used if the kernel has been
2416 |configured to transmit coredumps through boot-args as well.
2417 end
2418
2419 define switchtocorethread
2420 set $newact = (struct thread *) $arg0
2421 select 0
2422 if ($newact->kernel_stack == 0)
2423 echo This thread does not have a stack.\n
2424 echo continuation:
2425 output/a (unsigned) $newact.continuation
2426 echo \n
2427 else
2428 if ($kgm_mtype == $kgm_mtype_ppc)
2429 loadcontext $newact->machine->pcb
2430 flushstack
2431 set $pc = $newact->machine->pcb.save_srr0
2432 else
2433 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
2434 set $kgm_cstatep = (struct x86_kernel_state *) \
2435 ($newact->kernel_stack + kernel_stack_size \
2436 - sizeof(struct x86_kernel_state))
2437 loadcontext $kgm_cstatep
2438 flushstack
2439 else
2440 echo switchtocorethread not supported on this architecture\n
2441 end
2442 end
2443 showcontext_int
2444 end
2445 end
2446
2447 document switchtocorethread
2448 Syntax: switchtocorethread <address of activation>
2449 | The corefile equivalent of "switchtoact". When debugging a kernel coredump
2450 | file, this command can be used to examine the execution context and stack
2451 | trace for a given thread activation. For example, to view the backtrace
2452 | for a thread issue "switchtocorethread <address>", followed by "bt".
2453 | Before resuming execution, issue a "resetcorectx" command, to
2454 | return to the original execution context. Note that this command
2455 | requires gdb support, as documented in Radar 3401283.
2456 end
2457
2458 define loadcontext
2459 select 0
2460 if ($kgm_mtype == $kgm_mtype_ppc)
2461 set $kgm_contextp = (struct savearea *) $arg0
2462 set $pc = $kgm_contextp.save_srr0
2463 set $r1 = $kgm_contextp.save_r1
2464 set $lr = $kgm_contextp.save_lr
2465
2466 set $r2 = $kgm_contextp.save_r2
2467 set $r3 = $kgm_contextp.save_r3
2468 set $r4 = $kgm_contextp.save_r4
2469 set $r5 = $kgm_contextp.save_r5
2470 set $r6 = $kgm_contextp.save_r6
2471 set $r7 = $kgm_contextp.save_r7
2472 set $r8 = $kgm_contextp.save_r8
2473 set $r9 = $kgm_contextp.save_r9
2474 set $r10 = $kgm_contextp.save_r10
2475 set $r11 = $kgm_contextp.save_r11
2476 set $r12 = $kgm_contextp.save_r12
2477 set $r13 = $kgm_contextp.save_r13
2478 set $r14 = $kgm_contextp.save_r14
2479 set $r15 = $kgm_contextp.save_r15
2480 set $r16 = $kgm_contextp.save_r16
2481 set $r17 = $kgm_contextp.save_r17
2482 set $r18 = $kgm_contextp.save_r18
2483 set $r19 = $kgm_contextp.save_r19
2484 set $r20 = $kgm_contextp.save_r20
2485 set $r21 = $kgm_contextp.save_r21
2486 set $r22 = $kgm_contextp.save_r22
2487 set $r23 = $kgm_contextp.save_r23
2488 set $r24 = $kgm_contextp.save_r24
2489 set $r25 = $kgm_contextp.save_r25
2490 set $r26 = $kgm_contextp.save_r26
2491 set $r27 = $kgm_contextp.save_r27
2492 set $r28 = $kgm_contextp.save_r28
2493 set $r29 = $kgm_contextp.save_r29
2494 set $r30 = $kgm_contextp.save_r30
2495 set $r31 = $kgm_contextp.save_r31
2496
2497 set $cr = $kgm_contextp.save_cr
2498 set $ctr = $kgm_contextp.save_ctr
2499 else
2500 if ($kgm_mtype == $kgm_mtype_i386)
2501 set $kgm_contextp = (struct x86_kernel_state *) $arg0
2502 set $ebx = $kgm_contextp->k_ebx
2503 set $ebp = $kgm_contextp->k_ebp
2504 set $edi = $kgm_contextp->k_edi
2505 set $esi = $kgm_contextp->k_esi
2506 set $eip = $kgm_contextp->k_eip
2507 set $pc = $kgm_contextp->k_eip
2508 else
2509 if ($kgm_mtype == $kgm_mtype_x86_64)
2510 set $kgm_contextp = (struct x86_kernel_state *) $arg0
2511 set $rbx = $kgm_contextp->k_rbx
2512 set $rbp = $kgm_contextp->k_rbp
2513 set $r12 = $kgm_contextp->k_r12
2514 set $r13 = $kgm_contextp->k_r13
2515 set $r14 = $kgm_contextp->k_r14
2516 set $r15 = $kgm_contextp->k_r15
2517 set $rip = $kgm_contextp->k_rip
2518 set $pc = $kgm_contextp->k_rip
2519 else
2520 echo loadcontext not supported on this architecture\n
2521 end
2522 end
2523 end
2524 end
2525
2526 define resetcorectx
2527 select 0
2528 if ($kgm_mtype == $kgm_mtype_ppc)
2529 set $kgm_corecontext = (struct savearea *) kdp.saved_state
2530 loadcontext $kgm_corecontext
2531 else
2532 if ($kgm_mtype == $kgm_mtype_i386)
2533 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
2534 set $ebx = $kdpstatep->ebx
2535 set $ebp = $kdpstatep->ebp
2536 set $edi = $kdpstatep->edi
2537 set $esi = $kdpstatep->esi
2538 set $eip = $kdpstatep->eip
2539 set $eax = $kdpstatep->eax
2540 set $ecx = $kdpstatep->ecx
2541 set $edx = $kdpstatep->edx
2542 flushregs
2543 flushstack
2544 set $pc = $kdpstatep->eip
2545 update
2546 else
2547 echo resetcorectx not supported on this architecture\n
2548 end
2549 end
2550 showcontext_int
2551 end
2552
2553 document resetcorectx
2554 Syntax: resetcorectx
2555 | The corefile equivalent of "resetctx". Returns to the original
2556 | execution context (that of the active thread at the time of the NMI or
2557 | panic). This command should be issued if you wish to resume
2558 | execution after using the "switchtocorethread" command.
2559 end
2560
2561 #Helper function for "showallgdbstacks"
2562
2563 define showgdbthread
2564 printf " 0x%08x ", $arg0
2565 set $kgm_thread = *(struct thread *)$arg0
2566 printf "0x%08x ", $arg0
2567 printf "%3d ", $kgm_thread.sched_pri
2568 set $kgm_state = $kgm_thread.state
2569 if $kgm_state & 0x80
2570 printf "I"
2571 end
2572 if $kgm_state & 0x40
2573 printf "P"
2574 end
2575 if $kgm_state & 0x20
2576 printf "A"
2577 end
2578 if $kgm_state & 0x10
2579 printf "H"
2580 end
2581 if $kgm_state & 0x08
2582 printf "U"
2583 end
2584 if $kgm_state & 0x04
2585 printf "R"
2586 end
2587 if $kgm_state & 0x02
2588 printf "S"
2589 end
2590 if $kgm_state & 0x01
2591 printf "W\t"
2592 printf "0x%08x ", $kgm_thread.wait_queue
2593 output /a (unsigned) $kgm_thread.wait_event
2594 if ($kgm_thread.uthread != 0)
2595 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
2596 if ($kgm_uthread->uu_wmesg != 0)
2597 printf " \"%s\"", $kgm_uthread->uu_wmesg
2598 end
2599 end
2600 end
2601 if $arg1 != 0
2602 if ($kgm_thread.kernel_stack != 0)
2603 if ($kgm_thread.reserved_stack != 0)
2604 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack
2605 end
2606 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack
2607 if ($kgm_mtype == $kgm_mtype_ppc)
2608 set $mysp = $kgm_thread.machine.pcb->save_r1
2609 end
2610 if ($kgm_mtype == $kgm_mtype_i386)
2611 set $kgm_statep = (struct x86_kernel_state *) \
2612 ($kgm_thread->kernel_stack + kernel_stack_size \
2613 - sizeof(struct x86_kernel_state))
2614 set $mysp = $kgm_statep->k_ebp
2615 end
2616 if ($kgm_mtype == $kgm_mtype_arm)
2617 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
2618 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
2619 set $mysp = $r7
2620 else
2621 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
2622 set $mysp = $kgm_statep->r[7]
2623 end
2624 end
2625 set $prevsp = 0
2626 printf "\n\t\tstacktop=0x%08x", $mysp
2627 if ($arg2 == 0)
2628 switchtoact $arg0
2629 else
2630 switchtocorethread $arg0
2631 end
2632 bt
2633 else
2634 printf "\n\t\t\tcontinuation="
2635 output /a (unsigned) $kgm_thread.continuation
2636 end
2637 printf "\n"
2638 else
2639 printf "\n"
2640 end
2641 end
2642
2643 #Use of this macro is currently (8/04) blocked by the fact that gdb
2644 #stops evaluating macros when encountering an error, such as a failure
2645 #to read memory from a certain location. Until this issue (described in
2646 #3758949) is addressed, evaluation of this macro may stop upon
2647 #encountering such an error.
2648
2649 define showallgdbstacks
2650 set $kgm_head_taskp = &tasks
2651 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
2652 while $kgm_taskp != $kgm_head_taskp
2653 showtaskheader
2654 showtaskint $kgm_taskp
2655 set $kgm_head_actp = &($kgm_taskp->threads)
2656 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
2657 while $kgm_actp != $kgm_head_actp
2658 showactheader
2659 showgdbthread $kgm_actp 1 0
2660 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
2661 end
2662 printf "\n"
2663 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
2664 end
2665 resetctx
2666 end
2667
2668 document showallgdbstacks
2669 Syntax: showallgdbstacks
2670 | An alternative to "showallstacks". Iterates through the task list and
2671 | displays a gdb generated backtrace for each kernel thread. It is
2672 | advantageous in that it is much faster than "showallstacks", and
2673 | decodes function call arguments and displays source level traces, but
2674 | it has the drawback that it doesn't determine if frames belong to
2675 | functions from kernel extensions, as with "showallstacks".
2676 | This command may terminate prematurely because of a gdb bug
2677 | (Radar 3758949), which stops macro evaluation on memory read
2678 | errors.
2679 end
2680
2681 define showallgdbcorestacks
2682 select 0
2683 set $kgm_head_taskp = &tasks
2684 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
2685 while $kgm_taskp != $kgm_head_taskp
2686 showtaskheader
2687 showtaskint $kgm_taskp
2688 set $kgm_head_actp = &($kgm_taskp->threads)
2689 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
2690 while $kgm_actp != $kgm_head_actp
2691 showactheader
2692 showgdbthread $kgm_actp 1 1
2693 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
2694 end
2695 printf "\n"
2696 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
2697 end
2698 resetcorectx
2699 end
2700
2701
2702 document showallgdbcorestacks
2703 Syntax: showallgdbcorestacks
2704 |Corefile version of "showallgdbstacks"
2705 end
2706
2707
2708 define switchtouserthread
2709 select 0
2710 if ($kgm_mtype == $kgm_mtype_ppc)
2711 if ($kdp_act_counter == 0)
2712 set $kdpstate = (struct savearea *) kdp.saved_state
2713 end
2714 set $kdp_act_counter = $kdp_act_counter + 1
2715 set $newact = (struct thread *) $arg0
2716 _kgm_flush_loop
2717 set $checkpc = $newact->machine->upcb.save_srr0
2718 if ($checkpc == 0)
2719 echo This activation does not appear to have
2720 echo \20 a valid user context.\n
2721 else
2722 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
2723 set $pc = $checkpc
2724 #flush and update seem to be executed lazily by gdb on Tiger, hence the
2725 #repeated invocations - see 3743135
2726 _kgm_flush_loop
2727 # This works because the new pmap is used only for reads
2728 set kdp_pmap = $newact->task->map->pmap
2729 _kgm_flush_loop
2730 _kgm_update_loop
2731 end
2732 else
2733 echo switchtouserthread not implemented for this architecture.\n
2734 end
2735 end
2736
2737 document switchtouserthread
2738 Syntax: switchtouserthread <address of thread>
2739 | Analogous to switchtoact, but switches to the user context of a
2740 | specified thread address. Similar to the "showuserstack"
2741 | command, but this command does not return gdb to the kernel context
2742 | immediately. This is to assist with the following (rather risky)
2743 | manoeuvre - upon switching to the user context and virtual address
2744 | space, the user may choose to call remove-symbol-file on the
2745 | mach_kernel symbol file, and then add-symbol-file on the user space
2746 | binary's symfile. gdb can then generate symbolic backtraces
2747 | for the user space thread. To return to the
2748 | kernel context and virtual address space, the process must be
2749 | reversed, i.e. call remove-symbol-file on the user space symbols, and
2750 | then add-symbol-file on the appropriate mach_kernel, and issue the
2751 | "resetstacks" command. Note that gdb may not react kindly to all these
2752 | symbol file switches. The same restrictions that apply to "showuserstack"
2753 | apply here - pages that have been paged out cannot be read while in the
2754 | debugger context, so backtraces may terminate early.
2755 | If the virtual addresses in the stack trace do not conflict with those
2756 | of symbols in the kernel's address space, it may be sufficient to
2757 | just do an add-symbol-file on the user space binary's symbol file.
2758 | Note that while this command works on Panther's gdb, an issue
2759 | with Tiger gdb (3743135) appears to hamper the evaluation of this
2760 | macro in some cases.
2761 end
2762
2763 define showmetaclass
2764 set $kgm_metaclassp = (OSMetaClass *)$arg0
2765 printf "%-5d", $kgm_metaclassp->instanceCount
2766 printf "x %5d bytes", $kgm_metaclassp->classSize
2767 printf " %s\n", $kgm_metaclassp->className->string
2768 end
2769
2770 define showstring
2771 printf "\"%s\"", ((OSString *)$arg0)->string
2772 end
2773
2774 define shownumber
2775 printf "%lld", ((OSNumber *)$arg0)->value
2776 end
2777
2778 define showboolean
2779 if ($arg0 == gOSBooleanFalse)
2780 printf "No"
2781 else
2782 printf "Yes"
2783 end
2784 end
2785
2786 define showdatabytes
2787 set $kgm_data = (OSData *)$arg0
2788
2789 printf "<"
2790 set $kgm_datap = (const unsigned char *) $kgm_data->data
2791 set $kgm_idx = 0
2792 while ( $kgm_idx < $kgm_data->length )
2793 printf "%02X", *$kgm_datap
2794 set $kgm_datap = $kgm_datap + 1
2795 set $kgm_idx = $kgm_idx + 1
2796 end
2797 printf ">\n"
2798 end
2799
2800 define showdata
2801 set $kgm_data = (OSData *)$arg0
2802
2803 printf "<"
2804 set $kgm_datap = (const unsigned char *) $kgm_data->data
2805
2806 set $kgm_printstr = 0
2807 if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3))
2808 set $kgm_bytes = *(unsigned int *) $kgm_datap
2809 if (0xffff0000 & $kgm_bytes)
2810 set $kgm_idx = 0
2811 set $kgm_printstr = 1
2812 while ($kgm_idx++ < 4)
2813 set $kgm_bytes = $kgm_bytes >> 8
2814 set $kgm_char = 0xff & $kgm_bytes
2815 if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e)))
2816 set $kgm_printstr = 0
2817 end
2818 end
2819 end
2820 end
2821
2822 set $kgm_idx = 0
2823 if ($kgm_printstr)
2824 set $kgm_quoted = 0
2825 while ($kgm_idx < $kgm_data->length)
2826 set $kgm_char = $kgm_datap[$kgm_idx++]
2827 if ($kgm_char)
2828 if (0 == $kgm_quoted)
2829 set $kgm_quoted = 1
2830 if ($kgm_idx > 1)
2831 printf ",\""
2832 else
2833 printf "\""
2834 end
2835 end
2836 printf "%c", $kgm_char
2837 else
2838 if ($kgm_quoted)
2839 set $kgm_quoted = 0
2840 printf "\""
2841 end
2842 end
2843 end
2844 if ($kgm_quoted)
2845 printf "\""
2846 end
2847 else
2848 if (0 == (3 & (unsigned int)$kgm_datap))
2849 while (($kgm_idx + 3) <= $kgm_data->length)
2850 printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx]
2851 set $kgm_idx = $kgm_idx + 4
2852 end
2853 end
2854 while ($kgm_idx < $kgm_data->length)
2855 printf "%02x", $kgm_datap[$kgm_idx++]
2856 end
2857 end
2858 printf ">"
2859 end
2860
2861 define showdictionaryint
2862 set $kgm$arg0_dict = (OSDictionary *)$arg1
2863
2864 printf "{"
2865 set $kgm$arg0_idx = 0
2866 while ($kgm$arg0_idx < $kgm$arg0_dict->count)
2867 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key
2868 showobjectint _$arg0 $kgm_obj
2869 printf "="
2870 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value
2871 showobjectint _$arg0 $kgm_obj
2872 if ($kgm$arg0_idx < $kgm$arg0_dict->count)
2873 printf ","
2874 end
2875 end
2876 printf "}"
2877 end
2878
2879 define indent
2880 set $kgm_idx = 0
2881 while ($kgm_idx < $arg0)
2882 if ($arg1 & (1 << $kgm_idx++))
2883 printf "| "
2884 else
2885 printf " "
2886 end
2887 end
2888 end
2889
2890 define showregdictionary
2891 indent $kgm_reg_depth+2 $arg1
2892 printf "{\n"
2893
2894 set $kgm_reg_idx = 0
2895 while ($kgm_reg_idx < $arg0->count)
2896 indent $kgm_reg_depth+2 $arg1
2897 printf " "
2898 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key
2899 showobjectint _ $kgm_obj
2900 printf " = "
2901
2902 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value
2903 showobjectint _ $kgm_obj
2904 printf "\n"
2905 end
2906 indent $kgm_reg_depth+2 $arg1
2907 printf "}\n"
2908 end
2909
2910
2911 define showarraysetint
2912 set $kgm$arg0_array = (OSArray *)$arg1
2913
2914 set $kgm$arg0_idx = 0
2915 while ($kgm$arg0_idx < $kgm$arg0_array->count)
2916 set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++]
2917 showobjectint _$arg0 $kgm_obj
2918 if ($kgm$arg0_idx < $kgm$arg0_array->count)
2919 printf ","
2920 end
2921 end
2922 end
2923
2924 define showarrayint
2925 printf "("
2926 showarraysetint $arg0 $arg1
2927 printf ")"
2928 end
2929
2930 define showsetint
2931 set $kgm_array = ((OSSet *)$arg1)->members
2932 printf "["
2933 showarraysetint $arg0 $kgm_array
2934 printf "]"
2935 end
2936
2937
2938 define showobjectint
2939 set $kgm_obj = (OSObject *) $arg1
2940 set $kgm_vt = *((void **) $arg1)
2941
2942 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
2943 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
2944 end
2945
2946 if ($kgm_show_object_addrs)
2947 printf "`object "
2948 showptr $arg1
2949 printf ", vt "
2950 output /a (unsigned long) $kgm_vt
2951 if ($kgm_show_object_retain)
2952 printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16
2953 end
2954 printf "` "
2955 end
2956
2957 # No multiple-inheritance
2958 set $kgm_shown = 0
2959 if ($kgm_vt == &_ZTV8OSString)
2960 showstring $arg1
2961 set $kgm_shown = 1
2962 end
2963 if ($kgm_vt == &_ZTV8OSSymbol)
2964 showstring $arg1
2965 set $kgm_shown = 1
2966 end
2967 if ($kgm_vt == &_ZTV8OSNumber)
2968 shownumber $arg1
2969 set $kgm_shown = 1
2970 end
2971 if ($kgm_vt == &_ZTV6OSData)
2972 if $kgm_show_data_alwaysbytes == 1
2973 showdatabytes $arg1
2974 else
2975 showdata $arg1
2976 end
2977 set $kgm_shown = 1
2978 end
2979 if ($kgm_vt == &_ZTV9OSBoolean)
2980 showboolean $arg1
2981 set $kgm_shown = 1
2982 end
2983 if ($kgm_vt == &_ZTV12OSDictionary)
2984 showdictionaryint _$arg0 $arg1
2985 set $kgm_shown = 1
2986 end
2987 if ($kgm_vt == &_ZTV7OSArray)
2988 showarrayint _$arg0 $arg1
2989 set $kgm_shown = 1
2990 end
2991 if ($kgm_vt == &_ZTV5OSSet)
2992 showsetint _$arg0 $arg1
2993 set $kgm_shown = 1
2994 end
2995
2996 if ($kgm_shown != 1)
2997 if ($kgm_show_object_addrs == 0)
2998 printf "`object "
2999 showptr $arg1
3000 printf ", vt "
3001 output /a (unsigned long) $kgm_vt
3002 printf "`"
3003 end
3004 end
3005 end
3006
3007 define showobject
3008 set $kgm_save = $kgm_show_object_addrs
3009 set $kgm_show_object_addrs = 1
3010 set $kgm_show_object_retain = 1
3011 showobjectint _ $arg0
3012 set $kgm_show_object_addrs = $kgm_save
3013 set $kgm_show_object_retain = 0
3014 printf "\n"
3015 end
3016 document showobject
3017 Syntax: (gdb) showobject <object address>
3018 | Show info about an OSObject - its vtable ptr and retain count.
3019 | If the object is a simple container class, more info will be shown.
3020 end
3021
3022 define dictget
3023 set $kgm_dictp = (OSDictionary *)$arg0
3024 set $kgm_keyp = (const OSSymbol *)$arg1
3025 set $kgm_idx = 0
3026 set $kgm_result = 0
3027 while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0))
3028 if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key)
3029 set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value
3030 end
3031 set $kgm_idx = $kgm_idx + 1
3032 end
3033 end
3034
3035
3036 define _registryentryrecurseinit
3037 set $kgm_re = (IOService *)$arg1
3038 set $kgm$arg0_stack = (unsigned long long) $arg2
3039
3040 if ($arg3)
3041 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
3042 else
3043 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
3044 end
3045
3046 dictget $kgm_re->fRegistryTable $kgm_childkey
3047 set $kgm$arg0_child_array = (OSArray *) $kgm_result
3048
3049 if ($kgm$arg0_child_array)
3050 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
3051 else
3052 set $kgm$arg0_child_count = 0
3053 end
3054
3055 if ($kgm$arg0_child_count)
3056 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
3057 else
3058 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
3059 end
3060 end
3061
3062 define findregistryentryrecurse
3063 set $kgm_registry_entry = 0
3064 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
3065
3066 dictget $kgm_re->fRegistryTable $kgm_namekey
3067 if ($kgm_result == 0)
3068 dictget $kgm_re->fRegistryTable gIONameKey
3069 end
3070 if ($kgm_result == 0)
3071 dictget $kgm_re->fPropertyTable gIOClassKey
3072 end
3073
3074 if ($kgm_result != 0)
3075 set $str = ((OSString *) $kgm_result)->string
3076 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
3077 if $kgm_findregistry_verbose
3078 echo .
3079 end
3080
3081 if $kgm_strcmp_result == 0
3082 if $kgm_findregistry_verbose
3083 printf "\n%s:\n | ", ((OSString *) $kgm_result)->string
3084 showobject $kgm_re
3085 printf " | "
3086 print $kgm_re
3087 end
3088
3089 # if we want to show everything, then don't populate $kgm_registry_entry
3090 if !$kgm_findregistry_continue
3091 set $kgm_registry_entry = $kgm_re
3092 end
3093 end
3094 end
3095
3096 # recurse
3097 if (!$kgm_registry_entry && ($kgm$arg0_child_count != 0))
3098 set $kgm_reg_depth = $kgm_reg_depth + 1
3099 set $kgm$arg0_child_idx = 0
3100
3101 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3102 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
3103 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3104 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
3105 loop_break
3106 end
3107 findregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
3108 if $kgm_registry_entry
3109 loop_break
3110 end
3111 end
3112 set $kgm_reg_depth = $kgm_reg_depth - 1
3113 end
3114 end
3115
3116 define findregdictvalue
3117 set $kgm_registry_value = 0
3118 set $kgm_reg_idx = 0
3119 while ($kgm_reg_idx < $arg0->count)
3120 set $kgm_obj = $arg0->dictionary + $kgm_reg_idx
3121 set $str = ((OSString *)$kgm_obj->key)->string
3122 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
3123
3124 if $kgm_strcmp_result == 0
3125 set $kgm_registry_value = $kgm_obj->value
3126 if $kgm_findregistry_verbose
3127 showobject $kgm_registry_value
3128 print $kgm_registry_value
3129 end
3130 loop_break
3131 end
3132 set $kgm_reg_idx = $kgm_reg_idx + 1
3133 end
3134 end
3135
3136 define setfindregistrystr
3137 set $kgm_reg_find_str0 = 0
3138 set $kgm_reg_find_str1 = 0
3139 set $kgm_reg_find_str2 = 0
3140 set $kgm_reg_find_str3 = 0
3141 set $kgm_reg_find_str4 = 0
3142 set $kgm_reg_find_str5 = 0
3143 set $kgm_reg_find_str6 = 0
3144 set $kgm_reg_find_str7 = 0
3145 set $kgm_reg_find_str8 = 0
3146
3147 if $argc > 0
3148 set $kgm_reg_find_str0 = $arg0
3149 end
3150 if $argc > 1
3151 set $kgm_reg_find_str1 = $arg1
3152 end
3153 if $argc > 2
3154 set $kgm_reg_find_str2 = $arg2
3155 end
3156 if $argc > 3
3157 set $kgm_reg_find_str3 = $arg3
3158 end
3159 if $argc > 4
3160 set $kgm_reg_find_str4 = $arg4
3161 end
3162 if $argc > 5
3163 set $kgm_reg_find_str5 = $arg5
3164 end
3165 if $argc > 6
3166 set $kgm_reg_find_str6 = $arg6
3167 end
3168 if $argc > 7
3169 set $kgm_reg_find_str7 = $arg7
3170 end
3171 if $argc > 8
3172 set $kgm_reg_find_str8 = $arg8
3173 end
3174 end
3175
3176 document setfindregistrystr
3177 Syntax: (gdb) setfindregistrystr [a] [b] [c] [d] [e] [f] [g] [h] [i]
3178 | Store an encoded string into up to 9 arguments for use by
3179 | findregistryprop or findregistryentry. The arguments are created
3180 | through calls to strcmp_arg_pack64
3181 end
3182
3183 define _findregistryprop
3184 set $reg = (IOService *) $arg0
3185 set $kgm_props = $reg->fPropertyTable
3186 set $kgm_findregistry_verbose = 0
3187
3188 findregdictvalue $kgm_props
3189 end
3190
3191 define findregistryprop
3192 set $reg = (IOService *) $arg0
3193 set $kgm_props = $reg->fPropertyTable
3194
3195 set $kgm_findregistry_verbose = 1
3196 findregdictvalue $kgm_props
3197 end
3198
3199 document findregistryprop
3200 Syntax: (gdb) findregistryprop <entry>
3201 | Given a registry entry, print out the contents for the property that matches
3202 | the encoded string specified via setfindregistrystr.
3203 |
3204 | For example, the following will print out the "intel-pic" property stored in
3205 | the AppleACPIPlatformExpert registry entry $pe_entry:
3206 | strcmp_arg_pack64 'i' 'n' 't' 'e' 'l' '-' 'p' 'i'
3207 | set $intel_pi = $kgm_strcmp_arg
3208 | strcmp_arg_pack64 'c' 0 0 0 0 0 0 0
3209 | set $c = $kgm_strcmp_arg
3210 | setfindregistrystr $intel_pi $c
3211 | findregistryprop $pe_entry
3212 end
3213
3214 define findregistryentryint
3215 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
3216 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
3217 if $kgm_findregistry_verbose
3218 printf "Searching"
3219 end
3220 findregistryentryrecurse _ $arg0 0 0
3221 end
3222
3223 define _findregistryentry
3224 set $kgm_findregistry_verbose = 0
3225 set $kgm_findregistry_continue = 0
3226 set $kgm_reg_depth = 0
3227
3228 findregistryentryint gRegistryRoot
3229 end
3230
3231 define findregistryentry
3232 set $kgm_findregistry_verbose = 1
3233 set $kgm_findregistry_continue = 0
3234 set $kgm_reg_depth = 0
3235
3236 findregistryentryint gRegistryRoot
3237 end
3238
3239 define findregistryentries
3240 set $kgm_findregistry_verbose = 1
3241 set $kgm_findregistry_continue = 1
3242 set $kgm_reg_depth = 0
3243
3244 findregistryentryint gRegistryRoot
3245 end
3246
3247 document findregistryentry
3248 Syntax: (gdb) findregistryentry
3249 | Search for a registry entry that matches the encoded string specified through
3250 | setfindregistrystr. You can alter the search depth through use of
3251 | $kgm_reg_depth_max.
3252 |
3253 | For example, the following will pull out the AppleACPIPlatformExpert registry
3254 | entry:
3255 | strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
3256 | set $AppleACP = $kgm_strcmp_arg
3257 | strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
3258 | set $IPlatfor = $kgm_strcmp_arg
3259 | strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
3260 | set $mExpert = $kgm_strcmp_arg
3261 | setfindregistrystr $AppleACP $IPlatfor $mExpert
3262 | findregistryentry
3263 end
3264
3265 document findregistryentries
3266 Syntax: (gdb) findregistryentries
3267 | Search for all registry entries that match the encoded string specified through
3268 | setfindregistrystr. You can alter the search depth through use of
3269 | $kgm_reg_depth_max. See findregistryentry for an example of how to encode a string.
3270 end
3271
3272
3273 define showregistryentryrecurse
3274 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
3275
3276 indent $kgm_reg_depth $kgm$arg0_stack
3277 printf "+-o "
3278
3279 dictget $kgm_re->fRegistryTable $kgm_namekey
3280 if ($kgm_result == 0)
3281 dictget $kgm_re->fRegistryTable gIONameKey
3282 end
3283 if ($kgm_result == 0)
3284 dictget $kgm_re->fPropertyTable gIOClassKey
3285 end
3286
3287 if ($kgm_result != 0)
3288 printf "%s", ((OSString *)$kgm_result)->string
3289 else
3290 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
3291 printf "%s", ((IOService*)$kgm_re)->pwrMgt->Name
3292 else
3293 # printf ", guessclass "
3294 # guessclass $kgm_re
3295 printf "??"
3296 end
3297 end
3298
3299
3300 printf " <object "
3301 showptr $kgm_re
3302 printf ", id 0x%llx, ", $kgm_re->IORegistryEntry::reserved->fRegistryEntryID
3303 printf "vtable "
3304 set $kgm_vt = (unsigned long) *(void**) $kgm_re
3305 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
3306 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
3307 end
3308 output /a $kgm_vt
3309
3310 if ($kgm_vt != &_ZTV15IORegistryEntry)
3311 printf ", "
3312 set $kgm_state = $kgm_re->__state[0]
3313 # kIOServiceRegisteredState
3314 if (0 == ($kgm_state & 2))
3315 printf "!"
3316 end
3317 printf "registered, "
3318 # kIOServiceMatchedState
3319 if (0 == ($kgm_state & 4))
3320 printf "!"
3321 end
3322 printf "matched, "
3323 # kIOServiceInactiveState
3324 if ($kgm_state & 1)
3325 printf "in"
3326 end
3327 printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount)
3328 end
3329 printf ">\n"
3330
3331 if ($kgm_show_props)
3332 set $kgm_props = $kgm_re->fPropertyTable
3333 showregdictionary $kgm_props $kgm$arg0_stack
3334 end
3335
3336 # recurse
3337 if ($kgm$arg0_child_count != 0)
3338
3339 set $kgm_reg_depth = $kgm_reg_depth + 1
3340 set $kgm$arg0_child_idx = 0
3341
3342 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3343 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
3344 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
3345 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
3346 loop_break
3347 end
3348 showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
3349 end
3350
3351 set $kgm_reg_depth = $kgm_reg_depth - 1
3352 end
3353 end
3354
3355 define showregistryentryint
3356 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
3357 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
3358
3359 showregistryentryrecurse _ $arg0 0 0
3360 end
3361
3362 define showregistry
3363 set $kgm_reg_depth = 0
3364 set $kgm_show_props = 0
3365 showregistryentryint gRegistryRoot
3366 end
3367 document showregistry
3368 Syntax: (gdb) showregistry
3369 | Show info about all registry entries in the current plane. You can specify the maximum
3370 | display depth with $kgm_reg_depth_max.
3371 end
3372
3373 define showregistryprops
3374 set $kgm_reg_depth = 0
3375 set $kgm_show_props = 1
3376 showregistryentryint gRegistryRoot
3377 end
3378 document showregistryprops
3379 Syntax: (gdb) showregistryprops
3380 | Show info about all registry entries in the current plane, and their properties.
3381 | set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display
3382 | more verbose information
3383 end
3384
3385 define showregistryentry
3386 set $kgm_reg_depth = 0
3387 set $kgm_show_props = 1
3388 showregistryentryint $arg0
3389 end
3390 document showregistryentry
3391 Syntax: (gdb) showregistryentry <object address>
3392 | Show info about a registry entry; its properties and descendants in the current plane.
3393 end
3394
3395 define setregistryplane
3396 if ($arg0 != 0)
3397 set $kgm_reg_plane = (IORegistryPlane *) $arg0
3398 else
3399 showobjectint _ gIORegistryPlanes
3400 printf "\n"
3401 end
3402 end
3403 document setregistryplane
3404 Syntax: (gdb) setregistryplane <plane object address>
3405 | Set the plane to be used for the iokit registry macros. An argument of zero will
3406 | display known planes.
3407 end
3408
3409 define guessclass
3410 set $kgm_classidx = 0
3411 set $kgm_lookvt = *((void **) $arg0)
3412 set $kgm_bestvt = (void *) 0
3413 set $kgm_bestidx = 0
3414
3415 while $kgm_classidx < sAllClassesDict->count
3416 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value
3417
3418 set $kgm_vt = *((void **) $kgm_meta)
3419
3420 if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt))
3421 set $kgm_bestvt = $kgm_vt
3422 set $kgm_bestidx = $kgm_classidx
3423 end
3424 set $kgm_classidx = $kgm_classidx + 1
3425 end
3426 printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string
3427 end
3428
3429 define showallclasses
3430 set $kgm_classidx = 0
3431 while $kgm_classidx < sAllClassesDict->count
3432 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value
3433 showmetaclass $kgm_meta
3434 end
3435 end
3436
3437 document showallclasses
3438 Syntax: (gdb) showallclasses
3439 | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
3440 end
3441
3442 define showioalloc
3443 printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024
3444 printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024
3445 printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024
3446 printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024
3447 end
3448
3449 document showioalloc
3450 Syntax: (gdb) showioalloc
3451 | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
3452 end
3453
3454 define showosobjecttracking
3455 set $kgm_next = (OSObjectTracking *) gOSObjectTrackList.next
3456 while $kgm_next != &gOSObjectTrackList
3457 set $obj = (OSObject *) ($kgm_next+1)
3458 showobject $obj
3459 set $kgm_idx = 0
3460 while $kgm_idx < (sizeof($kgm_next->bt) / sizeof($kgm_next->bt[0]))
3461 if ((unsigned long) $kgm_next->bt[$kgm_idx] > (unsigned long) &last_kernel_symbol)
3462 showkmodaddr $kgm_next->bt[$kgm_idx]
3463 printf "\n"
3464 else
3465 if ((unsigned long) $kgm_next->bt[$kgm_idx] > 0)
3466 output /a $kgm_next->bt[$kgm_idx]
3467 printf "\n"
3468 end
3469 end
3470 set $kgm_idx = $kgm_idx + 1
3471 end
3472 printf "\n"
3473 set $kgm_next = (OSObjectTracking *) $kgm_next->link.next
3474 end
3475 end
3476
3477 document showosobjecttracking
3478 Syntax: (gdb) showosobjecttracking
3479 | Show the list of tracked OSObject allocations with backtraces.
3480 | Boot with the kOSTraceObjectAlloc (0x00400000) io debug flag set.
3481 | Set gOSObjectTrackThread to 1 or a thread_t to capture new OSObjects allocated by a thread or all threads.
3482 end
3483
3484 define readphysint
3485 set $kgm_readphysint_result = 0xBAD10AD
3486 # set up the manual KDP packet
3487 set manual_pkt.input = 0
3488 set manual_pkt.len = sizeof(kdp_readphysmem64_req_t)
3489 set $kgm_pkt = (kdp_readphysmem64_req_t *)&manual_pkt.data
3490 set $kgm_pkt->hdr.request = KDP_READPHYSMEM64
3491 set $kgm_pkt->hdr.len = sizeof(kdp_readphysmem64_req_t)
3492 set $kgm_pkt->hdr.is_reply = 0
3493 set $kgm_pkt->hdr.seq = 0
3494 set $kgm_pkt->hdr.key = 0
3495 set $kgm_pkt->address = (uint64_t)$arg0
3496 set $kgm_pkt->nbytes = $arg1 >> 3
3497 set $kgm_pkt->lcpu = $arg2
3498 set manual_pkt.input = 1
3499 # dummy to make sure manual packet is executed
3500 set $kgm_dummy = &_mh_execute_header
3501 set $kgm_pkt = (kdp_readphysmem64_reply_t *)&manual_pkt.data
3502 if ($kgm_pkt->error == 0)
3503 if $arg1 == 8
3504 set $kgm_readphysint_result = *((uint8_t *)$kgm_pkt->data)
3505 end
3506 if $arg1 == 16
3507 set $kgm_readphysint_result = *((uint16_t *)$kgm_pkt->data)
3508 end
3509 if $arg1 == 32
3510 set $kgm_readphysint_result = *((uint32_t *)$kgm_pkt->data)
3511 end
3512 if $arg1 == 64
3513 set $kgm_readphysint_result = *((uint64_t *)$kgm_pkt->data)
3514 end
3515 end
3516 end
3517
3518 define readphys8
3519 readphysint $arg0 8 $kgm_lcpu_self
3520 output /a $arg0
3521 printf ":\t0x%02hhx\n", $kgm_readphysint_result
3522 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3523 end
3524
3525 define readphys16
3526 readphysint $arg0 16 $kgm_lcpu_self
3527 output /a $arg0
3528 printf ":\t0x%04hx\n", $kgm_readphysint_result
3529 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3530 end
3531
3532 define readphys32
3533 readphysint $arg0 32 $kgm_lcpu_self
3534 output /a $arg0
3535 printf ":\t0x%08x\n", $kgm_readphysint_result
3536 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3537 end
3538
3539 define readphys64
3540 readphysint $arg0 64 $kgm_lcpu_self
3541 output /a $arg0
3542 printf ":\t0x%016llx\n", $kgm_readphysint_result
3543 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
3544 end
3545
3546 define readphys
3547 readphys32 $arg0
3548 end
3549
3550 document readphys8
3551 | See readphys64
3552 end
3553
3554 document readphys16
3555 | See readphys64
3556 end
3557
3558 document readphys32
3559 | See readphys64
3560 end
3561
3562 document readphys64
3563 | The argument is interpreted as a physical address, and the 64-bit word
3564 | addressed is displayed. Saves 64-bit result in $kgm_readphys_result.
3565 end
3566
3567 define writephysint
3568 # set up the manual KDP packet
3569 set manual_pkt.input = 0
3570 set manual_pkt.len = sizeof(kdp_writephysmem64_req_t)
3571 set $kgm_pkt = (kdp_writephysmem64_req_t *)&manual_pkt.data
3572 set $kgm_pkt->hdr.request = KDP_WRITEPHYSMEM64
3573 set $kgm_pkt->hdr.len = sizeof(kdp_writephysmem64_req_t)
3574 set $kgm_pkt->hdr.is_reply = 0
3575 set $kgm_pkt->hdr.seq = 0
3576 set $kgm_pkt->hdr.key = 0
3577 set $kgm_pkt->address = (uint64_t)$arg0
3578 set $kgm_pkt->nbytes = $arg1 >> 3
3579 set $kgm_pkt->lcpu = $arg3
3580 if $arg1 == 8
3581 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
3582 end
3583 if $arg1 == 16
3584 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
3585 end
3586 if $arg1 == 32
3587 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
3588 end
3589 if $arg1 == 64
3590 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg2
3591 end
3592 set manual_pkt.input = 1
3593 # dummy to make sure manual packet is executed
3594 set $kgm_dummy = &_mh_execute_header
3595 set $kgm_pkt = (kdp_writephysmem64_reply_t *)&manual_pkt.data
3596 set $kgm_writephysint_result = $kgm_pkt->error
3597 end
3598
3599 define writephys8
3600 writephysint $arg0 8 $arg1 $kgm_lcpu_self
3601 end
3602
3603 define writephys16
3604 writephysint $arg0 16 $arg1 $kgm_lcpu_self
3605 end
3606
3607 define writephys32
3608 writephysint $arg0 32 $arg1 $kgm_lcpu_self
3609 end
3610
3611 define writephys64
3612 writephysint $arg0 64 $arg1 $kgm_lcpu_self
3613 end
3614
3615 document writephys8
3616 | See writephys64
3617 end
3618
3619 document writephys16
3620 | See writephys64
3621 end
3622
3623 document writephys32
3624 | See writephys64
3625 end
3626
3627 document writephys64
3628 | The argument is interpreted as a physical address, and the second argument is
3629 | written to that address as a 64-bit word.
3630 end
3631
3632 define addkextsyms
3633 shell ls $arg0/* | xargs -n 1 echo add-symbol-file > /tmp/gdb-syms
3634 source /tmp/gdb-syms
3635 set $kgm_show_kmod_syms = 1
3636 end
3637
3638 document addkextsyms
3639 | Takes a directory of symbols for kexts generated with kextcache -y and loads them
3640 | into gdb.
3641 | (gdb) addkextsyms /path/to/symboldir
3642 end
3643
3644 define showprocfiles
3645 if ($argc == 1)
3646 _showprocheader
3647 _showprocfiles $arg0
3648 else
3649 printf "| Usage:\n|\n"
3650 help showprocfiles
3651 end
3652 end
3653 document showprocfiles
3654 Syntax: (gdb) showprocfiles <proc_t>
3655 | Given a proc_t pointer, display the list of open file descriptors for the
3656 | referenced process.
3657 end
3658
3659 define _showprocheader
3660 printf "fd fileglob "
3661 showptrhdrpad
3662 printf " fg flags fg type fg data "
3663 showptrhdrpad
3664 printf " info\n"
3665 printf "----- ----------"
3666 if $kgm_lp64
3667 printf "--------"
3668 end
3669 printf " ---------- -------- ----------"
3670 if $kgm_lp64
3671 printf "--------"
3672 end
3673 printf " -------------------\n"
3674 end
3675
3676 define _showprocfiles
3677 set $kgm_spf_filedesc = ((proc_t)$arg0)->p_fd
3678 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
3679 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
3680 set $kgm_spf_count = 0
3681 while ($kgm_spf_count <= $kgm_spf_last)
3682 if ($kgm_spf_ofiles[$kgm_spf_count] == 0)
3683 # DEBUG: For files that were open, but are now closed
3684 # printf "%-5d FILEPROC_NULL\n", $kgm_spf_count
3685 else
3686 # display fd #, fileglob address, fileglob flags
3687 set $kgm_spf_flags = $kgm_spf_ofiles[$kgm_spf_count].f_flags
3688 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
3689 printf "%-5d ", $kgm_spf_count
3690 showptr $kgm_spf_fg
3691 printf " 0x%08x ", $kgm_spf_flags
3692 # decode fileglob type
3693 set $kgm_spf_fgt = $kgm_spf_fg->fg_type
3694 if ($kgm_spf_fgt == 1)
3695 printf "VNODE "
3696 end
3697 if ($kgm_spf_fgt == 2)
3698 printf "SOCKET "
3699 end
3700 if ($kgm_spf_fgt == 3)
3701 printf "PSXSHM "
3702 end
3703 if ($kgm_spf_fgt == 4)
3704 printf "PSXSEM "
3705 end
3706 if ($kgm_spf_fgt == 5)
3707 printf "KQUEUE "
3708 end
3709 if ($kgm_spf_fgt == 6)
3710 printf "PIPE "
3711 end
3712 if ($kgm_spf_fgt == 7)
3713 printf "FSEVENTS"
3714 end
3715 if ($kgm_spf_fgt < 1 || $kgm_spf_fgt > 7)
3716 printf "?: %-5d", $kgm_spf_fgt
3717 end
3718
3719 # display fileglob data address and decode interesting fact(s)
3720 # about data, if we know any
3721 set $kgm_spf_fgd = $kgm_spf_fg->fg_data
3722 printf " "
3723 showptr $kgm_spf_fgd
3724 printf " "
3725 if ($kgm_spf_fgt == 1)
3726 set $kgm_spf_name = ((struct vnode *)$kgm_spf_fgd)->v_name
3727 if ($kgm_spf_name == 0)
3728 printf "(null)"
3729 else
3730 printf "%s", $kgm_spf_name
3731 end
3732 end
3733 printf "\n"
3734 end
3735 set $kgm_spf_count = $kgm_spf_count + 1
3736 end
3737 end
3738
3739 #
3740 # Show all the advisory file locks held by a process for each of the vnode
3741 # type files that it has open; do this by walking the per process open file
3742 # table and looking at any vnode type fileglob that has a non-NULL lock list
3743 # associated with it.
3744 #
3745 define showproclocks
3746 if ($argc == 1)
3747 _showproclocks $arg0
3748 else
3749 printf "| Usage:\n|\n"
3750 help showproclocks
3751 end
3752 end
3753 document showproclocks
3754 Syntax: (gdb) showproclocks <proc_t>
3755 | Given a proc_t pointer, display the list of advisory file locks held by the
3756 | referenced process.
3757 end
3758
3759 define _showproclocks
3760 set $kgm_spl_filedesc = ((proc_t)$arg0)->p_fd
3761 set $kgm_spl_last = $kgm_spl_filedesc->fd_lastfile
3762 set $kgm_spl_ofiles = $kgm_spl_filedesc->fd_ofiles
3763 set $kgm_spl_count = 0
3764 set $kgm_spl_seen = 0
3765 while ($kgm_spl_count <= $kgm_spl_last)
3766 if ($kgm_spl_ofiles[$kgm_spl_count] == 0)
3767 # DEBUG: For files that were open, but are now closed
3768 # printf "%-5d FILEPROC_NULL\n", $kgm_spl_count
3769 else
3770 set $kgm_spl_fg = $kgm_spl_ofiles[$kgm_spl_count].f_fglob
3771 # decode fileglob type
3772 set $kgm_spl_fgt = $kgm_spl_fg->fg_type
3773 if ($kgm_spl_fgt == 1)
3774 set $kgm_spl_fgd = $kgm_spl_fg->fg_data
3775 set $kgm_spl_name = ((struct vnode *)$kgm_spl_fgd)->v_name
3776 set $kgm_spl_vnode = ((vnode_t)$kgm_spl_fgd)
3777 set $kgm_spl_lockiter = $kgm_spl_vnode->v_lockf
3778 if ($kgm_spl_lockiter != 0)
3779 if ($kgm_spl_seen == 0)
3780 _showvnodelockheader
3781 end
3782 set $kgm_spl_seen = $kgm_spl_seen + 1
3783 printf "( fd %d, name ", $kgm_spl_count
3784 if ($kgm_spl_name == 0)
3785 printf "(null) )"
3786 else
3787 printf "%s )\n", $kgm_spl_name
3788 end
3789 _showvnodelocks $kgm_spl_fgd
3790 end
3791 end
3792 end
3793 set $kgm_spl_count = $kgm_spf_count + 1
3794 end
3795 printf "%d total locks for ", $kgm_spl_seen
3796 showptr $arg0
3797 printf "\n"
3798 end
3799
3800 define showprocinfo
3801 set $kgm_spi_proc = (proc_t)$arg0
3802 printf "Process "
3803 showptr $kgm_spi_proc
3804 printf "\n"
3805 printf " name %s\n", $kgm_spi_proc->p_comm
3806 printf " pid:%.8d", $kgm_spi_proc->p_pid
3807 printf " task:"
3808 showptr $kgm_spi_proc->task
3809 printf " p_stat:%.1d", $kgm_spi_proc->p_stat
3810 printf " parent pid:%.8d", $kgm_spi_proc->p_ppid
3811 printf "\n"
3812 # decode part of credential
3813 set $kgm_spi_cred = $kgm_spi_proc->p_ucred
3814 if ($kgm_spi_cred != 0)
3815 printf "Cred: euid %d ruid %d svuid %d\n", $kgm_spi_cred->cr_uid, $kgm_spi_cred->cr_ruid, $kgm_spi_cred->cr_svuid
3816 else
3817 printf "Cred: (null)\n"
3818 end
3819 # decode flags
3820 set $kgm_spi_flag = $kgm_spi_proc->p_flag
3821 printf "Flags: 0x%08x\n", $kgm_spi_flag
3822 if ($kgm_spi_flag & 0x00000001)
3823 printf " 0x00000001 - may hold advisory locks\n"
3824 end
3825 if ($kgm_spi_flag & 0x00000002)
3826 printf " 0x00000002 - has a controlling tty\n"
3827 end
3828 if ($kgm_spi_flag & 0x00000004)
3829 printf " 0x00000004 - process is 64 bit\n"
3830 else
3831 printf " !0x00000004 - process is 32 bit\n"
3832 end
3833 if ($kgm_spi_flag & 0x00000008)
3834 printf " 0x00000008 - no SIGCHLD on child stop\n"
3835 end
3836 if ($kgm_spi_flag & 0x00000010)
3837 printf " 0x00000010 - waiting for child exec/exit\n"
3838 end
3839 if ($kgm_spi_flag & 0x00000020)
3840 printf " 0x00000020 - has started profiling\n"
3841 end
3842 if ($kgm_spi_flag & 0x00000040)
3843 printf " 0x00000040 - in select; wakeup/waiting danger\n"
3844 end
3845 if ($kgm_spi_flag & 0x00000080)
3846 printf " 0x00000080 - was stopped and continued\n"
3847 end
3848 if ($kgm_spi_flag & 0x00000100)
3849 printf " 0x00000100 - has set privileges since exec\n"
3850 end
3851 if ($kgm_spi_flag & 0x00000200)
3852 printf " 0x00000200 - system process: no signals, stats, or swap\n"
3853 end
3854 if ($kgm_spi_flag & 0x00000400)
3855 printf " 0x00000400 - timing out during a sleep\n"
3856 end
3857 if ($kgm_spi_flag & 0x00000800)
3858 printf " 0x00000800 - debugged process being traced\n"
3859 end
3860 if ($kgm_spi_flag & 0x00001000)
3861 printf " 0x00001000 - debugging process has waited for child\n"
3862 end
3863 if ($kgm_spi_flag & 0x00002000)
3864 printf " 0x00002000 - exit in progress\n"
3865 end
3866 if ($kgm_spi_flag & 0x00004000)
3867 printf " 0x00004000 - process has called exec\n"
3868 end
3869 if ($kgm_spi_flag & 0x00008000)
3870 printf " 0x00008000 - owe process an addupc() XXX\n"
3871 end
3872 if ($kgm_spi_flag & 0x00010000)
3873 printf " 0x00010000 - affinity for Rosetta children\n"
3874 end
3875 if ($kgm_spi_flag & 0x00020000)
3876 printf " 0x00020000 - wants to run Rosetta\n"
3877 end
3878 if ($kgm_spi_flag & 0x00040000)
3879 printf " 0x00040000 - has wait() in progress\n"
3880 end
3881 if ($kgm_spi_flag & 0x00080000)
3882 printf " 0x00080000 - kdebug tracing on for this process\n"
3883 end
3884 if ($kgm_spi_flag & 0x00100000)
3885 printf " 0x00100000 - blocked due to SIGTTOU or SIGTTIN\n"
3886 end
3887 if ($kgm_spi_flag & 0x00200000)
3888 printf " 0x00200000 - has called reboot()\n"
3889 end
3890 if ($kgm_spi_flag & 0x00400000)
3891 printf " 0x00400000 - is TBE state\n"
3892 end
3893 if ($kgm_spi_flag & 0x00800000)
3894 printf " 0x00800000 - signal exceptions\n"
3895 end
3896 if ($kgm_spi_flag & 0x01000000)
3897 printf " 0x01000000 - has thread cwd\n"
3898 end
3899 if ($kgm_spi_flag & 0x02000000)
3900 printf " 0x02000000 - has vfork() children\n"
3901 end
3902 if ($kgm_spi_flag & 0x04000000)
3903 printf " 0x04000000 - not allowed to attach\n"
3904 end
3905 if ($kgm_spi_flag & 0x08000000)
3906 printf " 0x08000000 - vfork() in progress\n"
3907 end
3908 if ($kgm_spi_flag & 0x10000000)
3909 printf " 0x10000000 - no shared libraries\n"
3910 end
3911 if ($kgm_spi_flag & 0x20000000)
3912 printf " 0x20000000 - force quota for root\n"
3913 end
3914 if ($kgm_spi_flag & 0x40000000)
3915 printf " 0x40000000 - no zombies when children exit\n"
3916 end
3917 if ($kgm_spi_flag & 0x80000000)
3918 printf " 0x80000000 - don't hang on remote FS ops\n"
3919 end
3920 # decode state
3921 set $kgm_spi_state = $kgm_spi_proc->p_stat
3922 printf "State: "
3923 if ($kgm_spi_state == 1)
3924 printf "Idle\n"
3925 end
3926 if ($kgm_spi_state == 2)
3927 printf "Run\n"
3928 end
3929 if ($kgm_spi_state == 3)
3930 printf "Sleep\n"
3931 end
3932 if ($kgm_spi_state == 4)
3933 printf "Stop\n"
3934 end
3935 if ($kgm_spi_state == 5)
3936 printf "Zombie\n"
3937 end
3938 if ($kgm_spi_state == 6)
3939 printf "Reaping\n"
3940 end
3941 if ($kgm_spi_state < 1 || $kgm_spi_state > 6)
3942 printf "(Unknown)\n"
3943 end
3944 end
3945
3946 document showprocinfo
3947 Syntax: (gdb) showprocinfo <proc_t>
3948 | Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
3949 end
3950
3951 #
3952 # dump the zombprocs
3953 #
3954 define zombproc
3955 set $basep = (struct proc *)zombproc->lh_first
3956 set $pp = $basep
3957 while $pp
3958 showprocinfo $pp
3959 set $pp = $pp->p_list.le_next
3960 end
3961 end
3962
3963 document zombproc
3964 Syntax: (gdb) zombproc
3965 | Routine to print out all procs in the zombie list
3966 end
3967
3968 #
3969 # dump the zombstacks
3970 #
3971 define zombstacks
3972 set $basep = (struct proc *)zombproc->lh_first
3973 set $pp = $basep
3974 while $pp
3975 if $pp->p_stat != 5
3976 showtaskstacks $pp->task
3977 end
3978 set $pp = $pp->p_list.le_next
3979 end
3980 end
3981
3982 document zombstacks
3983 Syntax: (gdb) zombstacks
3984 | Routine to print out all stacks of tasks that are exiting
3985 end
3986
3987
3988 #
3989 # dump the allprocs
3990 #
3991 define allproc
3992 set $basep = (struct proc *)allproc->lh_first
3993 set $pp = $basep
3994 while $pp
3995 showprocinfo $pp
3996 set $pp = $pp->p_list.le_next
3997 end
3998 end
3999
4000 document allproc
4001 Syntax: (gdb) allproc
4002 | Routine to print out all process in the system
4003 | which are not in the zombie list
4004 end
4005
4006
4007
4008 define print_vnode
4009 set $vp = (struct vnode *)$arg0
4010 printf " "
4011 printf " vp "
4012 showptr $vp
4013 printf " use %d", $vp->v_usecount
4014 printf " io %d", $vp->v_iocount
4015 printf " kuse %d", $vp->v_kusecount
4016 printf " type %d", $vp->v_type
4017 printf " flg 0x%.8x", $vp->v_flag
4018 printf " lflg 0x%.8x", $vp->v_lflag
4019 printf " par "
4020 showptr $vp->v_parent
4021 set $_name = (char *)$vp->v_name
4022 if ($_name != 0)
4023 printf " %s", $_name
4024 end
4025 if ($vp->v_type == VREG) && ($vp->v_un.vu_ubcinfo != 0)
4026 printf " mapped %d", ($vp->v_un.vu_ubcinfo.ui_flags & 0x08) ? 1 : 0
4027 end
4028 printf "\n"
4029 end
4030
4031 document print_vnode
4032 Syntax: (gdb) print_vnode <vnode>
4033 | Prints out the fields of a vnode struct
4034 end
4035
4036 define showprocvnodes
4037 set $pp = (struct proc *)$arg0
4038 set $fdp = (struct filedesc *)$pp->p_fd
4039 set $cvp = $fdp->fd_cdir
4040 set $rvp = $fdp->fd_rdir
4041 if $cvp
4042 printf "Current Working Directory \n"
4043 print_vnode $cvp
4044 printf "\n"
4045 end
4046 if $rvp
4047 printf "Current Root Directory \n"
4048 print_vnode $rvp
4049 printf "\n"
4050 end
4051 set $count = 0
4052 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
4053 set $fpo = (char)($fdp->fd_ofileflags[0])
4054 while $count < $fdp->fd_nfiles
4055 #printf"fpp %x ", *$fpp
4056 if *$fpp
4057 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
4058 if $fg && (($fg)->fg_type == 1)
4059 if $fdp->fd_ofileflags[$count] & 4
4060 printf "U: "
4061 else
4062 printf " "
4063 end
4064 printf "fd = %d ", $count
4065 print_vnode $fg->fg_data
4066 end
4067 end
4068 set $fpp = $fpp + 1
4069 set $count = $count + 1
4070 end
4071 end
4072
4073 document showprocvnodes
4074 Syntax: (gdb) showprocvnodes <proc_address>
4075 | Routine to print out all the open fds
4076 | which are vnodes in a process
4077 end
4078
4079 define showallprocvnodes
4080 set $basep = (struct proc *)allproc->lh_first
4081 set $pp = $basep
4082 while $pp
4083 printf "============================================ \n"
4084 showprocinfo $pp
4085 showprocvnodes $pp
4086 set $pp = $pp->p_list.le_next
4087 end
4088 end
4089
4090 document showallprocvnodes
4091 Syntax: (gdb) showallprocvnodes
4092 | Routine to print out all the open fds
4093 | which are vnodes
4094 end
4095
4096
4097 #
4098 # dump the childrent of a proc
4099 #
4100 define showinitchild
4101 set $basep = (struct proc *)initproc->p_children.lh_first
4102 set $pp = $basep
4103 while $pp
4104 showprocinfo $pp
4105 set $pp = $pp->p_sibling.le_next
4106 end
4107 end
4108
4109 document showinitchild
4110 Syntax: (gdb) showinitchild
4111 | Routine to print out all processes in the system
4112 | which are children of init process
4113 end
4114
4115
4116 define showmountallvnodes
4117 set $mp = (struct mount *)$arg0
4118 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
4119 set $vp = $basevp
4120 printf "____________________ Vnode list Queue ---------------\n"
4121 while $vp
4122 print_vnode $vp
4123 set $vp = $vp->v_mntvnodes->tqe_next
4124 end
4125 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
4126 set $vp = $basevp
4127 printf "____________________ Worker Queue ---------------\n"
4128 while $vp
4129 print_vnode $vp
4130 set $vp = $vp->v_mntvnodes->tqe_next
4131 end
4132 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
4133 set $vp = $basevp
4134 printf "____________________ New vnodes Queue ---------------\n"
4135 while $vp
4136 print_vnode $vp
4137 set $vp = $vp->v_mntvnodes->tqe_next
4138 end
4139 end
4140 document showmountallvnodes
4141 Syntax: showmountallvnodes <struct mount *>
4142 | Print the vnode inactive list
4143 end
4144
4145
4146 define showmountvnodes
4147 set $mp = (struct mount *)$arg0
4148 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
4149 set $vp = $basevp
4150 printf "____________________ Vnode list Queue ---------------\n"
4151 while $vp
4152 print_vnode $vp
4153 set $vp = $vp->v_mntvnodes->tqe_next
4154 end
4155 end
4156 document showmountvnodes
4157 Syntax: showmountvnodes <struct mount *>
4158 | Print the vnode list
4159 end
4160
4161
4162
4163 define showworkqvnodes
4164 set $mp = (struct mount *)$arg0
4165 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
4166 set $vp = $basevp
4167 printf "____________________ Worker Queue ---------------\n"
4168 while $vp
4169 print_vnode $vp
4170 set $vp = $vp->v_mntvnodes->tqe_next
4171 end
4172 end
4173 document showworkqvnodes
4174 Syntax: showworkqvnodes <struct mount *>
4175 | Print the vnode worker list
4176 end
4177
4178
4179 define shownewvnodes
4180 set $mp = (struct mount *)$arg0
4181 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
4182 set $vp = $basevp
4183 printf "____________________ New vnodes Queue ---------------\n"
4184 while $vp
4185 print_vnode $vp
4186 set $vp = $vp->v_mntvnodes->tqe_next
4187 end
4188 end
4189
4190 document shownewvnodes
4191 Syntax: shownewvnodes <struct mount *>
4192 | Print the new vnode list
4193 end
4194
4195
4196 #
4197 # print mount point info
4198 define print_mount
4199 set $mp = (struct mount *)$arg0
4200 printf " "
4201 printf " mp "
4202 showptr $mp
4203 printf " flag %x", $mp->mnt_flag
4204 printf " kern_flag %x", $mp->mnt_kern_flag
4205 printf " lflag %x", $mp->mnt_lflag
4206 printf " type: %s", $mp->mnt_vfsstat.f_fstypename
4207 printf " mnton: %s", $mp->mnt_vfsstat.f_mntonname
4208 printf " mntfrom: %s", $mp->mnt_vfsstat.f_mntfromname
4209 printf "\n"
4210 end
4211
4212 define showallmounts
4213 set $mp=(struct mount *)mountlist.tqh_first
4214 while $mp
4215 print_mount $mp
4216 set $mp = $mp->mnt_list.tqe_next
4217 end
4218 end
4219
4220 document showallmounts
4221 Syntax: showallmounts
4222 | Print all mount points
4223 end
4224
4225 define pcprint
4226 if (((unsigned long) $arg0 < (unsigned long) &_mh_execute_header || \
4227 (unsigned long) $arg0 >= (unsigned long) &last_kernel_symbol ))
4228 showkmodaddr $arg0
4229 else
4230 output /a $arg0
4231 end
4232 end
4233
4234 define mbuf_walkpkt
4235 set $mp = (struct mbuf *)$arg0
4236 set $cnt = 1
4237 set $tot = 0
4238 while $mp
4239 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
4240 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
4241 if mclaudit != 0
4242 mbuf_buf2mca $mp
4243 printf ", "
4244 end
4245 set $tot = $tot + $mp->m_hdr.mh_len
4246 printf "total %d]\n", $tot
4247 set $mp = $mp->m_hdr.mh_nextpkt
4248 set $cnt = $cnt + 1
4249 end
4250 end
4251
4252 document mbuf_walkpkt
4253 Syntax: (gdb) mbuf_walkpkt <addr>
4254 | Given an mbuf address, walk its m_nextpkt pointer
4255 end
4256
4257 define mbuf_walk
4258 set $mp = (struct mbuf *)$arg0
4259 set $cnt = 1
4260 set $tot = 0
4261 while $mp
4262 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
4263 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
4264 if mclaudit != 0
4265 mbuf_buf2mca $mp
4266 printf ", "
4267 end
4268 set $tot = $tot + $mp->m_hdr.mh_len
4269 printf "total %d]\n", $tot
4270 set $mp = $mp->m_hdr.mh_next
4271 set $cnt = $cnt + 1
4272 end
4273 end
4274
4275 document mbuf_walk
4276 Syntax: (gdb) mbuf_walk <addr>
4277 | Given an mbuf address, walk its m_next pointer
4278 end
4279
4280 define mbuf_buf2slab
4281 set $addr = $arg0
4282 set $gix = ((char *)$addr - (char *)mbutl) >> 20
4283 set $ix = ((char *)$addr - (char *)mbutl) >> 11
4284 set $slab = &slabstbl[$gix].slg_slab[$ix]
4285 printf "%p", $slab
4286 end
4287
4288 document mbuf_buf2slab
4289 | Given an mbuf object, find its corresponding slab address.
4290 end
4291
4292 define mbuf_buf2mca
4293 set $addr = $arg0
4294 set $ix = ((char *)$addr - (char *)mbutl) >> 11
4295 set $clbase = ((union mcluster *)(mbutl + $ix))
4296 set $mclidx = (((char *)$addr - (char *)$clbase) >> 8)
4297 set $mca = mclaudit[$ix].cl_audit[$mclidx]
4298 printf "mca: %p", $mca
4299 end
4300
4301 document mbuf_buf2mca
4302 Syntax: (gdb) mbuf_buf2mca <addr>
4303 | Given an mbuf object, find its buffer audit structure address.
4304 | This requires mbuf buffer auditing to be turned on, by setting
4305 | the appropriate flags to the "mbuf_debug" boot-args parameter.
4306 end
4307
4308 define mbuf_showmca
4309 set language c
4310 set $mca = (mcache_audit_t *)$arg0
4311 set $cp = (mcache_t *)$mca->mca_cache
4312 printf "object type:\t\t"
4313 mbuf_mca_ctype $mca 1
4314 printf "\ncontrolling mcache:\t%p (%s)\n", $mca->mca_cache, $cp->mc_name
4315 if $mca->mca_uflags & $MB_SCVALID
4316 set $ix = ((char *)$mca->mca_addr - (char *)mbutl) >> 11
4317 set $clbase = ((union mcluster *)(mbutl + $ix))
4318 set $mclidx = (((char *)$mca->mca_addr - (char *)$clbase) >> 8)
4319 printf "mbuf obj:\t\t%p\n", $mca->mca_addr
4320 printf "mbuf index:\t\t%d (out of 8) in cluster base %p\n", \
4321 $mclidx + 1, $clbase
4322 if $mca->mca_uptr != 0
4323 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
4324 printf "paired cluster obj:\t%p (mca %p)\n", \
4325 $peer_mca->mca_addr, $peer_mca
4326 end
4327 printf "saved contents:\t\t%p (%d bytes)\n", \
4328 $mca->mca_contents, $mca->mca_contents_size
4329 else
4330 printf "cluster obj:\t\t%p\n", $mca->mca_addr
4331 if $mca->mca_uptr != 0
4332 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
4333 printf "paired mbuf obj:\t%p (mca %p)\n", \
4334 $peer_mca->mca_addr, $peer_mca
4335 end
4336 end
4337 printf "recent transaction for this buffer (thread %p):\n", \
4338 $mca->mca_thread
4339 set $cnt = 0
4340 while $cnt < $mca->mca_depth
4341 set $kgm_pc = $mca->mca_stack[$cnt]
4342 printf "%4d: ", $cnt + 1
4343 pcprint $kgm_pc
4344 printf "\n"
4345 set $cnt = $cnt + 1
4346 end
4347 if $mca->mca_pdepth > 0
4348 printf "previous transaction for this buffer (thread %p):\n", \
4349 $mca->mca_pthread
4350 end
4351 set $cnt = 0
4352 while $cnt < $mca->mca_pdepth
4353 set $kgm_pc = $mca->mca_pstack[$cnt]
4354 printf "%4d: ", $cnt + 1
4355 pcprint $kgm_pc
4356 printf "\n"
4357 set $cnt = $cnt + 1
4358 end
4359 set language auto
4360 end
4361
4362 document mbuf_showmca
4363 Syntax: (gdb) mbuf_showmca <addr>
4364 | Given an mbuf/cluster buffer audit structure address, print the audit
4365 | records including the stack trace of the last buffer transaction.
4366 end
4367
4368 set $MCF_NOCPUCACHE = 0x10
4369
4370 define mcache_stat
4371 set $head = (mcache_t *)mcache_head
4372 set $mc = $head
4373
4374 if $kgm_lp64
4375 printf "cache cache cache buf buf backing (# of retries) bufs\n"
4376 printf "name state addr size align zone wait nowait failed incache\n"
4377 printf "------------------------- -------- ------------------ ------ ----- ------------------ -------------------------- --------\n"
4378 else
4379 printf "cache cache cache buf buf backing (# of retries) bufs\n"
4380 printf "name state addr size align zone wait nowait failed incache\n"
4381 printf "------------------------- -------- ---------- ------ ----- ---------- -------------------------- --------\n"
4382 end
4383 while $mc != 0
4384 set $bktsize = $mc->mc_cpu.cc_bktsize
4385 printf "%-25s ", $mc->mc_name
4386 if ($mc->mc_flags & $MCF_NOCPUCACHE)
4387 printf "disabled"
4388 else
4389 if $mc->mc_purge_cnt > 0
4390 printf " purging"
4391 else
4392 if $bktsize == 0
4393 printf " offline"
4394 else
4395 printf " online"
4396 end
4397 end
4398 end
4399 printf " %p %6d %5d ",$mc, \
4400 $mc->mc_bufsize, $mc->mc_align
4401 if $mc->mc_slab_zone != 0
4402 printf "%p", $mc->mc_slab_zone
4403 else
4404 if $kgm_lp64
4405 printf " custom"
4406 else
4407 printf " custom"
4408 end
4409 end
4410 set $tot = 0
4411 set $tot += $mc->mc_full.bl_total * $bktsize
4412 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
4413 set $n = 0
4414 while $n < ncpu
4415 if $ccp->cc_objs > 0
4416 set $tot += $ccp->cc_objs
4417 end
4418 if $ccp->cc_pobjs > 0
4419 set $tot += $ccp->cc_pobjs
4420 end
4421 set $n += 1
4422 set $ccp += 1
4423 end
4424 printf " %8d %8d %8d %8d", $mc->mc_wretry_cnt, \
4425 $mc->mc_nwretry_cnt, $mc->mc_nwfail_cnt, $tot
4426 printf "\n"
4427 set $mc = (mcache_t *)$mc->mc_list.le_next
4428 end
4429 end
4430
4431 document mcache_stat
4432 Syntax: (gdb) mcache_stat
4433 | Print all mcaches in the system.
4434 end
4435
4436 define mcache_showzone
4437 set $mc = (mcache_t *)$arg0
4438 if $mc->mc_slab_zone != 0
4439 printf "%p", $mc->mc_slab_zone
4440 else
4441 printf " custom"
4442 end
4443
4444 document mcache_showzone
4445 Syntax: (gdb) mcache_showzone <mcache_addr>
4446 | Print the type of backend (custom or zone) of a mcache.
4447 end
4448
4449 define mcache_walkobj
4450 set $p = (mcache_obj_t *)$arg0
4451 set $cnt = 1
4452 set $tot = 0
4453 while $p
4454 printf "%4d: %p\n", $cnt, $p,
4455 set $p = $p->obj_next
4456 set $cnt = $cnt + 1
4457 end
4458 end
4459
4460 document mcache_walkobj
4461 Syntax: (gdb) mcache_walkobj <addr>
4462 | Given a mcache object address, walk its obj_next pointer
4463 end
4464
4465 define mcache_showcache
4466 set $cp = (mcache_t *)$arg0
4467 set $ccp = (mcache_cpu_t *)$cp->mc_cpu
4468 set $bktsize = $cp->mc_cpu.cc_bktsize
4469 set $cnt = 0
4470 set $tot = 0
4471 printf "Showing cache '%s':\n\n", $cp->mc_name
4472 printf " CPU cc_objs cc_pobjs total\n"
4473 printf "---- -------- -------- --------\n"
4474 while $cnt < ncpu
4475 set $objs = $ccp->cc_objs
4476 if $objs <= 0
4477 set $objs = 0
4478 end
4479 set $pobjs = $ccp->cc_pobjs
4480 if $pobjs <= 0
4481 set $pobjs = 0
4482 end
4483 set $tot_cpu = $objs + $pobjs
4484 set $tot += $tot_cpu
4485 printf "%4d %8d %8d %8d\n", $cnt, $objs, $pobjs, $tot_cpu
4486 set $ccp += 1
4487 set $cnt += 1
4488 end
4489 printf " ========\n"
4490 printf " %8d\n", $tot
4491 printf "\n"
4492 set $tot += $cp->mc_full.bl_total * $bktsize
4493 printf "Total # of full buckets (%d objs/bkt):\t%-8d\n", \
4494 $bktsize, $cp->mc_full.bl_total
4495 printf "Total # of objects cached:\t\t%-8d\n", $tot
4496 end
4497
4498 document mcache_showcache
4499 | Display the number of objects in the cache
4500 end
4501
4502 set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
4503
4504 define mbuf_slabstbl
4505 set $x = 0
4506
4507 printf "slot addr slabs range\n"
4508 printf "---- ---------- -----------------------\n"
4509 while $x < maxslabgrp
4510 set $slg = slabstbl[$x]
4511 printf "%3d: ", $x
4512 if $slg == 0
4513 printf "-\n"
4514 else
4515 printf "%p [%p-%p]\n", $slg, &$slg->slg_slab[0], \
4516 &$slg->slg_slab[$NSLABSPMB-1]
4517 end
4518 set $x += 1
4519 end
4520 end
4521
4522 document mbuf_slabstbl
4523 | Display the mbuf slabs table
4524 end
4525
4526 set $SLF_MAPPED=0x0001
4527 set $SLF_PARTIAL=0x0002
4528 set $SLF_DETACHED=0x0004
4529
4530 define mbuf_slabs
4531 set $slg = (mcl_slabg_t *)$arg0
4532 set $x = 0
4533
4534 if $kgm_lp64
4535 printf "slot addr next base C R N size flags\n"
4536 printf "---- ------------------ ------------------ ------------------ -- -- -- ------ -----\n"
4537 else
4538 printf "slot addr next base C R N size flags\n"
4539 printf "---- ---------- ---------- ---------- -- -- -- ------ -----\n"
4540 end
4541 while $x < $NSLABSPMB
4542 set $sl = &$slg->slg_slab[$x]
4543 printf "%3d: %p %p %p %2d %2d %2d %6d 0x%04x ", \
4544 $x + 1, $sl, $sl->sl_next, $sl->sl_base, $sl->sl_class, \
4545 $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
4546 $sl->sl_flags
4547 if $sl->sl_flags != 0
4548 printf "<"
4549 if $sl->sl_flags & $SLF_MAPPED
4550 printf "mapped"
4551 end
4552 if $sl->sl_flags & $SLF_PARTIAL
4553 printf ",partial"
4554 end
4555 if $sl->sl_flags & $SLF_DETACHED
4556 printf ",detached"
4557 end
4558 printf ">"
4559 end
4560 printf "\n"
4561 set $x += 1
4562 end
4563 end
4564
4565 document mbuf_slabs
4566 | Display all mbuf slabs in the group
4567 end
4568
4569 define mbuf_stat
4570 set $x = 0
4571
4572 printf "class total cached uncached inuse failed waiter notified purge\n"
4573 printf "name objs objs objs / slabs objs alloc count count count count\n"
4574 printf "---------------- -------- -------- ------------------- -------- ---------------- -------- -------- --------\n"
4575 while $x < (sizeof(mbuf_table) / sizeof(mbuf_table[0]))
4576 set $mbt = mbuf_table[$x]
4577 set $mcs = (mb_class_stat_t *)mbuf_table[$x].mtbl_stats
4578 set $tot = 0
4579 set $mc = $mbt->mtbl_cache
4580 set $bktsize = $mc->mc_cpu.cc_bktsize
4581 set $tot += $mc->mc_full.bl_total * $bktsize
4582 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
4583 set $n = 0
4584 while $n < ncpu
4585 if $ccp->cc_objs > 0
4586 set $tot += $ccp->cc_objs
4587 end
4588 if $ccp->cc_pobjs > 0
4589 set $tot += $ccp->cc_pobjs
4590 end
4591 set $n += 1
4592 set $ccp += 1
4593 end
4594
4595 printf "%-16s %8d %8d %8d / %-8d %8d %16llu %8d %8llu %8llu", \
4596 $mcs->mbcl_cname, $mcs->mbcl_total, $tot, \
4597 $mcs->mbcl_infree, $mcs->mbcl_slab_cnt, \
4598 ($mcs->mbcl_total - $tot - $mcs->mbcl_infree), \
4599 $mcs->mbcl_fail_cnt, $mc->mc_waiter_cnt, \
4600 $mcs->mbcl_notified, $mcs->mbcl_purge_cnt
4601 printf "\n"
4602 set $x += 1
4603 end
4604 end
4605
4606 document mbuf_stat
4607 | Print extended mbuf allocator statistics.
4608 end
4609
4610 set $MB_INUSE = 0x1
4611 set $MB_COMP_INUSE = 0x2
4612 set $MB_SCVALID = 0x4
4613
4614 set $MCLBYTES = 2048
4615 set $MSIZE = 256
4616 set $NBPG = 4096
4617 set $M16KCLBYTES = 16384
4618
4619 define mbuf_mca_ctype
4620 set $mca = (mcache_audit_t *)$arg0
4621 set $vopt = $arg1
4622 set $cp = $mca->mca_cache
4623 set $class = (unsigned int)$cp->mc_private
4624 set $csize = mbuf_table[$class].mtbl_stats->mbcl_size
4625 set $done = 0
4626 if $csize == $MSIZE
4627 if $vopt
4628 printf "M (mbuf) "
4629 else
4630 printf "M "
4631 end
4632 set $done = 1
4633 end
4634 if !$done && $csize == $MCLBYTES
4635 if $vopt
4636 printf "CL (2K cluster) "
4637 else
4638 printf "CL "
4639 end
4640 set $done = 1
4641 end
4642 if !$done && $csize == $NBPG
4643 if $vopt
4644 printf "BCL (4K cluster) "
4645 else
4646 printf "BCL "
4647 end
4648 set $done = 1
4649 end
4650 if !$done && $csize == $M16KCLBYTES
4651 if $vopt
4652 printf "JCL (16K cluster) "
4653 else
4654 printf "JCL "
4655 end
4656 set $done = 1
4657 end
4658 if !$done && $csize == ($MSIZE+$MCLBYTES)
4659 if $mca->mca_uflags & $MB_SCVALID
4660 if $mca->mca_uptr
4661 printf "M+CL "
4662 if $vopt
4663 printf "(paired mbuf, 2K cluster)"
4664 end
4665 else
4666 printf "M-CL "
4667 if $vopt
4668 printf "(unpaired mbuf, 2K cluster) "
4669 end
4670 end
4671 else
4672 if $mca->mca_uptr
4673 printf "CL+M "
4674 if $vopt
4675 printf "(paired 2K cluster, mbuf) "
4676 end
4677 else
4678 printf "CL-M "
4679 if $vopt
4680 printf "(paired 2K cluster, mbuf) "
4681 end
4682 end
4683 end
4684 set $done = 1
4685 end
4686 if !$done && $csize == ($MSIZE+$NBPG)
4687 if $mca->mca_uflags & $MB_SCVALID
4688 if $mca->mca_uptr
4689 printf "M+BCL "
4690 if $vopt
4691 printf "(paired mbuf, 4K cluster) "
4692 end
4693 else
4694 printf "M-BCL "
4695 if $vopt
4696 printf "(unpaired mbuf, 4K cluster) "
4697 end
4698 end
4699 else
4700 if $mca->mca_uptr
4701 printf "BCL+M "
4702 if $vopt
4703 printf "(paired 4K cluster, mbuf) "
4704 end
4705 else
4706 printf "BCL-M "
4707 if $vopt
4708 printf "(unpaired 4K cluster, mbuf) "
4709 end
4710 end
4711 end
4712 set $done = 1
4713 end
4714 if !$done && $csize == ($MSIZE+$M16KCLBYTES)
4715 if $mca->mca_uflags & $MB_SCVALID
4716 if $mca->mca_uptr
4717 printf "M+JCL "
4718 if $vopt
4719 printf "(paired mbuf, 16K cluster) "
4720 end
4721 else
4722 printf "M-JCL "
4723 if $vopt
4724 printf "(unpaired mbuf, 16K cluster) "
4725 end
4726 end
4727 else
4728 if $mca->mca_uptr
4729 printf "JCL+M "
4730 if $vopt
4731 printf "(paired 16K cluster, mbuf) "
4732 end
4733 else
4734 printf "JCL-M "
4735 if $vopt
4736 printf "(unpaired 16K cluster, mbuf) "
4737 end
4738 end
4739 end
4740 set $done = 1
4741 end
4742 if !$done
4743 printf "unknown: %s ", $cp->mc_name
4744 end
4745 end
4746
4747 document mbuf_mca_ctype
4748 | This is a helper macro for mbuf_show{active,inactive,all} that prints
4749 | out the mbuf object type represented by a given mcache audit structure.
4750 end
4751
4752 define mbuf_showactive
4753 if $argc == 0
4754 mbuf_walkallslabs 1 0
4755 else
4756 mbuf_walkallslabs 1 0 $arg0
4757 end
4758 end
4759
4760 document mbuf_showactive
4761 Syntax: (gdb) mbuf_showactive
4762 | Walk the mbuf objects pool and print only the active ones; this
4763 | requires mbuf debugging to be turned on, by setting the appropriate flags
4764 | to the "mbuf_debug" boot-args parameter. Active objects are those that
4765 | are outstanding (have not returned to the mbuf slab layer) and in use
4766 | by the client (have not been freed).
4767 end
4768
4769 define mbuf_showinactive
4770 mbuf_walkallslabs 0 1
4771 end
4772
4773 document mbuf_showinactive
4774 Syntax: (gdb) mbuf_showinactive
4775 | Walk the mbuf objects pool and print only the inactive ones; this
4776 | requires mbuf debugging to be turned on, by setting the appropriate flags
4777 | to the "mbuf_debug" boot-args parameter. Inactive objects are those that
4778 | are outstanding (have not returned to the mbuf slab layer) but have been
4779 | freed by the client, i.e. they still reside in the mcache layer ready to
4780 | be used for subsequent allocation requests.
4781 end
4782
4783 define mbuf_showall
4784 mbuf_walkallslabs 1 1
4785 end
4786
4787 document mbuf_showall
4788 Syntax: (gdb) mbuf_showall
4789 | Walk the mbuf objects pool and print them all; this requires
4790 | mbuf debugging to be turned on, by setting the appropriate flags to the
4791 | "mbuf_debug" boot-args parameter.
4792 end
4793
4794 define mbuf_mcaobjs
4795 end
4796
4797 define mbuf_walkallslabs
4798 set $show_a = $arg0
4799 set $show_f = $arg1
4800 if $argc == 3
4801 set $show_tr = $arg2
4802 else
4803 set $show_tr = 0
4804 end
4805 set $x = 0
4806 set $total = 0
4807 set $total_a = 0
4808 set $total_f = 0
4809
4810 printf "("
4811 if $show_a && !$show_f
4812 printf "Searching only for active "
4813 end
4814 if !$show_a && $show_f
4815 printf "Searching only for inactive "
4816 end
4817 if $show_a && $show_f
4818 printf "Displaying all "
4819 end
4820 printf "objects; this may take a while ...)\n\n"
4821
4822 if $kgm_lp64
4823 printf " slab mca obj allocation\n"
4824 printf "slot idx address address address type state\n"
4825 printf "---- ---- ------------------ ------------------ ------------------ ----- -----------\n"
4826 else
4827 printf " slab mca obj allocation\n"
4828 printf "slot idx address address address type state\n"
4829 printf "---- ---- ---------- ---------- ---------- ----- -----------\n"
4830 end
4831
4832 while $x < slabgrp
4833 set $slg = slabstbl[$x]
4834 set $y = 0
4835 set $stop = 0
4836 while $y < $NSLABSPMB && $stop == 0
4837 set $sl = &$slg->slg_slab[$y]
4838 set $base = (char *)$sl->sl_base
4839 set $ix = ($base - (char *)mbutl) >> 11
4840 set $clbase = ((union mcluster *)(mbutl + $ix))
4841 set $mclidx = ($base - (char *)$clbase) >> 8
4842 set $mca = mclaudit[$ix].cl_audit[$mclidx]
4843 set $first = 1
4844
4845 while $mca != 0 && $mca->mca_addr != 0
4846 set $printmca = 0
4847 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
4848 set $total_a = $total_a + 1
4849 set $printmca = $show_a
4850 else
4851 set $total_f = $total_f + 1
4852 set $printmca = $show_f
4853 end
4854
4855 if $printmca != 0
4856 if $first == 1
4857 printf "%4d %4d %p ", $x, $y, $sl
4858 else
4859 if $kgm_lp64
4860 printf " "
4861 else
4862 printf " "
4863 end
4864 end
4865
4866 printf "%p %p ", $mca, $mca->mca_addr
4867 mbuf_mca_ctype $mca 0
4868 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
4869 printf "active "
4870 else
4871 printf " freed "
4872 end
4873 if $first == 1
4874 set $first = 0
4875 end
4876 printf "\n"
4877 set $total = $total + 1
4878
4879 if $show_tr != 0
4880 printf "recent transaction for this buffer (thread %p):\n", \
4881 $mca->mca_thread
4882 set $cnt = 0
4883 while $cnt < $mca->mca_depth
4884 set $kgm_pc = $mca->mca_stack[$cnt]
4885 printf "%4d: ", $cnt + 1
4886 pcprint $kgm_pc
4887 printf "\n"
4888 set $cnt = $cnt + 1
4889 end
4890 end
4891 end
4892
4893 set $mca = $mca->mca_next
4894 end
4895 set $y += 1
4896 if $slg->slg_slab[$y].sl_base == 0
4897 set $stop = 1
4898 end
4899 end
4900 set $x += 1
4901 end
4902 if $total && $show_a && $show_f
4903 printf "\ntotal objects:\t%d\n", $total
4904 printf "active/unfreed:\t%d\n", $total_a
4905 printf "freed/in_cache:\t%d\n", $total_f
4906 end
4907 end
4908
4909 document mbuf_walkallslabs
4910 | Walk the mbuf objects pool; this requires mbuf debugging to be
4911 | turned on, by setting the appropriate flags to the "mbuf_debug" boot-args
4912 | parameter. This is a backend routine for mbuf_show{active,inactive,all}.
4913 end
4914
4915 set $RTF_UP = 0x1
4916 set $RTF_GATEWAY = 0x2
4917 set $RTF_HOST = 0x4
4918 set $RTF_REJECT = 0x8
4919 set $RTF_DYNAMIC = 0x10
4920 set $RTF_MODIFIED = 0x20
4921 set $RTF_DONE = 0x40
4922 set $RTF_DELCLONE = 0x80
4923 set $RTF_CLONING = 0x100
4924 set $RTF_XRESOLVE = 0x200
4925 set $RTF_LLINFO = 0x400
4926 set $RTF_STATIC = 0x800
4927 set $RTF_BLACKHOLE = 0x1000
4928 set $RTF_PROTO2 = 0x4000
4929 set $RTF_PROTO1 = 0x8000
4930 set $RTF_PRCLONING = 0x10000
4931 set $RTF_WASCLONED = 0x20000
4932 set $RTF_PROTO3 = 0x40000
4933 set $RTF_PINNED = 0x100000
4934 set $RTF_LOCAL = 0x200000
4935 set $RTF_BROADCAST = 0x400000
4936 set $RTF_MULTICAST = 0x800000
4937 set $RTF_IFSCOPE = 0x1000000
4938 set $RTF_CONDEMNED = 0x2000000
4939
4940 set $AF_INET = 2
4941 set $AF_INET6 = 30
4942 set $AF_LINK = 18
4943
4944 define rtentry_prdetails
4945 set $rt = (struct rtentry *)$arg0
4946 set $is_v6 = 0
4947
4948 set $dst = (struct sockaddr *)$rt->rt_nodes->rn_u.rn_leaf.rn_Key
4949 if $dst->sa_family == $AF_INET
4950 showsockaddr_in $dst
4951 printf " "
4952 else
4953 if $dst->sa_family == $AF_INET6
4954 showsockaddr_in6 $dst
4955 printf " "
4956 set $is_v6 = 1
4957 else
4958 if $dst->sa_family == $AF_LINK
4959 showsockaddr_dl $dst
4960 printf " "
4961 else
4962 showsockaddr_unspec $dst
4963 end
4964 end
4965 end
4966
4967 set $dst = (struct sockaddr *)$rt->rt_gateway
4968 if $dst->sa_family == $AF_INET
4969 showsockaddr_in $dst
4970 printf " "
4971 else
4972 if $dst->sa_family == $AF_INET6
4973 set $is_v6 = 1
4974 showsockaddr_in6 $dst
4975 printf " "
4976 else
4977 if $dst->sa_family == $AF_LINK
4978 showsockaddr_dl $dst
4979 if $is_v6
4980 printf " "
4981 else
4982 printf " "
4983 end
4984 else
4985 showsockaddr_unspec $dst
4986 end
4987 end
4988 end
4989
4990 if $rt->rt_flags & $RTF_WASCLONED
4991 if $kgm_lp64
4992 printf "%18p ", $rt->rt_parent
4993 else
4994 printf "%10p ", $rt->rt_parent
4995 end
4996 else
4997 if $kgm_lp64
4998 printf " "
4999 else
5000 printf " "
5001 end
5002 end
5003
5004 printf "%6u %8u ", $rt->rt_refcnt, $rt->rt_rmx.rmx_pksent
5005
5006 if $rt->rt_flags & $RTF_UP
5007 printf "U"
5008 end
5009 if $rt->rt_flags & $RTF_GATEWAY
5010 printf "G"
5011 end
5012 if $rt->rt_flags & $RTF_HOST
5013 printf "H"
5014 end
5015 if $rt->rt_flags & $RTF_REJECT
5016 printf "R"
5017 end
5018 if $rt->rt_flags & $RTF_DYNAMIC
5019 printf "D"
5020 end
5021 if $rt->rt_flags & $RTF_MODIFIED
5022 printf "M"
5023 end
5024 if $rt->rt_flags & $RTF_CLONING
5025 printf "C"
5026 end
5027 if $rt->rt_flags & $RTF_PRCLONING
5028 printf "c"
5029 end
5030 if $rt->rt_flags & $RTF_LLINFO
5031 printf "L"
5032 end
5033 if $rt->rt_flags & $RTF_STATIC
5034 printf "S"
5035 end
5036 if $rt->rt_flags & $RTF_PROTO1
5037 printf "1"
5038 end
5039 if $rt->rt_flags & $RTF_PROTO2
5040 printf "2"
5041 end
5042 if $rt->rt_flags & $RTF_PROTO3
5043 printf "3"
5044 end
5045 if $rt->rt_flags & $RTF_WASCLONED
5046 printf "W"
5047 end
5048 if $rt->rt_flags & $RTF_BROADCAST
5049 printf "b"
5050 end
5051 if $rt->rt_flags & $RTF_MULTICAST
5052 printf "m"
5053 end
5054 if $rt->rt_flags & $RTF_XRESOLVE
5055 printf "X"
5056 end
5057 if $rt->rt_flags & $RTF_BLACKHOLE
5058 printf "B"
5059 end
5060 if $rt->rt_flags & $RTF_IFSCOPE
5061 printf "I"
5062 end
5063
5064 printf "/%s%d", $rt->rt_ifp->if_name, $rt->rt_ifp->if_unit
5065 end
5066
5067 set $RNF_ROOT = 2
5068
5069 define _rttable_dump
5070 set $rnh = $arg0
5071 set $rn = (struct radix_node *)$rnh->rnh_treetop
5072 set $rnh_cnt = $rnh->rnh_cnt
5073
5074 while $rn->rn_bit >= 0
5075 set $rn = $rn->rn_u.rn_node.rn_L
5076 end
5077
5078 while 1
5079 set $base = (struct radix_node *)$rn
5080 while ($rn->rn_parent->rn_u.rn_node.rn_R == $rn) && ($rn->rn_flags & $RNF_ROOT) == 0
5081 set $rn = $rn->rn_parent
5082 end
5083 set $rn = $rn->rn_parent->rn_u.rn_node.rn_R
5084 while $rn->rn_bit >= 0
5085 set $rn = $rn->rn_u.rn_node.rn_L
5086 end
5087 set $next = $rn
5088 while $base != 0
5089 set $rn = $base
5090 set $base = $rn->rn_u.rn_leaf.rn_Dupedkey
5091 if ($rn->rn_flags & $RNF_ROOT) == 0
5092
5093 set $rt = (struct rtentry *)$rn
5094
5095 if $kgm_lp64
5096 printf "%18p ", $rt
5097 else
5098 printf "%10p ", $rt
5099 end
5100 rtentry_prdetails $rt
5101 printf "\n"
5102
5103 end
5104 end
5105 set $rn = $next
5106 if ($rn->rn_flags & $RNF_ROOT) != 0
5107 loop_break
5108 end
5109 end
5110 end
5111
5112
5113 define show_rt_inet
5114 if $kgm_lp64
5115 printf " rtentry dst gw parent Refs Use flags/if\n"
5116 printf " ----------------- --------------- ----------------- ------------------ ------ -------- -----------\n"
5117 else
5118 printf " rtentry dst gw parent Refs Use flags/if\n"
5119 printf " --------- --------------- ----------------- ---------- ------ -------- -----------\n"
5120 end
5121 _rttable_dump rt_tables[2]
5122 end
5123
5124 document show_rt_inet
5125 Syntax: (gdb) show_rt_inet
5126 | Show the entries of the IPv4 routing table.
5127 end
5128
5129 define show_rt_inet6
5130 if $kgm_lp64
5131 printf " rtentry dst gw parent Refs Use flags/if\n"
5132 printf " ----------------- --------------------------------------- --------------------------------------- ------------------ ------ -------- -----------\n"
5133 else
5134 printf " rtentry dst gw parent Refs Use flags/if\n"
5135 printf " --------- --------------------------------------- --------------------------------------- ---------- ------ -------- -----------\n"
5136 end
5137 _rttable_dump rt_tables[30]
5138 end
5139
5140 document show_rt_inet6
5141 Syntax: (gdb) show_rt_inet6
5142 | Show the entries of the IPv6 routing table.
5143 end
5144
5145 define rtentry_trash
5146 set $rtd = (struct rtentry_dbg *)rttrash_head.tqh_first
5147 set $cnt = 0
5148 while $rtd != 0
5149 if $cnt == 0
5150 if $kgm_lp64
5151 printf " rtentry ref hold rele dst gw parent flags/if\n"
5152 printf " ----------------- --- ------ ------ --------------- ----- ------------------ -----------\n"
5153 else
5154 printf " rtentry ref hold rele dst gw parent flags/if\n"
5155 printf " --------- --- ------ ------ --------------- ----- ---------- -----------\n"
5156 end
5157 end
5158 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $rtd, \
5159 $rtd->rtd_refhold_cnt - $rtd->rtd_refrele_cnt, \
5160 $rtd->rtd_refhold_cnt, $rtd->rtd_refrele_cnt
5161 rtentry_prdetails $rtd
5162 printf "\n"
5163 set $rtd = $rtd->rtd_trash_link.tqe_next
5164 set $cnt = $cnt + 1
5165 end
5166 end
5167
5168 document rtentry_trash
5169 Syntax: (gdb) rtentry_trash
5170 | Walk the list of trash route entries; this requires route entry
5171 | debugging to be turned on, by setting the appropriate flags to the
5172 | "rte_debug" boot-args parameter.
5173 end
5174
5175 set $CTRACE_STACK_SIZE = ctrace_stack_size
5176 set $CTRACE_HIST_SIZE = ctrace_hist_size
5177
5178 define rtentry_showdbg
5179 set $rtd = (struct rtentry_dbg *)$arg0
5180 set $cnt = 0
5181
5182 printf "Total holds:\t%d\n", $rtd->rtd_refhold_cnt
5183 printf "Total releases:\t%d\n", $rtd->rtd_refrele_cnt
5184
5185 set $ix = 0
5186 while $ix < $CTRACE_STACK_SIZE
5187 set $kgm_pc = $rtd->rtd_alloc.pc[$ix]
5188 if $kgm_pc != 0
5189 if $ix == 0
5190 printf "\nAlloc (thread %p):\n", \
5191 $rtd->rtd_alloc.th
5192 end
5193 printf "%4d: ", $ix + 1
5194 pcprint $kgm_pc
5195 printf "\n"
5196 end
5197 set $ix = $ix + 1
5198 end
5199 set $ix = 0
5200 while $ix < $CTRACE_STACK_SIZE
5201 set $kgm_pc = $rtd->rtd_free.pc[$ix]
5202 if $kgm_pc != 0
5203 if $ix == 0
5204 printf "\nFree: (thread %p)\n", \
5205 $rtd->rtd_free.th
5206 end
5207 printf "%4d: ", $ix + 1
5208 pcprint $kgm_pc
5209 printf "\n"
5210 end
5211 set $ix = $ix + 1
5212 end
5213 while $cnt < $CTRACE_HIST_SIZE
5214 set $ix = 0
5215 while $ix < $CTRACE_STACK_SIZE
5216 set $kgm_pc = $rtd->rtd_refhold[$cnt].pc[$ix]
5217 if $kgm_pc != 0
5218 if $ix == 0
5219 printf "\nHold [%d] (thread %p):\n", \
5220 $cnt, $rtd->rtd_refhold[$cnt].th
5221 end
5222 printf "%4d: ", $ix + 1
5223 pcprint $kgm_pc
5224 printf "\n"
5225 end
5226 set $ix = $ix + 1
5227 end
5228 set $cnt = $cnt + 1
5229 end
5230 set $cnt = 0
5231 while $cnt < $CTRACE_HIST_SIZE
5232 set $ix = 0
5233 while $ix < $CTRACE_STACK_SIZE
5234 set $kgm_pc = $rtd->rtd_refrele[$cnt].pc[$ix]
5235 if $kgm_pc != 0
5236 if $ix == 0
5237 printf "\nRelease [%d] (thread %p):\n",\
5238 $cnt, $rtd->rtd_refrele[$cnt].th
5239 end
5240 printf "%4d: ", $ix + 1
5241 pcprint $kgm_pc
5242 printf "\n"
5243 end
5244 set $ix = $ix + 1
5245 end
5246 set $cnt = $cnt + 1
5247 end
5248
5249 printf "\nTotal locks:\t%d\n", $rtd->rtd_lock_cnt
5250 printf "Total unlocks:\t%d\n", $rtd->rtd_unlock_cnt
5251
5252 set $cnt = 0
5253 while $cnt < $CTRACE_HIST_SIZE
5254 set $ix = 0
5255 while $ix < $CTRACE_STACK_SIZE
5256 set $kgm_pc = $rtd->rtd_lock[$cnt].pc[$ix]
5257 if $kgm_pc != 0
5258 if $ix == 0
5259 printf "\nLock [%d] (thread %p):\n",\
5260 $cnt, $rtd->rtd_lock[$cnt].th
5261 end
5262 printf "%4d: ", $ix + 1
5263 pcprint $kgm_pc
5264 printf "\n"
5265 end
5266 set $ix = $ix + 1
5267 end
5268 set $cnt = $cnt + 1
5269 end
5270 set $cnt = 0
5271 while $cnt < $CTRACE_HIST_SIZE
5272 set $ix = 0
5273 while $ix < $CTRACE_STACK_SIZE
5274 set $kgm_pc = $rtd->rtd_unlock[$cnt].pc[$ix]
5275 if $kgm_pc != 0
5276 if $ix == 0
5277 printf "\nUnlock [%d] (thread %p):\n",\
5278 $cnt, $rtd->rtd_unlock[$cnt].th
5279 end
5280 printf "%4d: ", $ix + 1
5281 pcprint $kgm_pc
5282 printf "\n"
5283 end
5284 set $ix = $ix + 1
5285 end
5286 set $cnt = $cnt + 1
5287 end
5288 end
5289
5290 document rtentry_showdbg
5291 Syntax: (gdb) rtentry_showdbg <addr>
5292 | Given a route entry structure address, print the debug information
5293 | related to it. This requires route entry debugging to be turned
5294 | on, by setting the appropriate flags to the "rte_debug" boot-args
5295 | parameter.
5296 end
5297
5298 define inifa_showdbg
5299 set $inifa = (struct in_ifaddr_dbg *)$arg0
5300 set $cnt = 0
5301
5302 printf "Total holds:\t%d\n", $inifa->inifa_refhold_cnt
5303 printf "Total releases:\t%d\n", $inifa->inifa_refrele_cnt
5304
5305 set $ix = 0
5306 while $ix < $CTRACE_STACK_SIZE
5307 set $kgm_pc = $inifa->inifa_alloc.pc[$ix]
5308 if $kgm_pc != 0
5309 if $ix == 0
5310 printf "\nAlloc (thread %p):\n", \
5311 $inifa->inifa_alloc.th
5312 end
5313 printf "%4d: ", $ix + 1
5314 pcprint $kgm_pc
5315 printf "\n"
5316 end
5317 set $ix = $ix + 1
5318 end
5319 set $ix = 0
5320 while $ix < $CTRACE_STACK_SIZE
5321 set $kgm_pc = $inifa->inifa_free.pc[$ix]
5322 if $kgm_pc != 0
5323 if $ix == 0
5324 printf "\nFree: (thread %p)\n", \
5325 $inifa->inifa_free.th
5326 end
5327 printf "%4d: ", $ix + 1
5328 pcprint $kgm_pc
5329 printf "\n"
5330 end
5331 set $ix = $ix + 1
5332 end
5333 while $cnt < $CTRACE_HIST_SIZE
5334 set $ix = 0
5335 while $ix < $CTRACE_STACK_SIZE
5336 set $kgm_pc = $inifa->inifa_refhold[$cnt].pc[$ix]
5337 if $kgm_pc != 0
5338 if $ix == 0
5339 printf "\nHold [%d] (thread %p):\n", \
5340 $cnt, $inifa->inifa_refhold[$cnt].th
5341 end
5342 printf "%4d: ", $ix + 1
5343 pcprint $kgm_pc
5344 printf "\n"
5345 end
5346 set $ix = $ix + 1
5347 end
5348 set $cnt = $cnt + 1
5349 end
5350 set $cnt = 0
5351 while $cnt < $CTRACE_HIST_SIZE
5352 set $ix = 0
5353 while $ix < $CTRACE_STACK_SIZE
5354 set $kgm_pc = $inifa->inifa_refrele[$cnt].pc[$ix]
5355 if $kgm_pc != 0
5356 if $ix == 0
5357 printf "\nRelease [%d] (thread %p):\n",\
5358 $cnt, $inifa->inifa_refrele[$cnt].th
5359 end
5360 printf "%4d: ", $ix + 1
5361 pcprint $kgm_pc
5362 printf "\n"
5363 end
5364 set $ix = $ix + 1
5365 end
5366 set $cnt = $cnt + 1
5367 end
5368 end
5369
5370 document inifa_showdbg
5371 Syntax: (gdb) inifa_showdbg <addr>
5372 | Given an IPv4 interface structure address, print the debug information
5373 | related to it. This requires interface address debugging to be turned
5374 | on, by setting the appropriate flags to the "ifa_debug" boot-args
5375 | parameter.
5376 end
5377
5378 define in6ifa_showdbg
5379 set $in6ifa = (struct in6_ifaddr_dbg *)$arg0
5380 set $cnt = 0
5381
5382 printf "Total holds:\t%d\n", $in6ifa->in6ifa_refhold_cnt
5383 printf "Total releases:\t%d\n", $in6ifa->in6ifa_refrele_cnt
5384
5385 set $ix = 0
5386 while $ix < $CTRACE_STACK_SIZE
5387 set $kgm_pc = $in6ifa->in6ifa_alloc.pc[$ix]
5388 if $kgm_pc != 0
5389 if $ix == 0
5390 printf "\nAlloc (thread %p):\n", \
5391 $in6ifa->in6ifa_alloc.th
5392 end
5393 printf "%4d: ", $ix + 1
5394 pcprint $kgm_pc
5395 printf "\n"
5396 end
5397 set $ix = $ix + 1
5398 end
5399 set $ix = 0
5400 while $ix < $CTRACE_STACK_SIZE
5401 set $kgm_pc = $in6ifa->in6ifa_free.pc[$ix]
5402 if $kgm_pc != 0
5403 if $ix == 0
5404 printf "\nFree: (thread %p)\n", \
5405 $in6ifa->in6ifa_free.th
5406 end
5407 printf "%4d: ", $ix + 1
5408 pcprint $kgm_pc
5409 printf "\n"
5410 end
5411 set $ix = $ix + 1
5412 end
5413 while $cnt < $CTRACE_HIST_SIZE
5414 set $ix = 0
5415 while $ix < $CTRACE_STACK_SIZE
5416 set $kgm_pc = $in6ifa->in6ifa_refhold[$cnt].pc[$ix]
5417 if $kgm_pc != 0
5418 if $ix == 0
5419 printf "\nHold [%d] (thread %p):\n", \
5420 $cnt, $in6ifa->in6ifa_refhold[$cnt].th
5421 end
5422 printf "%4d: ", $ix + 1
5423 pcprint $kgm_pc
5424 printf "\n"
5425 end
5426 set $ix = $ix + 1
5427 end
5428 set $cnt = $cnt + 1
5429 end
5430 set $cnt = 0
5431 while $cnt < $CTRACE_HIST_SIZE
5432 set $ix = 0
5433 while $ix < $CTRACE_STACK_SIZE
5434 set $kgm_pc = $in6ifa->in6ifa_refrele[$cnt].pc[$ix]
5435 if $kgm_pc != 0
5436 if $ix == 0
5437 printf "\nRelease [%d] (thread %p):\n",\
5438 $cnt, $in6ifa->in6ifa_refrele[$cnt].th
5439 end
5440 printf "%4d: ", $ix + 1
5441 pcprint $kgm_pc
5442 printf "\n"
5443 end
5444 set $ix = $ix + 1
5445 end
5446 set $cnt = $cnt + 1
5447 end
5448 end
5449
5450 document in6ifa_showdbg
5451 Syntax: (gdb) in6ifa_showdbg <addr>
5452 | Given an IPv6 interface structure address, print the debug information
5453 | related to it. This requires interface address debugging to be turned
5454 | on, by setting the appropriate flags to the "ifa_debug" boot-args
5455 | parameter.
5456 end
5457
5458 #
5459 # print all OSMalloc stats
5460
5461 define ostag_print
5462 set $kgm_tagp = (OSMallocTag)$arg0
5463 printf "0x%08x: ", $kgm_tagp
5464 printf "%8d ",$kgm_tagp->OSMT_refcnt
5465 printf "%8x ",$kgm_tagp->OSMT_state
5466 printf "%8x ",$kgm_tagp->OSMT_attr
5467 printf "%s ",$kgm_tagp->OSMT_name
5468 printf "\n"
5469 end
5470
5471
5472 define showosmalloc
5473 printf "TAG COUNT STATE ATTR NAME\n"
5474 set $kgm_tagheadp = (OSMallocTag)&OSMalloc_tag_list
5475 set $kgm_tagptr = (OSMallocTag )($kgm_tagheadp->OSMT_link.next)
5476 while $kgm_tagptr != $kgm_tagheadp
5477 ostag_print $kgm_tagptr
5478 set $kgm_tagptr = (OSMallocTag)$kgm_tagptr->OSMT_link.next
5479 end
5480 printf "\n"
5481 end
5482 document showosmalloc
5483 Syntax: (gdb) showosmalloc
5484 | Print the outstanding allocation count by OSMallocTags.
5485 end
5486
5487
5488 define systemlog
5489 if msgbufp->msg_bufc[msgbufp->msg_bufx] == 0
5490 # The buffer hasn't wrapped, so take the easy (and fast!) path
5491 printf "%s", msgbufp->msg_bufc
5492 else
5493 set $kgm_msgbuf = *msgbufp
5494 set $kgm_syslog_bufsize = $kgm_msgbuf.msg_size
5495 set $kgm_syslog_bufend = $kgm_msgbuf.msg_bufx
5496 if $kgm_syslog_bufend >= $kgm_syslog_bufsize
5497 set $kgm_syslog_bufend = 0
5498 end
5499
5500 # print older messages from msg_bufx to end of buffer
5501 set $kgm_i = $kgm_syslog_bufend
5502 while $kgm_i < $kgm_syslog_bufsize
5503 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
5504 if $kgm_syslog_char == 0
5505 # break out of loop
5506 set $kgm_i = $kgm_syslog_bufsize
5507 else
5508 printf "%c", $kgm_syslog_char
5509 end
5510 set $kgm_i = $kgm_i + 1
5511 end
5512
5513 # print newer messages from start of buffer to msg_bufx
5514 set $kgm_i = 0
5515 while $kgm_i < $kgm_syslog_bufend
5516 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
5517 printf "%c", $kgm_syslog_char
5518 set $kgm_i = $kgm_i + 1
5519 end
5520 end
5521 printf "\n"
5522 end
5523 document systemlog
5524 | Syntax: systemlog
5525 | Display the kernel's printf ring buffer
5526 end
5527
5528
5529 define hexdump
5530 set $kgm_addr = (unsigned char *)$arg0
5531 set $kgm_len = $arg1
5532 while $kgm_len > 0
5533 showptr $kgm_addr
5534 printf ": "
5535 set $kgm_i = 0
5536 while $kgm_i < 16
5537 printf "%02x ", *($kgm_addr+$kgm_i)
5538 set $kgm_i += 1
5539 end
5540 printf " |"
5541 set $kgm_i = 0
5542 while $kgm_i < 16
5543 set $kgm_temp = *($kgm_addr+$kgm_i)
5544 if $kgm_temp < 32 || $kgm_temp >= 127
5545 printf "."
5546 else
5547 printf "%c", $kgm_temp
5548 end
5549 set $kgm_i += 1
5550 end
5551 printf "|\n"
5552 set $kgm_addr += 16
5553 set $kgm_len -= 16
5554 end
5555 end
5556 document hexdump
5557 | Show the contents of memory as a hex/ASCII dump
5558 | The following is the syntax:
5559 | (gdb) hexdump <address> <length>
5560 end
5561
5562
5563 define printcolonhex
5564 if ($argc == 2)
5565 set $addr = $arg0
5566 set $count = $arg1
5567 set $li = 0
5568 while ($li < $count)
5569 if ($li == 0)
5570 printf "%02x", (u_char)$addr[$li]
5571 end
5572 if ($li != 0)
5573 printf ":%02x", (u_char)$addr[$li]
5574 end
5575 set $li = $li + 1
5576 end
5577 end
5578 end
5579
5580 define showsockaddr_dl
5581 set $sdl = (struct sockaddr_dl *)$arg0
5582 if ($sdl == 0)
5583 printf "(null) "
5584 else
5585 if $sdl->sdl_nlen == 0 && $sdl->sdl_alen == 0 && $sdl->sdl_slen == 0
5586 printf "link#%3d ", $sdl->sdl_index
5587 else
5588 set $addr = $sdl->sdl_data + $sdl->sdl_nlen
5589 set $count = $sdl->sdl_alen
5590 printcolonhex $addr $count
5591 end
5592 end
5593 end
5594
5595 define showsockaddr_unspec
5596 set $sockaddr = (struct sockaddr *)$arg0
5597 set $addr = $sockaddr->sa_data
5598 set $count = $sockaddr->sa_len - 2
5599 printcolonhex $addr $count
5600 end
5601
5602 define showsockaddr_at
5603 set $sockaddr = (struct sockaddr *)$arg0
5604 set $addr = $sockaddr->sa_data
5605 set $count = $sockaddr->sa_len - 2
5606 printcolonhex $addr $count
5607 end
5608
5609 define showsockaddr_in
5610 set $sin = (struct sockaddr_in *)$arg0
5611 set $sa_bytes = (unsigned char *)&($sin->sin_addr)
5612 printf "%3u.%03u.%03u.%03u", $sa_bytes[0], $sa_bytes[1], $sa_bytes[2], $sa_bytes[3]
5613 end
5614
5615 define showsockaddr_in6
5616 set $sin6 = (struct sockaddr_in6 *)$arg0
5617 set $sa_bytes = $sin6->sin6_addr.__u6_addr.__u6_addr8
5618 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
5619 $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]
5620 end
5621
5622 define showsockaddr_un
5623 set $sun = (struct sockaddr_un *)$arg0
5624 if $sun == 0
5625 printf "(null)"
5626 else
5627 if $sun->sun_path[0] == 0
5628 printf "\"\""
5629 else
5630 printf "%s", $sun->sun_path
5631 end
5632 end
5633 end
5634
5635 define showifmultiaddrs
5636 set $ifp = (struct ifnet *)$arg0
5637 set $if_multi = (struct ifmultiaddr *)$ifp->if_multiaddrs->lh_first
5638 set $mymulti = $if_multi
5639 set $myi = 0
5640 while ($mymulti != 0)
5641 printf "%2d. ", $myi
5642 set $sa_family = $mymulti->ifma_addr.sa_family
5643 if ($sa_family == 2)
5644 if ($mymulti->ifma_ll != 0)
5645 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
5646 printf " "
5647 end
5648 showsockaddr_in $mymulti->ifma_addr
5649 end
5650 if ($sa_family == 30)
5651 if ($mymulti->ifma_ll != 0)
5652 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
5653 printf " "
5654 end
5655 showsockaddr_in6 $mymulti->ifma_addr
5656 end
5657 if ($sa_family == 18)
5658 showsockaddr_dl $mymulti->ifma_addr
5659 end
5660 if ($sa_family == 0)
5661 showsockaddr_unspec $mymulti->ifma_addr 6
5662 end
5663 printf " [%d]", $mymulti->ifma_refcount
5664 printf "\n"
5665 set $mymulti = $mymulti->ifma_link.le_next
5666 set $myi = $myi + 1
5667 end
5668 end
5669
5670 document showifmultiaddrs
5671 Syntax showifmultiaddrs <ifp>
5672 | show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
5673 end
5674
5675 define showsockaddr
5676 set $mysock = (struct sockaddr *)$arg0
5677 set $showsockaddr_handled = 0
5678 if ($mysock == 0)
5679 printf "(null)"
5680 else
5681 if ($mysock->sa_family == 0)
5682 printf "UNSPC"
5683 showsockaddr_unspec $mysock
5684 set $showsockaddr_handled = 1
5685 end
5686 if ($mysock->sa_family == 1)
5687 printf "UNIX "
5688 showsockaddr_un $mysock
5689 set $showsockaddr_handled = 1
5690 end
5691 if ($mysock->sa_family == 2)
5692 printf "INET "
5693 showsockaddr_in $mysock
5694 set $showsockaddr_handled = 1
5695 end
5696 if ($mysock->sa_family == 30)
5697 printf "INET6 "
5698 showsockaddr_in6 $mysock
5699 set $showsockaddr_handled = 1
5700 end
5701 if ($mysock->sa_family == 18)
5702 printf "LINK "
5703 showsockaddr_dl $mysock
5704 set $showsockaddr_handled = 1
5705 end
5706 if ($mysock->sa_family == 16)
5707 printf "ATLK "
5708 showsockaddr_at $mysock
5709 set $showsockaddr_handled = 1
5710 end
5711 if ($showsockaddr_handled == 0)
5712 printf "FAM %d ", $mysock->sa_family
5713 set $addr = $mysock->sa_data
5714 set $count = $mysock->sa_len
5715 printcolonhex $addr $count
5716 end
5717 end
5718 end
5719
5720 define showifflags
5721 set $flags = (u_short)$arg0
5722 set $first = 1
5723 printf "<"
5724 if ($flags & 0x1)
5725 printf "UP"
5726 set $first = 0
5727 end
5728 if ($flags & 0x2)
5729 if ($first == 1)
5730 set $first = 0
5731 else
5732 printf ","
5733 end
5734 printf "BROADCAST"
5735 end
5736 if ($flags & 0x4)
5737 printf "DEBUG"
5738 end
5739 if ($flags & 0x8)
5740 if ($first == 1)
5741 set $first = 0
5742 else
5743 printf ","
5744 end
5745 printf "LOOPBACK"
5746 end
5747 if ($flags & 0x10)
5748 if ($first == 1)
5749 set $first = 0
5750 else
5751 printf ","
5752 end
5753 printf "POINTTOPOINT"
5754 end
5755 # if ($flags & 0x20)
5756 # if ($first == 1)
5757 # set $first = 0
5758 # else
5759 # printf ","
5760 # end
5761 # printf "NOTRAILERS"
5762 # end
5763 if ($flags & 0x40)
5764 if ($first == 1)
5765 set $first = 0
5766 else
5767 printf ","
5768 end
5769 printf "RUNNING"
5770 end
5771 if ($flags & 0x80)
5772 if ($first == 1)
5773 set $first = 0
5774 else
5775 printf ","
5776 end
5777 printf "NOARP"
5778 end
5779 if ($flags & 0x100)
5780 if ($first == 1)
5781 set $first = 0
5782 else
5783 printf ","
5784 end
5785 printf "PROMISC"
5786 end
5787 if ($flags & 0x200)
5788 if ($first == 1)
5789 set $first = 0
5790 else
5791 printf ","
5792 end
5793 printf "ALLMULTI"
5794 end
5795 if ($flags & 0x400)
5796 if ($first == 1)
5797 set $first = 0
5798 else
5799 printf ","
5800 end
5801 printf "OACTIVE"
5802 end
5803 if ($flags & 0x800)
5804 if ($first == 1)
5805 set $first = 0
5806 else
5807 printf ","
5808 end
5809 printf "SIMPLEX"
5810 end
5811 if ($flags & 0x1000)
5812 if ($first == 1)
5813 set $first = 0
5814 else
5815 printf ","
5816 end
5817 printf "LINK0"
5818 end
5819 if ($flags & 0x2000)
5820 if ($first == 1)
5821 set $first = 0
5822 else
5823 printf ","
5824 end
5825 printf "LINK1"
5826 end
5827 if ($flags & 0x4000)
5828 if ($first == 1)
5829 set $first = 0
5830 else
5831 printf ","
5832 end
5833 printf "LINK2-ALTPHYS"
5834 end
5835 if ($flags & 0x8000)
5836 if ($first == 1)
5837 set $first = 0
5838 else
5839 printf ","
5840 end
5841 printf "MULTICAST"
5842 end
5843 printf ">"
5844 end
5845
5846 define showifaddrs
5847 set $ifp = (struct ifnet *)$arg0
5848 set $myifaddr = (struct ifaddr *)$ifp->if_addrhead->tqh_first
5849 set $myi = 0
5850 while ($myifaddr != 0)
5851 printf "\t%d. ", $myi
5852 showsockaddr $myifaddr->ifa_addr
5853 printf " [%d]\n", $myifaddr->ifa_refcnt
5854 set $myifaddr = $myifaddr->ifa_link->tqe_next
5855 set $myi = $myi + 1
5856 end
5857 end
5858
5859 document showifaddrs
5860 Syntax: showifaddrs <ifp>
5861 | show the (struct ifnet).if_addrhead list of addresses for the given ifp
5862 end
5863
5864 define ifconfig
5865 set $ifconfig_all = 0
5866 if ($argc == 1)
5867 set $ifconfig_all = 1
5868 end
5869 set $ifp = (struct ifnet *)(ifnet->tqh_first)
5870 while ($ifp != 0)
5871 printf "%s%d: flags=%hx", $ifp->if_name, $ifp->if_unit, (u_short)$ifp->if_flags
5872 showifflags $ifp->if_flags
5873 printf " index %d", $ifp->if_index
5874 printf " mtu %d\n", $ifp->if_data.ifi_mtu
5875 printf "\t(struct ifnet *)"
5876 showptr $ifp
5877 printf "\n"
5878 if ($ifconfig_all == 1)
5879 showifaddrs $ifp
5880 end
5881 set $ifp = $ifp->if_link->tqe_next
5882 end
5883 end
5884 document ifconfig
5885 Syntax: (gdb) ifconfig
5886 | display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
5887 end
5888
5889 define _show_unix_domain_socket
5890 set $so = (struct socket *)$arg0
5891 set $pcb = (struct unpcb *)$so->so_pcb
5892 if $pcb == 0
5893 printf "unpcb: (null) "
5894 else
5895 printf "unpcb: %p ", $pcb
5896 printf "unp_vnode: %p ", $pcb->unp_vnode
5897 printf "unp_conn: %p ", $pcb->unp_conn
5898 printf "unp_addr: "
5899 showsockaddr_un $pcb->unp_addr
5900 end
5901 end
5902
5903 define _show_in_port
5904 set $str = (unsigned char *)$arg0
5905 set $port = *(unsigned short *)$arg0
5906
5907 if (((($port & 0xff00) >> 8) == $str[0])) && ((($port & 0x00ff) == $str[1]))
5908 #printf "big endian "
5909 printf ":%d ", $port
5910 else
5911 #printf "little endian "
5912 printf ":%d ", (($port & 0xff00) >> 8) | (($port & 0x00ff) << 8)
5913 end
5914 end
5915
5916 define _show_in_addr_4in6
5917 set $ia = (unsigned char *)$arg0
5918 if $ia
5919 printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
5920 end
5921 end
5922
5923 define _show_in6_addr
5924 set $ia = (unsigned char *)$arg0
5925 if $ia
5926 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
5927 $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], \
5928 $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
5929 end
5930 end
5931
5932 define _showtcpstate
5933 set $tp = (struct tcpcb *)$arg0
5934 if $tp
5935 if $tp->t_state == 0
5936 printf "CLOSED "
5937 end
5938 if $tp->t_state == 1
5939 printf "LISTEN "
5940 end
5941 if $tp->t_state == 2
5942 printf "SYN_SENT "
5943 end
5944 if $tp->t_state == 3
5945 printf "SYN_RCVD "
5946 end
5947 if $tp->t_state == 4
5948 printf "ESTABLISHED "
5949 end
5950 if $tp->t_state == 5
5951 printf "CLOSE_WAIT "
5952 end
5953 if $tp->t_state == 6
5954 printf "FIN_WAIT_1 "
5955 end
5956 if $tp->t_state == 7
5957 printf "CLOSING "
5958 end
5959 if $tp->t_state == 8
5960 printf "LAST_ACK "
5961 end
5962 if $tp->t_state == 9
5963 printf "FIN_WAIT_2 "
5964 end
5965 if $tp->t_state == 10
5966 printf "TIME_WAIT "
5967 end
5968 end
5969 end
5970
5971 define _showsockprotocol
5972 set $so = (struct socket *)$arg0
5973 set $inpcb = (struct inpcb *)$so->so_pcb
5974
5975 if $so->so_proto->pr_protocol == 6
5976 printf "TCP "
5977 _showtcpstate $inpcb->inp_ppcb
5978 end
5979 if $so->so_proto->pr_protocol == 17
5980 printf "UDP "
5981 end
5982 if $so->so_proto->pr_protocol == 1
5983 printf "ICMP "
5984 end
5985 if $so->so_proto->pr_protocol == 254
5986 printf "DIVERT "
5987 end
5988 if $so->so_proto->pr_protocol == 255
5989 printf "RAW "
5990 end
5991 end
5992
5993 define _show_ipv4_socket
5994 set $so = (struct socket *)$arg0
5995 set $inpcb = (struct inpcb *)$so->so_pcb
5996 if $inpcb == 0
5997 printf "inpcb: (null) "
5998 else
5999 printf "inpcb: %p ", $inpcb
6000
6001 _showsockprotocol $so
6002
6003 _show_in_addr_4in6 &$inpcb->inp_dependladdr.inp46_local
6004 _show_in_port &$inpcb->inp_lport
6005 printf "-> "
6006 _show_in_addr_4in6 &$inpcb->inp_dependfaddr.inp46_foreign
6007 _show_in_port &$inpcb->inp_fport
6008 end
6009 end
6010
6011 define _show_ipv6_socket
6012 set $so = (struct socket *)$arg0
6013 set $pcb = (struct inpcb *)$so->so_pcb
6014 if $pcb == 0
6015 printf "inpcb: (null) "
6016 else
6017 printf "inpcb: %p ", $pcb
6018
6019 _showsockprotocol $so
6020
6021 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
6022 _show_in_port &$pcb->inp_lport
6023 printf "-> "
6024 _show_in6_addr &$pcb->inp_dependfaddr.inp6_foreign
6025 _show_in_port &$pcb->inp_fport
6026 end
6027 end
6028
6029
6030 define showsocket
6031 set $so = (struct socket *)$arg0
6032 if $so == 0
6033 printf "so: (null) "
6034 else
6035 printf "so: %p ", $so
6036 if $so && $so->so_proto && $so->so_proto->pr_domain
6037 set $domain = (struct domain *) $so->so_proto->pr_domain
6038
6039 printf "%s ", $domain->dom_name
6040 if $domain->dom_family == 1
6041 _show_unix_domain_socket $so
6042 end
6043 if $domain->dom_family == 2
6044 _show_ipv4_socket $so
6045 end
6046 if $domain->dom_family == 30
6047 _show_ipv6_socket $so
6048 end
6049 end
6050 end
6051 printf "\n"
6052 end
6053 document showsocket
6054 Syntax: (gdb) showsocket <socket_address>
6055 | Routine to print out a socket
6056 end
6057
6058 define showprocsockets
6059 set $pp = (struct proc *)$arg0
6060 set $fdp = (struct filedesc *)$pp->p_fd
6061
6062 set $count = 0
6063 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
6064 set $fpo = (char)($fdp->fd_ofileflags[0])
6065 while $count < $fdp->fd_nfiles
6066 if *$fpp
6067 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
6068 if $fg && (($fg)->fg_type == 2)
6069 if $fdp->fd_ofileflags[$count] & 4
6070 printf "U: "
6071 else
6072 printf " "
6073 end
6074 printf "fd = %d ", $count
6075 if $fg->fg_data
6076 showsocket $fg->fg_data
6077 else
6078 printf "\n"
6079 end
6080 end
6081 end
6082 set $fpp = $fpp + 1
6083 set $count = $count + 1
6084 end
6085 end
6086 document showprocsockets
6087 Syntax: (gdb) showprocsockets <proc_address>
6088 | Routine to print out all the open fds
6089 | which are sockets in a process
6090 end
6091
6092 define showallprocsockets
6093 set $basep = (struct proc *)allproc->lh_first
6094 set $pp = $basep
6095 while $pp
6096 printf "============================================ \n"
6097 showproc $pp
6098 showprocsockets $pp
6099 set $pp = $pp->p_list.le_next
6100 end
6101 end
6102 document showallprocsockets
6103 Syntax: (gdb) showallprocsockets
6104 | Routine to print out all the open fds
6105 | which are sockets
6106 end
6107
6108 define _print_ntohs
6109 set $port = (unsigned short)$arg0
6110 set $port = (unsigned short)((($arg0 & 0xff00) >> 8) & 0xff)
6111 set $port |= (unsigned short)(($arg0 & 0xff) << 8)
6112 printf "%5d", $port
6113 end
6114
6115 set $INPCB_STATE_INUSE=0x1
6116 set $INPCB_STATE_CACHED=0x2
6117 set $INPCB_STATE_DEAD=0x3
6118
6119 set $INP_RECVOPTS=0x01
6120 set $INP_RECVRETOPTS=0x02
6121 set $INP_RECVDSTADDR=0x04
6122 set $INP_HDRINCL=0x08
6123 set $INP_HIGHPORT=0x10
6124 set $INP_LOWPORT=0x20
6125 set $INP_ANONPORT=0x40
6126 set $INP_RECVIF=0x80
6127 set $INP_MTUDISC=0x100
6128 set $INP_STRIPHDR=0x200
6129 set $INP_FAITH=0x400
6130 set $INP_INADDR_ANY=0x800
6131 set $INP_RECVTTL=0x1000
6132 set $INP_UDP_NOCKSUM=0x2000
6133 set $IN6P_IPV6_V6ONLY=0x008000
6134 set $IN6P_PKTINFO=0x010000
6135 set $IN6P_HOPLIMIT=0x020000
6136 set $IN6P_HOPOPTS=0x040000
6137 set $IN6P_DSTOPTS=0x080000
6138 set $IN6P_RTHDR=0x100000
6139 set $IN6P_RTHDRDSTOPTS=0x200000
6140 set $IN6P_AUTOFLOWLABEL=0x800000
6141 set $IN6P_BINDV6ONLY=0x10000000
6142
6143 set $INP_IPV4=0x1
6144 set $INP_IPV6=0x2
6145
6146 set $IPPROTO_TCP=6
6147 set $IPPROTO_UDP=17
6148
6149 define _dump_inpcb
6150 set $pcb = (struct inpcb *)$arg0
6151 if $kgm_lp64
6152 printf "%18p", $pcb
6153 else
6154 printf "%10p ", $pcb
6155 end
6156 if $arg1 == $IPPROTO_TCP
6157 printf "tcp"
6158 else
6159 if $arg1 == $IPPROTO_UDP
6160 printf "udp"
6161 else
6162 printf "%2d.", $arg1
6163 end
6164 end
6165 if ($pcb->inp_vflag & $INP_IPV4)
6166 printf "4 "
6167 end
6168 if ($pcb->inp_vflag & $INP_IPV6)
6169 printf "6 "
6170 end
6171
6172 if ($pcb->inp_vflag & $INP_IPV4)
6173 printf " "
6174 _show_in_addr &$pcb->inp_dependladdr.inp46_local.ia46_addr4
6175 else
6176 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
6177 end
6178 printf " "
6179 _print_ntohs $pcb->inp_lport
6180 printf " "
6181 if ($pcb->inp_vflag & $INP_IPV4)
6182 printf " "
6183 _show_in_addr &($pcb->inp_dependfaddr.inp46_foreign.ia46_addr4)
6184 else
6185 _show_in6_addr &($pcb->inp_dependfaddr.inp6_foreign)
6186 end
6187 printf " "
6188 _print_ntohs $pcb->inp_fport
6189 printf " "
6190
6191 if $arg1 == $IPPROTO_TCP
6192 _showtcpstate $pcb->inp_ppcb
6193 end
6194
6195 # printf "phd "
6196 # set $phd = $pcb->inp_phd
6197 # while $phd != 0
6198 # printf " "
6199 # _print_ntohs $phd->phd_port
6200 # set $phd = $phd->phd_hash.le_next
6201 # end
6202 # printf ", "
6203 if ($pcb->inp_flags & $INP_RECVOPTS)
6204 printf "recvopts "
6205 end
6206 if ($pcb->inp_flags & $INP_RECVRETOPTS)
6207 printf "recvretopts "
6208 end
6209 if ($pcb->inp_flags & $INP_RECVDSTADDR)
6210 printf "recvdstaddr "
6211 end
6212 if ($pcb->inp_flags & $INP_HDRINCL)
6213 printf "hdrincl "
6214 end
6215 if ($pcb->inp_flags & $INP_HIGHPORT)
6216 printf "highport "
6217 end
6218 if ($pcb->inp_flags & $INP_LOWPORT)
6219 printf "lowport "
6220 end
6221 if ($pcb->inp_flags & $INP_ANONPORT)
6222 printf "anonport "
6223 end
6224 if ($pcb->inp_flags & $INP_RECVIF)
6225 printf "recvif "
6226 end
6227 if ($pcb->inp_flags & $INP_MTUDISC)
6228 printf "mtudisc "
6229 end
6230 if ($pcb->inp_flags & $INP_STRIPHDR)
6231 printf "striphdr "
6232 end
6233 if ($pcb->inp_flags & $INP_FAITH)
6234 printf "faith "
6235 end
6236 if ($pcb->inp_flags & $INP_INADDR_ANY)
6237 printf "inaddr_any "
6238 end
6239 if ($pcb->inp_flags & $INP_RECVTTL)
6240 printf "recvttl "
6241 end
6242 if ($pcb->inp_flags & $INP_UDP_NOCKSUM)
6243 printf "nocksum "
6244 end
6245 if ($pcb->inp_flags & $IN6P_IPV6_V6ONLY)
6246 printf "v6only "
6247 end
6248 if ($pcb->inp_flags & $IN6P_PKTINFO)
6249 printf "pktinfo "
6250 end
6251 if ($pcb->inp_flags & $IN6P_HOPLIMIT)
6252 printf "hoplimit "
6253 end
6254 if ($pcb->inp_flags & $IN6P_HOPOPTS)
6255 printf "hopopts "
6256 end
6257 if ($pcb->inp_flags & $IN6P_DSTOPTS)
6258 printf "dstopts "
6259 end
6260 if ($pcb->inp_flags & $IN6P_RTHDR)
6261 printf "rthdr "
6262 end
6263 if ($pcb->inp_flags & $IN6P_RTHDRDSTOPTS)
6264 printf "rthdrdstopts "
6265 end
6266 if ($pcb->inp_flags & $IN6P_AUTOFLOWLABEL)
6267 printf "autoflowlabel "
6268 end
6269 if ($pcb->inp_flags & $IN6P_BINDV6ONLY)
6270 printf "bindv6only "
6271 end
6272 set $so = (struct socket *)$pcb->inp_socket
6273 if $so != 0
6274 printf "[so=%p s=%ld r=%ld usecnt=%ld] ", $so, $so->so_snd.sb_cc, \
6275 $so->so_rcv.sb_cc, $so->so_usecount
6276 end
6277 if ($pcb->inp_state == 0 || $pcb->inp_state == $INPCB_STATE_INUSE)
6278 printf "inuse, "
6279 else
6280 if ($pcb->inp_state == $INPCB_STATE_CACHED)
6281 printf "cached, "
6282 else
6283 if ($pcb->inp_state == $INPCB_STATE_DEAD)
6284 printf "dead, "
6285 else
6286 printf "unknown (%d), ", $pcb->inp_state
6287 end
6288 end
6289 end
6290 end
6291
6292 define _dump_inpcbport
6293 set $ppcb = (struct inpcbport *)$arg0
6294 printf "%p: lport ", $ppcb
6295 _print_ntohs $ppcb->phd_port
6296 end
6297
6298 set $UDBHASHSIZE=16
6299
6300 define _dump_pcbinfo
6301 set $snd_cc = 0
6302 set $rcv_cc = 0
6303 set $pcbseen = 0
6304 set $pcbi = (struct inpcbinfo *)$arg0
6305 printf "lastport %d lastlow %d lasthi %d\n", \
6306 $pcbi->lastport, $pcbi->lastlow, $pcbi->lasthi
6307 printf "active pcb count is %d\n", $pcbi->ipi_count
6308 set $hashsize = $pcbi->hashmask + 1
6309 printf "hash size is %d\n", $hashsize
6310 printf "hash base %p has the following inpcb(s):\n", $pcbi->hashbase
6311 if $kgm_lp64
6312 printf "pcb prot source address port destination address port\n"
6313 printf "------------------ ---- --------------------------------------- ----- --------------------------------------- -----\n"
6314 else
6315 printf "pcb prot source address port destination address port\n"
6316 printf "---------- ---- --------------------------------------- ----- --------------------------------------- -----\n"
6317 end
6318 set $i = 0
6319 set $hashbase = $pcbi->hashbase
6320 set $head = *(uintptr_t *)$hashbase
6321 while $i < $hashsize
6322 if $head != 0
6323 set $pcb0 = (struct inpcb *)$head
6324 while $pcb0 != 0
6325 set $pcbseen += 1
6326 _dump_inpcb $pcb0 $arg1
6327 set $so = (struct socket *)$pcb->inp_socket
6328 if $so != 0
6329 set $snd_cc += $so->so_snd.sb_cc
6330 set $rcv_cc += $so-> so_rcv.sb_cc
6331 end
6332 set $pcb0 = $pcb0->inp_hash.le_next
6333 printf "\n"
6334 end
6335 end
6336 set $i += 1
6337 set $hashbase += 1
6338 set $head = *(uintptr_t *)$hashbase
6339 end
6340 printf "total seen %ld snd_cc %ld rcv_cc %ld\n", $pcbseen, $snd_cc, $rcv_cc
6341 printf "port hash base is %p\n", $pcbi->porthashbase
6342 set $i = 0
6343 set $hashbase = $pcbi->porthashbase
6344 set $head = *(uintptr_t *)$hashbase
6345 while $i < $hashsize
6346 if $head != 0
6347 set $pcb0 = (struct inpcbport *)$head
6348 while $pcb0 != 0
6349 printf "\t"
6350 _dump_inpcbport $pcb0
6351 printf "\n"
6352 set $pcb0 = $pcb0->phd_hash.le_next
6353 end
6354 end
6355 set $i += 1
6356 set $hashbase += 1
6357 set $head = *(uintptr_t *)$hashbase
6358 end
6359 end
6360
6361 set $N_TIME_WAIT_SLOTS=128
6362
6363 define show_tcp_timewaitslots
6364 set $slot = -1
6365 set $all = 0
6366 if $argc == 1
6367 if (int)$arg0 == -1
6368 set $all = 1
6369 else
6370 set $slot = (int)$arg0
6371 end
6372 end
6373 printf "time wait slot size %d cur_tw_slot %ld\n", $N_TIME_WAIT_SLOTS, cur_tw_slot
6374 set $i = 0
6375 while $i < $N_TIME_WAIT_SLOTS
6376 set $perslot = 0
6377 set $head = (uintptr_t *)time_wait_slots[$i]
6378 if $i == $slot || $slot == -1
6379 if $head != 0
6380 set $pcb0 = (struct inpcb *)$head
6381 while $pcb0 != 0
6382 set $perslot += 1
6383 set $pcb0 = $pcb0->inp_list.le_next
6384 end
6385 end
6386 printf " slot %ld count %ld\n", $i, $perslot
6387 end
6388 if $all || $i == $slot
6389 if $head != 0
6390 set $pcb0 = (struct inpcb *)$head
6391 while $pcb0 != 0
6392 printf "\t"
6393 _dump_inpcb $pcb0 $IPPROTO_TCP
6394 printf "\n"
6395 set $pcb0 = $pcb0->inp_list.le_next
6396 end
6397 end
6398 end
6399 set $i += 1
6400 end
6401 end
6402 document show_tcp_timewaitslots
6403 Syntax: (gdb) show_tcp_timewaitslots
6404 | Print the list of TCP protocol control block in the TIMEWAIT state
6405 | Pass -1 to see the list of PCB for each slot
6406 | Pass a slot number to see information for that slot with the list of PCB
6407 end
6408
6409 define show_tcp_pcbinfo
6410 _dump_pcbinfo &tcbinfo $IPPROTO_TCP
6411 end
6412 document show_tcp_pcbinfo
6413 Syntax: (gdb) show_tcp_pcbinfo
6414 | Print the list of TCP protocol control block information
6415 end
6416
6417
6418 define show_udp_pcbinfo
6419 _dump_pcbinfo &udbinfo $IPPROTO_UDP
6420 end
6421 document show_udp_pcbinfo
6422 Syntax: (gdb) show_udp_pcbinfo
6423 | Print the list of UDP protocol control block information
6424 end
6425
6426 define showbpfdtab
6427 set $myi = 0
6428 while ($myi < bpf_dtab_size)
6429 if (bpf_dtab[$myi] != 0)
6430 printf "Address 0x%x, bd_next 0x%x\n", bpf_dtab[$myi], bpf_dtab[$myi]->bd_next
6431 print *bpf_dtab[$myi]
6432 end
6433 set $myi = $myi + 1
6434 end
6435 end
6436
6437 define printvnodepathint_recur
6438 if $arg0 != 0
6439 if ($arg0->v_flag & 0x000001) && ($arg0->v_mount != 0)
6440 if $arg0->v_mount->mnt_vnodecovered != 0
6441 printvnodepathint_recur $arg0->v_mount->mnt_vnodecovered $arg0->v_mount->mnt_vnodecovered->v_name
6442 end
6443 else
6444 printvnodepathint_recur $arg0->v_parent $arg0->v_parent->v_name
6445 printf "/%s", $arg1
6446 end
6447 end
6448 end
6449
6450 define showvnodepath
6451 set $vp = (struct vnode *)$arg0
6452 if $vp != 0
6453 if ($vp->v_flag & 0x000001) && ($vp->v_mount != 0) && ($vp->v_mount->mnt_flag & 0x00004000)
6454 printf "/"
6455 else
6456 printvnodepathint_recur $vp $vp->v_name
6457 end
6458 end
6459 printf "\n"
6460 end
6461
6462 document showvnodepath
6463 Syntax: (gdb) showvnodepath <vnode>
6464 | Prints the path for a vnode
6465 end
6466
6467 define showallvols
6468 printf "volume "
6469 showptrhdrpad
6470 printf " mnt_data "
6471 showptrhdrpad
6472 printf " mnt_devvp "
6473 showptrhdrpad
6474 printf " typename mountpoint\n"
6475 set $kgm_vol = (mount_t) mountlist.tqh_first
6476 while $kgm_vol
6477 showptr $kgm_vol
6478 printf " "
6479 showptr $kgm_vol->mnt_data
6480 printf " "
6481 showptr $kgm_vol->mnt_devvp
6482 printf " "
6483 if ($kgm_vol->mnt_vtable->vfc_name[0] == 'h') && \
6484 ($kgm_vol->mnt_vtable->vfc_name[1] == 'f') && \
6485 ($kgm_vol->mnt_vtable->vfc_name[2] == 's') && \
6486 ($kgm_vol->mnt_vtable->vfc_name[3] == '\0')
6487 set $kgm_hfsmount = \
6488 (struct hfsmount *) $kgm_vol->mnt_data
6489 if $kgm_hfsmount->hfs_freezing_proc != 0
6490 printf "FROZEN hfs "
6491 else
6492 printf "hfs "
6493 end
6494 else
6495 printf "%-10s ", $kgm_vol->mnt_vtable->vfc_name
6496 end
6497 printf "%s\n", $kgm_vol->mnt_vfsstat.f_mntonname
6498
6499 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6500 end
6501 end
6502
6503 document showallvols
6504 Syntax: (gdb) showallvols
6505 | Display a summary of mounted volumes
6506 end
6507
6508 define showvnodeheader
6509 printf "vnode "
6510 showptrhdrpad
6511 printf " usecount iocount v_data "
6512 showptrhdrpad
6513 printf " vtype parent "
6514 showptrhdrpad
6515 printf " name\n"
6516 end
6517
6518 define showvnodeint
6519 set $kgm_vnode = (vnode_t) $arg0
6520 showptr $kgm_vnode
6521 printf " %8d ", $kgm_vnode->v_usecount
6522 printf "%7d ", $kgm_vnode->v_iocount
6523 # print information about clean/dirty blocks?
6524 showptr $kgm_vnode->v_data
6525 printf " "
6526 # print the vtype, using the enum tag
6527 set $kgm_vtype = $kgm_vnode->v_type
6528 if $kgm_vtype == VNON
6529 printf "VNON "
6530 end
6531 if $kgm_vtype == VREG
6532 printf "VREG "
6533 end
6534 if $kgm_vtype == VDIR
6535 printf "VDIR "
6536 end
6537 if $kgm_vtype == VBLK
6538 printf "VBLK "
6539 end
6540 if $kgm_vtype == VCHR
6541 printf "VCHR "
6542 end
6543 if $kgm_vtype == VLNK
6544 printf "VLNK "
6545 end
6546 if $kgm_vtype == VSOCK
6547 printf "VSOCK "
6548 end
6549 if $kgm_vtype == VFIFO
6550 printf "VFIFO "
6551 end
6552 if $kgm_vtype == VBAD
6553 printf "VBAD "
6554 end
6555 if ($kgm_vtype < VNON) || ($kgm_vtype > VBAD)
6556 printf "%5d ", $kgm_vtype
6557 end
6558
6559 showptr $kgm_vnode->v_parent
6560 printf " "
6561 if $kgm_vnode->v_name != 0
6562 printf "%s\n", $kgm_vnode->v_name
6563 else
6564 printf "\n"
6565 end
6566 end
6567
6568 define showvnode
6569 showvnodeheader
6570 showvnodeint $arg0
6571 end
6572
6573 document showvnode
6574 Syntax: (gdb) showvnode <vnode>
6575 | Display info about one vnode
6576 end
6577
6578 define showvolvnodes
6579 showvnodeheader
6580 set $kgm_vol = (mount_t) $arg0
6581 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6582 while $kgm_vnode
6583 showvnodeint $kgm_vnode
6584 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6585 end
6586 end
6587
6588 document showvolvnodes
6589 Syntax: (gdb) showvolvnodes <mouont_t>
6590 | Display info about all vnodes of a given mount_t
6591 end
6592
6593 define showvolbusyvnodes
6594 showvnodeheader
6595 set $kgm_vol = (mount_t) $arg0
6596 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6597 while $kgm_vnode
6598 if $kgm_vnode->v_iocount != 0
6599 showvnodeint $kgm_vnode
6600 end
6601 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6602 end
6603 end
6604
6605 document showvolbusyvnodes
6606 Syntax: (gdb) showvolbusyvnodes <mount_t>
6607 | Display info about busy (iocount!=0) vnodes of a given mount_t
6608 end
6609
6610 define showallbusyvnodes
6611 showvnodeheader
6612 set $kgm_vol = (mount_t) mountlist.tqh_first
6613 while $kgm_vol
6614 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6615 while $kgm_vnode
6616 if $kgm_vnode->v_iocount != 0
6617 showvnodeint $kgm_vnode
6618 end
6619 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6620 end
6621 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6622 end
6623 end
6624
6625 document showallbusyvnodes
6626 Syntax: (gdb) showallbusyvnodes <vnode>
6627 | Display info about all busy (iocount!=0) vnodes
6628 end
6629
6630 define showallvnodes
6631 showvnodeheader
6632 set $kgm_vol = (mount_t) mountlist.tqh_first
6633 while $kgm_vol
6634 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
6635 while $kgm_vnode
6636 showvnodeint $kgm_vnode
6637 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
6638 end
6639 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
6640 end
6641 end
6642
6643 document showallvnodes
6644 Syntax: (gdb) showallvnodes
6645 | Display info about all vnodes
6646 end
6647
6648 define _showvnodelockheader
6649 printf "* type W held by lock type start end\n"
6650 printf "- ----- - ------------- --------- ------------------ ------------------\n"
6651 end
6652
6653 define _showvnodelock
6654 set $kgm_svl_lock = ((struct lockf *)$arg0)
6655
6656 # decode flags
6657 set $kgm_svl_flags = $kgm_svl_lock->lf_flags
6658 set $kgm_svl_type = $kgm_svl_lock->lf_type
6659 if ($kgm_svl_flags & 0x20)
6660 printf "flock"
6661 end
6662 if ($kgm_svl_flags & 0x40)
6663 printf "posix"
6664 end
6665 if ($kgm_svl_flags & 0x80)
6666 printf "prov "
6667 end
6668 if ($kgm_svl_flags & 0x10)
6669 printf " W "
6670 else
6671 printf " . "
6672 end
6673
6674 # POSIX file vs. advisory range locks
6675 if ($kgm_svl_flags & 0x40)
6676 set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id
6677 printf "PID %8d ", $kgm_svl_proc->p_pid
6678 else
6679 printf "ID 0x%08x ", $kgm_svl_lock->lf_id
6680 end
6681
6682 # lock type
6683 if ($kgm_svl_type == 1)
6684 printf "shared "
6685 else
6686 if ($kgm_svl_type == 3)
6687 printf "exclusive "
6688 else
6689 if ($kgm_svl_type == 2)
6690 printf "unlock "
6691 else
6692 printf "unknown "
6693 end
6694 end
6695 end
6696
6697 # start and stop
6698 printf "0x%016x..", $kgm_svl_lock->lf_start
6699 printf "0x%016x ", $kgm_svl_lock->lf_end
6700 printf "\n"
6701 end
6702 # Body of showvnodelocks, not including header
6703 define _showvnodelocks
6704 set $kgm_svl_vnode = ((vnode_t)$arg0)
6705 set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf
6706 while ($kgm_svl_lockiter != 0)
6707 # locks that are held
6708 printf "H "
6709 _showvnodelock $kgm_svl_lockiter
6710
6711 # and any locks blocked by them
6712 set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first
6713 while ($kgm_svl_blocker != 0)
6714 printf "> "
6715 _showvnodelock $kgm_svl_blocker
6716 set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next
6717 end
6718
6719 # and on to the next one...
6720 set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next
6721 end
6722 end
6723
6724
6725 define showvnodelocks
6726 if ($argc == 1)
6727 _showvnodelockheader
6728 _showvnodelocks $arg0
6729 else
6730 printf "| Usage:\n|\n"
6731 help showvnodelocks
6732 end
6733 end
6734
6735 document showvnodelocks
6736 Syntax: (gdb) showvnodelocks <vnode_t>
6737 | Given a vnodet pointer, display the list of advisory record locks for the
6738 | referenced pvnodes
6739 end
6740
6741 define showbootargs
6742 printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
6743 end
6744
6745 document showbootargs
6746 Syntax: showbootargs
6747 | Display boot arguments passed to the target kernel
6748 end
6749
6750 define showbootermemorymap
6751 if ($kgm_mtype == $kgm_mtype_i386)
6752 set $kgm_voffset = 0
6753 else
6754 if ($kgm_mtype == $kgm_mtype_x86_64)
6755 set $kgm_voffset = 0xFFFFFF8000000000ULL
6756 else
6757 echo showbootermemorymap not supported on this architecture
6758 end
6759 end
6760
6761 set $kgm_boot_args = kernelBootArgs
6762 set $kgm_msize = kernelBootArgs->MemoryMapDescriptorSize
6763 set $kgm_mcount = kernelBootArgs->MemoryMapSize / $kgm_msize
6764 set $kgm_i = 0
6765
6766 printf "Type Physical Start Number of Pages Virtual Start Attributes\n"
6767 while $kgm_i < $kgm_mcount
6768 set $kgm_mptr = (EfiMemoryRange *)((unsigned long)kernelBootArgs->MemoryMap + $kgm_voffset + $kgm_i * $kgm_msize)
6769 # p/x *$kgm_mptr
6770 if $kgm_mptr->Type == 0
6771 printf "reserved "
6772 end
6773 if $kgm_mptr->Type == 1
6774 printf "LoaderCode"
6775 end
6776 if $kgm_mptr->Type == 2
6777 printf "LoaderData"
6778 end
6779 if $kgm_mptr->Type == 3
6780 printf "BS_code "
6781 end
6782 if $kgm_mptr->Type == 4
6783 printf "BS_data "
6784 end
6785 if $kgm_mptr->Type == 5
6786 printf "RT_code "
6787 end
6788 if $kgm_mptr->Type == 6
6789 printf "RT_data "
6790 end
6791 if $kgm_mptr->Type == 7
6792 printf "available "
6793 end
6794 if $kgm_mptr->Type == 8
6795 printf "Unusable "
6796 end
6797 if $kgm_mptr->Type == 9
6798 printf "ACPI_recl "
6799 end
6800 if $kgm_mptr->Type == 10
6801 printf "ACPI_NVS "
6802 end
6803 if $kgm_mptr->Type == 11
6804 printf "MemMapIO "
6805 end
6806 if $kgm_mptr->Type == 12
6807 printf "MemPortIO "
6808 end
6809 if $kgm_mptr->Type == 13
6810 printf "PAL_code "
6811 end
6812 if $kgm_mptr->Type > 13
6813 printf "UNKNOWN "
6814 end
6815
6816 printf " %016llx %016llx", $kgm_mptr->PhysicalStart, $kgm_mptr->NumberOfPages
6817 if $kgm_mptr->VirtualStart != 0
6818 printf " %016llx", $kgm_mptr->VirtualStart
6819 else
6820 printf " "
6821 end
6822 printf " %016llx\n", $kgm_mptr->Attribute
6823 set $kgm_i = $kgm_i + 1
6824 end
6825 end
6826
6827 document showbootermemorymap
6828 Syntax: (gdb) showbootermemorymap
6829 | Prints out the phys memory map from kernelBootArgs
6830 end
6831
6832
6833 define showstacksaftertask
6834 set $kgm_head_taskp = &default_pset.tasks
6835 set $kgm_taskp = (struct task *)$arg0
6836 while $kgm_taskp != $kgm_head_taskp
6837 showtaskheader
6838 showtaskint $kgm_taskp
6839 set $kgm_head_actp = &($kgm_taskp->threads)
6840 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
6841 while $kgm_actp != $kgm_head_actp
6842 showactheader
6843 if ($decode_wait_events > 0)
6844 showactint $kgm_actp 1
6845 else
6846 showactint $kgm_actp 2
6847 end
6848 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
6849 end
6850 printf "\n"
6851 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
6852 end
6853 end
6854 document showstacksaftertask
6855 Syntax: (gdb) showstacksaftertask <task>
6856 | Routine to print out all stacks (as in showallstacks) starting after a given task
6857 | Useful if that gdb refuses to print a certain task's stack.
6858 end
6859
6860 define showpmworkqueueint
6861 set $kgm_pm_wq = (IOPMWorkQueue *)$arg0
6862 set $kgm_pm_node = (IOService *)$kgm_pm_wq->owner
6863 showptr $kgm_pm_wq
6864 printf " "
6865 showptr $kgm_pm_node
6866 printf " "
6867 printf "%02d ", $kgm_pm_node->pwrMgt->CurrentPowerState
6868 printf "%02d ", $kgm_pm_node->pwrMgt->MachineState
6869 printf "%02d ", $kgm_pm_node->pwrMgt->WaitReason
6870 printf "%s\n", $kgm_pm_node->pwrMgt->Name
6871 set $kgm_pm_queue = &($kgm_pm_wq->fWorkQueue)
6872 set $kgm_pm_req = (IOPMRequest *)$kgm_pm_queue->next
6873 if ((queue_entry_t) $kgm_pm_req != (queue_entry_t) $kgm_pm_queue)
6874 printf "\n"
6875 printf "request "
6876 showptrhdrpad
6877 printf " type next "
6878 showptrhdrpad
6879 printf " root "
6880 showptrhdrpad
6881 printf " work_wait free_wait\n"
6882 while ((queue_entry_t) $kgm_pm_req != (queue_entry_t) $kgm_pm_queue)
6883 showptr $kgm_pm_req
6884 printf " 0x%02x ", $kgm_pm_req->fType
6885 showptr $kgm_pm_req->fRequestNext
6886 printf " "
6887 showptr $kgm_pm_req->fRequestRoot
6888 printf " 0x%08x 0x%08x\n", $kgm_pm_req->fWorkWaitCount, $kgm_pm_req->fFreeWaitCount
6889 showptrhdrpad
6890 printf " args "
6891 showptr $kgm_pm_req->fArg0
6892 printf " "
6893 showptr $kgm_pm_req->fArg1
6894 printf " "
6895 showptr $kgm_pm_req->fArg2
6896 printf "\n"
6897 set $kgm_pm_req = (IOPMRequest *)$kgm_pm_req->fCommandChain.next
6898 end
6899 printf "\n"
6900 end
6901 end
6902
6903 define showallpmworkqueues
6904 set $kgm_pm_next = gIOPMWorkLoop->eventChain
6905 printf "queue "
6906 showptrhdrpad
6907 printf " owner "
6908 showptrhdrpad
6909 printf " ps ms wr name\n"
6910 while ( $kgm_pm_next )
6911 set $kgm_vt = *((void **) $kgm_pm_next)
6912 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
6913 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
6914 end
6915 if ($kgm_vt == &_ZTV13IOPMWorkQueue)
6916 showpmworkqueueint $kgm_pm_next
6917 end
6918 set $kgm_pm_next = $kgm_pm_next->eventChainNext
6919 end
6920 end
6921
6922 document showallpmworkqueues
6923 Syntax: (gdb) showallpmworkqueues
6924 | Display info about all IOPMWorkQueue objects
6925 end
6926
6927 define showioservicepm
6928 set $kgm_iopmpriv = (IOServicePM *)$arg0
6929 printf "{ "
6930 printf "MachineState = %d (", $kgm_iopmpriv->MachineState
6931 if ( $kgm_iopmpriv->MachineState == 1 )
6932 printf "kIOPM_OurChangeTellClientsPowerDown"
6933 else
6934 if ( $kgm_iopmpriv->MachineState == 2 )
6935 printf "kIOPM_OurChangeTellPriorityClientsPowerDown"
6936 else
6937 if ( $kgm_iopmpriv->MachineState == 3 )
6938 printf "kIOPM_OurChangeNotifyInterestedDriversWillChange"
6939 else
6940 if ( $kgm_iopmpriv->MachineState == 4 )
6941 printf "kIOPM_OurChangeSetPowerState"
6942 else
6943 if ( $kgm_iopmpriv->MachineState == 5 )
6944 printf "kIOPM_OurChangeWaitForPowerSettle"
6945 else
6946 if ( $kgm_iopmpriv->MachineState == 6 )
6947 printf "kIOPM_OurChangeNotifyInterestedDriversDidChange"
6948 else
6949 if ( $kgm_iopmpriv->MachineState == 7 )
6950 printf "kIOPM_OurChangeFinish"
6951 else
6952 if ( $kgm_iopmpriv->MachineState == 8 )
6953 printf "kIOPM_ParentDownTellPriorityClientsPowerDown"
6954 else
6955 if ( $kgm_iopmpriv->MachineState == 9 )
6956 printf "kIOPM_ParentDownNotifyInterestedDriversWillChange"
6957 else
6958 if ( $kgm_iopmpriv->MachineState == 10 )
6959 printf "Unused_MachineState_10"
6960 else
6961 if ( $kgm_iopmpriv->MachineState == 11 )
6962 printf "kIOPM_ParentDownNotifyDidChangeAndAcknowledgeChange"
6963 else
6964 if ( $kgm_iopmpriv->MachineState == 12 )
6965 printf "kIOPM_ParentDownSetPowerState"
6966 else
6967 if ( $kgm_iopmpriv->MachineState == 13 )
6968 printf "kIOPM_ParentDownWaitForPowerSettle"
6969 else
6970 if ( $kgm_iopmpriv->MachineState == 14 )
6971 printf "kIOPM_ParentDownAcknowledgeChange"
6972 else
6973 if ( $kgm_iopmpriv->MachineState == 15)
6974 printf "kIOPM_ParentUpSetPowerState"
6975 else
6976 if ( $kgm_iopmpriv->MachineState == 16)
6977 printf "Unused_MachineState_16"
6978 else
6979 if ( $kgm_iopmpriv->MachineState == 17)
6980 printf "kIOPM_ParentUpWaitForSettleTime"
6981 else
6982 if ( $kgm_iopmpriv->MachineState == 18)
6983 printf "kIOPM_ParentUpNotifyInterestedDriversDidChange"
6984 else
6985 if ( $kgm_iopmpriv->MachineState == 19)
6986 printf "kIOPM_ParentUpAcknowledgePowerChange"
6987 else
6988 if ( $kgm_iopmpriv->MachineState == 20)
6989 printf "kIOPM_Finished"
6990 else
6991 if ( $kgm_iopmpriv->MachineState == 21)
6992 printf "kIOPM_DriverThreadCallDone"
6993 else
6994 if ( $kgm_iopmpriv->MachineState == 22)
6995 printf "kIOPM_NotifyChildrenDone"
6996 end
6997 end
6998 end
6999 end
7000 end
7001 end
7002 end
7003 end
7004 end
7005 end
7006 end
7007 end
7008 end
7009 end
7010 end
7011 end
7012 end
7013 end
7014 end
7015 end
7016 end
7017 end
7018 printf "), "
7019
7020 if ( $kgm_iopmpriv->MachineState != 20 )
7021 printf "DriverTimer = %d, ",(unsigned int)$kgm_iopmpriv->DriverTimer
7022 printf "SettleTime = %d, ",(unsigned int)$kgm_iopmpriv->SettleTimeUS
7023 printf "HeadNoteFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteFlags
7024 printf "HeadNotePendingAcks = %x, ",(unsigned int)$kgm_iopmpriv->HeadNotePendingAcks
7025 end
7026
7027 if ( $kgm_iopmpriv->DeviceOverrides != 0 )
7028 printf"DeviceOverrides, "
7029 end
7030
7031 printf "DeviceDesire = %d, ",(unsigned int)$kgm_iopmpriv->DeviceDesire
7032 printf "DesiredPowerState = %d, ",(unsigned int)$kgm_iopmpriv->DesiredPowerState
7033 printf "PreviousRequest = %d }\n",(unsigned int)$kgm_iopmpriv->PreviousRequest
7034 end
7035
7036 document showioservicepm
7037 Syntax: (gdb) showioservicepm <IOServicePM pointer>
7038 | Routine to dump the IOServicePM object
7039 end
7040
7041 define showregistryentryrecursepmstate
7042 set $kgm_re = (IOService *)$arg1
7043 set $kgm$arg0_stack = (unsigned long long) $arg2
7044
7045 if ($arg3)
7046 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
7047 else
7048 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
7049 end
7050
7051 dictget $kgm_re->fRegistryTable $kgm_childkey
7052 set $kgm$arg0_child_array = (OSArray *) $kgm_result
7053
7054 if ($kgm$arg0_child_array)
7055 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
7056 else
7057 set $kgm$arg0_child_count = 0
7058 end
7059
7060 if ($kgm$arg0_child_count)
7061 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
7062 else
7063 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
7064 end
7065
7066 indent $kgm_reg_depth $kgm$arg0_stack
7067 printf "+-o "
7068
7069 dictget $kgm_re->fRegistryTable $kgm_namekey
7070 if ($kgm_result == 0)
7071 dictget $kgm_re->fRegistryTable gIONameKey
7072 end
7073 if ($kgm_result == 0)
7074 dictget $kgm_re->fPropertyTable gIOClassKey
7075 end
7076
7077 if ($kgm_result != 0)
7078 printf "%s <%p>", ((OSString *)$kgm_result)->string, $kgm_re
7079 else
7080 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
7081 printf "%s <", ((IOService*)$kgm_re)->pwrMgt->Name
7082 showptr $kgm_re
7083 printf ">"
7084 else
7085 printf "?? <"
7086 showptr $kgm_re
7087 printf ">"
7088 end
7089 end
7090
7091 if (((IOService*)$kgm_re)->pwrMgt )
7092 printf " Current Power State: %ld ", ((IOService*)$kgm_re)->pwrMgt->CurrentPowerState
7093 #printf " Mach State %ld", ((IOService*)$kgm_re)->pwrMgt->MachineState
7094 showioservicepm ((IOService*)$kgm_re)->pwrMgt
7095 end
7096 printf "\n"
7097
7098
7099 # recurse
7100 if ($kgm$arg0_child_count != 0)
7101
7102 set $kgm_reg_depth = $kgm_reg_depth + 1
7103 set $kgm$arg0_child_idx = 0
7104
7105 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
7106 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
7107 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
7108 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
7109 loop_break
7110 end
7111 showregistryentryrecursepmstate _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
7112 end
7113
7114 set $kgm_reg_depth = $kgm_reg_depth - 1
7115 end
7116 end
7117
7118 define showregistryentryintpmstate
7119 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
7120 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
7121 showregistryentryrecursepmstate _ $arg0 0 0
7122 end
7123
7124 define showregistrypmstate
7125 # setregistryplane gIOPowerPlane
7126 set $kgm_reg_depth = 0
7127 set $kgm_show_props = 1
7128 showregistryentryintpmstate gRegistryRoot
7129 end
7130
7131 document showregistrypmstate
7132 Syntax: (gdb) showregistrypmstate
7133 | Routine to dump the PM state of each IOPower registry entry
7134 end
7135
7136 define showstacksafterthread
7137 set $kgm_head_taskp = &default_pset.tasks
7138 set $kgm_actp = (struct thread *)$arg0
7139 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
7140 set $kgm_taskp = (struct task *)$kgm_actp->task
7141 while $kgm_taskp != $kgm_head_taskp
7142 showtaskheader
7143 showtaskint $kgm_taskp
7144 set $kgm_head_actp = &($kgm_taskp->threads)
7145 while $kgm_actp != $kgm_head_actp
7146 showactheader
7147 if ($decode_wait_events > 0)
7148 showactint $kgm_actp 1
7149 else
7150 showactint $kgm_actp 2
7151 end
7152 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
7153 end
7154 printf "\n"
7155 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next)
7156 end
7157 end
7158
7159 document showstacksafterthread
7160 Syntax: (gdb) showstacksafterthread <thread>
7161 | Routine to print out all stacks (as in showallstacks) starting after a given thread
7162 | Useful if that gdb refuses to print a certain task's stack.
7163 end
7164
7165 define kdp-reenter
7166 set kdp_reentry_deadline = ((unsigned) $arg0)*1000
7167 continue
7168 end
7169
7170 document kdp-reenter
7171 Syntax: (gdb) kdp-reenter <seconds>
7172 | Schedules reentry into the debugger after <seconds> seconds, and resumes
7173 | the target system.
7174 end
7175
7176 define _if_present
7177 if (!$arg0)
7178 printf " not"
7179 end
7180 printf " present"
7181 end
7182
7183 define showMCAstate
7184 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7185 printf "Not available for current architecture.\n"
7186 else
7187 printf "MCA"
7188 _if_present mca_MCA_present
7189 printf ", control MSR"
7190 _if_present mca_control_MSR_present
7191 printf ", threshold status"
7192 _if_present mca_threshold_status_present
7193 printf "\n%d error banks, ", mca_error_bank_count
7194 printf "family code 0x%x, ", mca_family
7195 printf "machine-check dump state: %d\n", mca_dump_state
7196 set $kgm_cpu = 0
7197 while cpu_data_ptr[$kgm_cpu] != 0
7198 set $kgm_mcp = cpu_data_ptr[$kgm_cpu]->cpu_mca_state
7199 if $kgm_mcp
7200 printf "CPU %d:", $kgm_cpu
7201 printf " mca_mcg_ctl: 0x%016llx", $kgm_mcp->mca_mcg_ctl
7202 printf " mca_mcg_status: 0x%016llx\n", $kgm_mcp->mca_mcg_status.u64
7203 printf "bank "
7204 printf "mca_mci_ctl "
7205 printf "mca_mci_status "
7206 printf "mca_mci_addr "
7207 printf "mca_mci_misc\n"
7208 set $kgm_bank = 0
7209 while $kgm_bank < mca_error_bank_count
7210 set $kgm_bp = &$kgm_mcp->mca_error_bank[$kgm_bank]
7211 printf " %2d:", $kgm_bank
7212 printf " 0x%016llx", $kgm_bp->mca_mci_ctl
7213 printf " 0x%016llx", $kgm_bp->mca_mci_status.u64
7214 printf " 0x%016llx", $kgm_bp->mca_mci_addr
7215 printf " 0x%016llx\n", $kgm_bp->mca_mci_misc
7216 set $kgm_bank = $kgm_bank + 1
7217 end
7218 end
7219 set $kgm_cpu = $kgm_cpu + 1
7220 end
7221 end
7222 end
7223
7224 document showMCAstate
7225 Syntax: showMCAstate
7226 | Print machine-check register state after MC exception.
7227 end
7228
7229 define _pt_step
7230 #
7231 # Step to lower-level page table and print attributes
7232 # $kgm_pt_paddr: current page table entry physical address
7233 # $kgm_pt_index: current page table entry index (0..511)
7234 # returns
7235 # $kgm_pt_paddr: next level page table entry physical address
7236 # or null if invalid
7237 # $kgm_pt_valid: 1 if $kgm_pt_paddr is valid, 0 if the walk
7238 # should be aborted
7239 # $kgm_pt_large: 1 if kgm_pt_paddr is a page frame address
7240 # of a large page and not another page table entry
7241 # For $kgm_pt_verbose = 0: print nothing
7242 # 1: print basic information
7243 # 2: print basic information and hex table dump
7244 #
7245 set $kgm_entryp = $kgm_pt_paddr + 8*$kgm_pt_index
7246 readphysint $kgm_entryp 64 $kgm_lcpu_self
7247 set $entry = $kgm_readphysint_result
7248 if $kgm_pt_verbose == 2
7249 set $kgm_pte_loop = 0
7250 while $kgm_pte_loop < 512
7251 set $kgm_pt_paddr_tmp = $kgm_pt_paddr + $kgm_pte_loop*8
7252 readphys64 $kgm_pt_paddr_tmp
7253 set $kgm_pte_loop = $kgm_pte_loop + 1
7254 end
7255 end
7256 set $kgm_paddr_mask = ~((0xfffULL<<52) | 0xfffULL)
7257 set $kgm_paddr_largemask = ~((0xfffULL<<52) | 0x1fffffULL)
7258 if $kgm_pt_verbose == 0
7259 if $entry & (0x1 << 0)
7260 set $kgm_pt_valid = 1
7261 if $entry & (0x1 << 7)
7262 set $kgm_pt_large = 1
7263 set $kgm_pt_paddr = $entry & $kgm_paddr_largemask
7264 else
7265 set $kgm_pt_large = 0
7266 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
7267 end
7268 else
7269 set $kgm_pt_valid = 0
7270 set $kgm_pt_large = 0
7271 set $kgm_pt_paddr = 0
7272 end
7273 else
7274 printf "0x%016llx:\n\t0x%016llx\n\t", $kgm_entryp, $entry
7275 if $entry & (0x1 << 0)
7276 printf "valid"
7277 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
7278 set $kgm_pt_valid = 1
7279 else
7280 printf "invalid"
7281 set $kgm_pt_paddr = 0
7282 set $kgm_pt_valid = 0
7283 # stop decoding other bits
7284 set $entry = 0
7285 end
7286 if $entry & (0x1 << 1)
7287 printf " writeable"
7288 else
7289 printf " read-only"
7290 end
7291 if $entry & (0x1 << 2)
7292 printf " user"
7293 else
7294 printf " supervisor"
7295 end
7296 if $entry & (0x1 << 3)
7297 printf " PWT"
7298 end
7299 if $entry & (0x1 << 4)
7300 printf " PCD"
7301 end
7302 if $entry & (0x1 << 5)
7303 printf " accessed"
7304 end
7305 if $entry & (0x1 << 6)
7306 printf " dirty"
7307 end
7308 if $entry & (0x1 << 7)
7309 printf " large"
7310 set $kgm_pt_large = 1
7311 else
7312 set $kgm_pt_large = 0
7313 end
7314 if $entry & (0x1 << 8)
7315 printf " global"
7316 end
7317 if $entry & (0x3 << 9)
7318 printf " avail:0x%x", ($entry >> 9) & 0x3
7319 end
7320 if $entry & (0x1 << 63)
7321 printf " noexec"
7322 end
7323 printf "\n"
7324 end
7325 end
7326
7327 define _pmap_walk
7328 set $kgm_pmap = (pmap_t) $arg0
7329 set $kgm_vaddr = $arg1
7330 set $kgm_pt_paddr = $kgm_pmap->pm_cr3
7331 set $kgm_pt_valid = $kgm_pt_paddr != 0
7332 set $kgm_pt_large = 0
7333 set $kgm_pframe_offset = 0
7334 if $kgm_pt_valid && cpu_64bit
7335 # Look up bits 47:39 of the linear address in PML4T
7336 set $kgm_pt_index = ($kgm_vaddr >> 39) & 0x1ffULL
7337 set $kgm_pframe_offset = $kgm_vaddr & 0x7fffffffffULL
7338 if $kgm_pt_verbose
7339 printf "pml4 (index %d):\n", $kgm_pt_index
7340 end
7341 _pt_step
7342 end
7343 if $kgm_pt_valid
7344 # Look up bits 38:30 of the linear address in PDPT
7345 set $kgm_pt_index = ($kgm_vaddr >> 30) & 0x1ffULL
7346 set $kgm_pframe_offset = $kgm_vaddr & 0x3fffffffULL
7347 if $kgm_pt_verbose
7348 printf "pdpt (index %d):\n", $kgm_pt_index
7349 end
7350 _pt_step
7351 end
7352 if $kgm_pt_valid && !$kgm_pt_large
7353 # Look up bits 29:21 of the linear address in PDT
7354 set $kgm_pt_index = ($kgm_vaddr >> 21) & 0x1ffULL
7355 set $kgm_pframe_offset = $kgm_vaddr & 0x1fffffULL
7356 if $kgm_pt_verbose
7357 printf "pdt (index %d):\n", $kgm_pt_index
7358 end
7359 _pt_step
7360 end
7361 if $kgm_pt_valid && !$kgm_pt_large
7362 # Look up bits 20:21 of the linear address in PT
7363 set $kgm_pt_index = ($kgm_vaddr >> 12) & 0x1ffULL
7364 set $kgm_pframe_offset = $kgm_vaddr & 0xfffULL
7365 if $kgm_pt_verbose
7366 printf "pt (index %d):\n", $kgm_pt_index
7367 end
7368 _pt_step
7369 end
7370 if $kgm_pt_valid
7371 set $kgm_paddr = $kgm_pt_paddr + $kgm_pframe_offset
7372 readphysint $kgm_paddr 32 $kgm_lcpu_self
7373 set $kgm_value = $kgm_readphysint_result
7374 printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value
7375 else
7376 set $kgm_paddr = 0
7377 printf "(no translation)\n"
7378 end
7379 end
7380
7381 define pmap_walk
7382 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7383 printf "Not available for current architecture.\n"
7384 else
7385 if $argc != 2
7386 printf "pmap_walk <pmap> <vaddr>\n"
7387 else
7388 if !$kgm_pt_verbose
7389 set $kgm_pt_verbose = 1
7390 else
7391 if $kgm_pt_verbose != 2
7392 set $kgm_pt_verbose = 1
7393 end
7394 end
7395 _pmap_walk $arg0 $arg1
7396 end
7397 end
7398 end
7399
7400 document pmap_walk
7401 Syntax: (gdb) pmap_walk <pmap> <virtual_address>
7402 | Perform a page-table walk in <pmap> for <virtual_address>.
7403 | Set $kgm_pt_verbose=2 for full hex dump of page tables.
7404 end
7405
7406 define pmap_vtop
7407 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
7408 printf "Not available for current architecture.\n"
7409 else
7410 if $argc != 2
7411 printf "pmap_vtop <pamp> <vaddr>\n"
7412 else
7413 set $kgm_pt_verbose = 0
7414 _pmap_walk $arg0 $arg1
7415 end
7416 end
7417 end
7418
7419 document pmap_vtop
7420 Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
7421 | For page-tables in <pmap> translate <virtual_address> to physical address.
7422 end
7423
7424 define zstack
7425 set $index = $arg0
7426
7427 if (log_records == 0)
7428 set $count = 0
7429 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7430 else
7431 if ($argc == 2)
7432 set $count = $arg1
7433 else
7434 set $count = 1
7435 end
7436 end
7437
7438 while ($count)
7439 printf "\n--------------- "
7440
7441 if (zrecords[$index].z_opcode == 1)
7442 printf "ALLOC "
7443 else
7444 printf "FREE "
7445 end
7446
7447 printf " 0x%x : index %d : ztime %d -------------\n", zrecords[$index].z_element, $index, zrecords[$index].z_time
7448
7449 set $frame = 0
7450
7451 while ($frame < 15)
7452 set $frame_pc = zrecords[$index].z_pc[$frame]
7453
7454 if ($frame_pc == 0)
7455 loop_break
7456 end
7457
7458 x/i $frame_pc
7459 set $frame = $frame + 1
7460 end
7461
7462 set $index = $index + 1
7463 set $count = $count - 1
7464 end
7465 end
7466
7467 document zstack
7468 Syntax: (gdb) zstack <index> [<count>]
7469 | Zone leak debugging: print the stack trace of log element at <index>.
7470 | If a <count> is supplied, it prints <count> log elements starting at <index>.
7471 |
7472 | The suggested usage is to look at indexes below zcurrent and look for common stack traces.
7473 | The stack trace that occurs the most is probably the cause of the leak. Find the pc of the
7474 | function calling into zalloc and use the countpcs kgmacro to find out how often that pc occurs in the log.
7475 | The pc occuring in a high percentage of records is most likely the source of the leak.
7476 |
7477 | The findoldest kgmacro is also useful for leak debugging since it identifies the oldest record
7478 | in the log, which may indicate the leaker.
7479 end
7480
7481 define findoldest
7482 set $index = 0
7483 set $count = log_records
7484 set $cur_min = 2000000000
7485 set $cur_index = 0
7486
7487 if (log_records == 0)
7488 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7489 else
7490
7491 while ($count)
7492 if (zrecords[$index].z_element && zrecords[$index].z_time < $cur_min)
7493 set $cur_index = $index
7494 set $cur_min = zrecords[$index].z_time
7495 end
7496
7497 set $count = $count - 1
7498 set $index = $index + 1
7499 end
7500
7501 printf "oldest record is at log index %d:\n", $cur_index
7502 zstack $cur_index
7503 end
7504 end
7505
7506 document findoldest
7507 Syntax: (gdb) findoldest
7508 | Zone leak debugging: find and print the oldest record in the log. Note that this command
7509 | can take several minutes to run since it uses linear search.
7510 |
7511 | Once it prints a stack trace, find the pc of the caller above all the zalloc, kalloc and
7512 | IOKit layers. Then use the countpcs kgmacro to see how often this caller has allocated
7513 | memory. A caller with a high percentage of records in the log is probably the leaker.
7514 end
7515
7516 define countpcs
7517 set $target_pc = $arg0
7518 set $index = 0
7519 set $count = log_records
7520 set $found = 0
7521
7522 if (log_records == 0)
7523 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7524 else
7525
7526 while ($count)
7527 set $frame = 0
7528
7529 if (zrecords[$index].z_element != 0)
7530 while ($frame < 15)
7531 if (zrecords[$index].z_pc[$frame] == $target_pc)
7532 set $found = $found + 1
7533 set $frame = 15
7534 end
7535
7536 set $frame = $frame + 1
7537 end
7538 end
7539
7540 set $index = $index + 1
7541 set $count = $count - 1
7542 end
7543
7544 printf "occurred %d times in log (%d%c of records)\n", $found, ($found * 100) / zrecorded, '%'
7545 end
7546 end
7547
7548 document countpcs
7549 Syntax: (gdb) countpcs <pc>
7550 | Zone leak debugging: search the log and print a count of all log entries that contain the given <pc>
7551 | in the stack trace. This is useful for verifying a suspected <pc> as being the source of
7552 | the leak. If a high percentage of the log entries contain the given <pc>, then it's most
7553 | likely the source of the leak. Note that this command can take several minutes to run.
7554 end
7555
7556 define findelem
7557 set $fe_index = zcurrent
7558 set $fe_count = log_records
7559 set $fe_elem = $arg0
7560 set $fe_prev_op = -1
7561
7562 if (log_records == 0)
7563 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
7564 end
7565
7566 while ($fe_count)
7567 if (zrecords[$fe_index].z_element == $fe_elem)
7568 zstack $fe_index
7569
7570 if (zrecords[$fe_index].z_opcode == $fe_prev_op)
7571 printf "*************** DOUBLE OP! *********************\n
7572 end
7573
7574 set $fe_prev_op = zrecords[$fe_index].z_opcode
7575 end
7576
7577 set $fe_count = $fe_count - 1
7578 set $fe_index = $fe_index + 1
7579
7580 if ($fe_index >= log_records)
7581 set $fe_index = 0
7582 end
7583 end
7584 end
7585
7586 document findelem
7587 Syntax: (gdb) findelem <elem addr>
7588 | Zone corruption debugging: search the log and print out the stack traces for all log entries that
7589 | refer to the given zone element. When the kernel panics due to a corrupted zone element, get the
7590 | element address and use this macro. This will show you the stack traces of all logged zalloc and
7591 | zfree operations which tells you who touched the element in the recent past. This also makes
7592 | double-frees readily apparent.
7593 end
7594
7595
7596 # This implements a shadowing scheme in kgmacros. If the
7597 # current user data can be accessed by simply changing kdp_pmap,
7598 # that is used. Otherwise, we copy data into a temporary buffer
7599 # in the kernel's address space and use that instead. Don't rely on
7600 # kdp_pmap between invocations of map/unmap. Since the shadow
7601 # codepath uses a manual KDP packet, request no more than 128 bytes.
7602 # Uses $kgm_lp64 for kernel address space size
7603 define _map_user_data_from_task
7604 set $kgm_map_user_taskp = (task_t)$arg0
7605 set $kgm_map_user_map = $kgm_map_user_taskp->map
7606 set $kgm_map_user_pmap = $kgm_map_user_map->pmap
7607 set $kgm_map_user_task_64 = ( $kgm_map_user_taskp->taskFeatures[0] & 0x80000000)
7608 set $kgm_map_user_window = 0
7609 set $kgm_map_switch_map = 0
7610
7611 if $kgm_lp64
7612 set $kgm_map_switch_map = 1
7613 else
7614 if !$kgm_map_user_task_64
7615 set $kgm_map_switch_map = 1
7616 end
7617 end
7618
7619 if ($kgm_map_switch_map)
7620 # switch the map safely
7621 set $kgm_map_user_window = $arg1
7622 set kdp_pmap = $kgm_map_user_pmap
7623 else
7624 # requires shadowing/copying
7625
7626 # set up the manual KDP packet
7627 set manual_pkt.input = 0
7628 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
7629 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
7630 set $kgm_pkt->hdr.request = KDP_READMEM64
7631 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
7632 set $kgm_pkt->hdr.is_reply = 0
7633 set $kgm_pkt->hdr.seq = 0
7634 set $kgm_pkt->hdr.key = 0
7635 set $kgm_pkt->address = (uint64_t)$arg1
7636 set $kgm_pkt->nbytes = (uint32_t)$arg2
7637
7638 set kdp_pmap = $kgm_map_user_pmap
7639 set manual_pkt.input = 1
7640 # dummy to make sure manual packet is executed
7641 set $kgm_dummy = &_mh_execute_header
7642 # Go back to kernel map so that we can access buffer directly
7643 set kdp_pmap = 0
7644
7645 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
7646 if ($kgm_pkt->error == 0)
7647 set $kgm_map_user_window = $kgm_pkt->data
7648 else
7649 set $kgm_map_user_window = 0
7650 end
7651
7652 end
7653 end
7654
7655 define _unmap_user_data_from_task
7656 set kdp_pmap = 0
7657 end
7658
7659 # uses $kgm_taskp. Maps 32 bytes at a time and prints it
7660 define _print_path_for_image
7661 set $kgm_print_path_address = (unsigned long long)$arg0
7662 set $kgm_path_str_notdone = 1
7663
7664 while $kgm_path_str_notdone
7665 _map_user_data_from_task $kgm_taskp $kgm_print_path_address 32
7666
7667 set $kgm_print_path_ptr = (char *)$kgm_map_user_window
7668 set $kgm_path_i = 0
7669 while ($kgm_path_i < 32 && $kgm_print_path_ptr[$kgm_path_i] != '\0')
7670 set $kgm_path_i = $kgm_path_i + 1
7671 end
7672 printf "%.32s", $kgm_print_path_ptr
7673
7674 _unmap_user_data_from_task $kgm_taskp
7675
7676 # if we terminated on NUL, break out
7677 if $kgm_path_i < 32
7678 set $kgm_path_str_notdone = 0
7679 else
7680 set $kgm_print_path_address = $kgm_print_path_address + 32
7681 end
7682 end
7683 end
7684
7685 # uses $kgm_taskp and $kgm_task_64
7686 define _print_image_info
7687 set $kgm_mh_image_address = (unsigned long long)$arg0
7688 set $kgm_mh_path_address = (unsigned long long)$arg1
7689
7690 # 32 bytes enough for mach_header/mach_header_64
7691 _map_user_data_from_task $kgm_taskp $kgm_mh_image_address 32
7692
7693 set $kgm_mh_ptr = (unsigned int*)$kgm_map_user_window
7694 set $kgm_mh_magic = $kgm_mh_ptr[0]
7695 set $kgm_mh_cputype = $kgm_mh_ptr[1]
7696 set $kgm_mh_cpusubtype = $kgm_mh_ptr[2]
7697 set $kgm_mh_filetype = $kgm_mh_ptr[3]
7698 set $kgm_mh_ncmds = $kgm_mh_ptr[4]
7699 set $kgm_mh_sizeofcmds = $kgm_mh_ptr[5]
7700 set $kgm_mh_flags = $kgm_mh_ptr[6]
7701
7702 _unmap_user_data_from_task $kgm_taskp
7703
7704 if $kgm_mh_magic == 0xfeedfacf
7705 set $kgm_mh_64 = 1
7706 set $kgm_lc_address = $kgm_mh_image_address + 32
7707 else
7708 set $kgm_mh_64 = 0
7709 set $kgm_lc_address = $kgm_mh_image_address + 28
7710 end
7711
7712 set $kgm_lc_idx = 0
7713 set $kgm_uuid_data = 0
7714 while $kgm_lc_idx < $kgm_mh_ncmds
7715
7716 # 24 bytes is size of uuid_command
7717 _map_user_data_from_task $kgm_taskp $kgm_lc_address 24
7718
7719 set $kgm_lc_ptr = (unsigned int *)$kgm_map_user_window
7720 set $kgm_lc_cmd = $kgm_lc_ptr[0]
7721 set $kgm_lc_cmd_size = $kgm_lc_ptr[1]
7722 set $kgm_lc_data = (unsigned char *)$kgm_lc_ptr + 8
7723
7724 if $kgm_lc_cmd == 0x1b
7725 set $kgm_uuid_data = $kgm_lc_data
7726 if $kgm_mh_64
7727 printf "0x%016llx ", $kgm_mh_image_address
7728 else
7729 printf "0x%08x ", $kgm_mh_image_address
7730 end
7731
7732 set $kgm_printed_type = 0
7733 if $kgm_mh_filetype == 0x2
7734 printf "MH_EXECUTE "
7735 set $kgm_printed_type = 1
7736 end
7737 if $kgm_mh_filetype == 0x6
7738 printf "MH_DYLIB "
7739 set $kgm_printed_type = 1
7740 end
7741 if $kgm_mh_filetype == 0x7
7742 printf "MH_DYLINKER "
7743 set $kgm_printed_type = 1
7744 end
7745 if $kgm_mh_filetype == 0x8
7746 printf "MH_BUNDLE "
7747 set $kgm_printed_type = 1
7748 end
7749 if !$kgm_printed_type
7750 printf "UNKNOWN "
7751 end
7752 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]
7753 printf "%02.2X%02.2X-", $kgm_uuid_data[4], $kgm_uuid_data[5]
7754 printf "%02.2X%02.2X-", $kgm_uuid_data[6], $kgm_uuid_data[7]
7755 printf "%02.2X%02.2X-", $kgm_uuid_data[8], $kgm_uuid_data[9]
7756 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]
7757
7758 _unmap_user_data_from_task $kgm_taskp
7759
7760 printf " "
7761 _print_path_for_image $kgm_mh_path_address
7762 printf "\n"
7763
7764 loop_break
7765 else
7766 _unmap_user_data_from_task $kgm_taskp
7767 end
7768
7769 set $kgm_lc_address = $kgm_lc_address + $kgm_lc_cmd_size
7770 set $kgm_lc_idx = $kgm_lc_idx + 1
7771 end
7772
7773 if (!$kgm_uuid_data)
7774 # didn't find LC_UUID, for a dylib, just print out basic info
7775 if $kgm_mh_64
7776 printf "0x%016llx ", $kgm_mh_image_address
7777 else
7778 printf "0x%08x ", $kgm_mh_image_address
7779 end
7780 set $kgm_printed_type = 0
7781 if $kgm_mh_filetype == 0x2
7782 printf "MH_EXECUTE "
7783 set $kgm_printed_type = 1
7784 end
7785 if $kgm_mh_filetype == 0x6
7786 printf "MH_DYLIB "
7787 set $kgm_printed_type = 1
7788 end
7789 if $kgm_mh_filetype == 0x7
7790 printf "MH_DYLINKER "
7791 set $kgm_printed_type = 1
7792 end
7793 if $kgm_mh_filetype == 0x8
7794 printf "MH_BUNDLE "
7795 set $kgm_printed_type = 1
7796 end
7797 if !$kgm_printed_type
7798 printf "UNKNOWN "
7799 end
7800 printf " ",
7801
7802 printf " "
7803 _print_path_for_image $kgm_mh_path_address
7804 printf "\n"
7805
7806 end
7807
7808 end
7809
7810 define _print_images_for_dyld_image_info
7811 set $kgm_taskp = $arg0
7812 set $kgm_task_64 = $arg1
7813 set $kgm_dyld_all_image_infos_address = (unsigned long long)$arg2
7814
7815 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 16
7816
7817 set $kgm_dyld_all_image_infos = (unsigned int *)$kgm_map_user_window
7818 if ($kgm_dyld_all_image_infos[0] != 6)
7819 printf "Invalid version number %d\n", $kgm_dyld_all_image_infos[0]
7820 end
7821 set $kgm_image_info_count = $kgm_dyld_all_image_infos[1]
7822
7823 if $kgm_task_64
7824 set $kgm_image_info_size = 24
7825 set $kgm_image_info_array_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[1]
7826 else
7827 set $kgm_image_info_size = 12
7828 set $kgm_image_info_array_address = ((unsigned int *)$kgm_dyld_all_image_infos)[2]
7829 end
7830
7831 _unmap_user_data_from_task $kgm_taskp
7832
7833 set $kgm_image_info_i = 0
7834 while $kgm_image_info_i < $kgm_image_info_count
7835
7836 set $kgm_image_info_address = $kgm_image_info_array_address + $kgm_image_info_size*$kgm_image_info_i
7837
7838 _map_user_data_from_task $kgm_taskp $kgm_image_info_address $kgm_image_info_size
7839 if $kgm_task_64
7840 set $kgm_image_info_addr = ((unsigned long long *)$kgm_map_user_window)[0]
7841 set $kgm_image_info_path = ((unsigned long long *)$kgm_map_user_window)[1]
7842 else
7843 set $kgm_image_info_addr = ((unsigned int *)$kgm_map_user_window)[0]
7844 set $kgm_image_info_path = ((unsigned int *)$kgm_map_user_window)[1]
7845 end
7846 _unmap_user_data_from_task $kgm_taskp
7847
7848 # printf "[%d] = image address %llx path address %llx\n", $kgm_image_info_i, $kgm_image_info_addr, $kgm_image_info_path
7849 _print_image_info $kgm_image_info_addr $kgm_image_info_path
7850
7851 set $kgm_image_info_i = $kgm_image_info_i + 1
7852 end
7853 end
7854
7855 define showuserlibraries
7856 set $kgm_taskp = (task_t)$arg0
7857 set $kgm_dyld_image_info = $kgm_taskp->all_image_info_addr
7858
7859 set $kgm_map = $kgm_taskp->map
7860 set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
7861
7862 if ($kgm_dyld_image_info != 0)
7863 printf "address "
7864 if $kgm_task_64
7865 printf " "
7866 end
7867 printf " type "
7868 printf " uuid "
7869 printf "path\n"
7870
7871 _print_images_for_dyld_image_info $kgm_taskp $kgm_task_64 $kgm_dyld_image_info
7872 else
7873 printf "No dyld shared library information available for task\n"
7874 end
7875 end
7876 document showuserlibraries
7877 Syntax: (gdb) showuserlibraries <task_t>
7878 | For a given user task, inspect the dyld shared library state and print
7879 | information about all Mach-O images.
7880 end
7881
7882 define showkerneldebugheader
7883 printf "kd_buf "
7884 showptrhdrpad
7885 printf "CPU Thread "
7886 showptrhdrpad
7887 printf "Timestamp S/E Class Sub Code Code Specific Info\n"
7888 end
7889
7890 define _printevflags
7891 if $arg0 & 1
7892 printf "EV_RE "
7893 end
7894 if $arg0 & 2
7895 printf "EV_WR "
7896 end
7897 if $arg0 & 4
7898 printf "EV_EX "
7899 end
7900 if $arg0 & 8
7901 printf "EV_RM "
7902 end
7903
7904 if $arg0 & 0x00100
7905 printf "EV_RBYTES "
7906 end
7907 if $arg0 & 0x00200
7908 printf "EV_WBYTES "
7909 end
7910 if $arg0 & 0x00400
7911 printf "EV_RCLOSED "
7912 end
7913 if $arg0 & 0x00800
7914 printf "EV_RCONN "
7915 end
7916 if $arg0 & 0x01000
7917 printf "EV_WCLOSED "
7918 end
7919 if $arg0 & 0x02000
7920 printf "EV_WCONN "
7921 end
7922 if $arg0 & 0x04000
7923 printf "EV_OOB "
7924 end
7925 if $arg0 & 0x08000
7926 printf "EV_FIN "
7927 end
7928 if $arg0 & 0x10000
7929 printf "EV_RESET "
7930 end
7931 if $arg0 & 0x20000
7932 printf "EV_TIMEOUT "
7933 end
7934 end
7935
7936 define showkerneldebugbufferentry
7937 set $kgm_kdebug_entry = (kd_buf *) $arg0
7938
7939 set $kgm_debugid = $kgm_kdebug_entry->debugid
7940 set $kgm_kdebug_arg1 = $kgm_kdebug_entry->arg1
7941 set $kgm_kdebug_arg2 = $kgm_kdebug_entry->arg2
7942 set $kgm_kdebug_arg3 = $kgm_kdebug_entry->arg3
7943 set $kgm_kdebug_arg4 = $kgm_kdebug_entry->arg4
7944
7945 if $kgm_lp64
7946 set $kgm_kdebug_cpu = $kgm_kdebug_entry->cpuid
7947 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0xFFFFFFFF
7948 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
7949 else
7950 set $kgm_kdebug_cpu = ($kgm_kdebug_entry->timestamp >> 56)
7951 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0x00FFFFFF
7952 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
7953 end
7954
7955 set $kgm_kdebug_class = ($kgm_debugid >> 24) & 0x000FF
7956 set $kgm_kdebug_subclass = ($kgm_debugid >> 16) & 0x000FF
7957 set $kgm_kdebug_code = ($kgm_debugid >> 2) & 0x03FFF
7958 set $kgm_kdebug_qual = ($kgm_debugid ) & 0x00003
7959
7960 if $kgm_kdebug_qual == 0
7961 set $kgm_kdebug_qual = '-'
7962 else
7963 if $kgm_kdebug_qual == 1
7964 set $kgm_kdebug_qual = 'S'
7965 else
7966 if $kgm_kdebug_qual == 2
7967 set $kgm_kdebug_qual = 'E'
7968 else
7969 if $kgm_kdebug_qual == 3
7970 set $kgm_kdebug_qual = '?'
7971 end
7972 end
7973 end
7974 end
7975
7976 # preamble and qual
7977
7978 showptr $kgm_kdebug_entry
7979 printf " %d ", $kgm_kdebug_cpu
7980 showptr $kgm_kdebug_entry->arg5
7981 printf " 0x%08X%08X %c ", $kgm_ts_hi, $kgm_ts_lo, $kgm_kdebug_qual
7982
7983 # class
7984
7985 if $kgm_kdebug_class == 1
7986 printf "MACH"
7987 else
7988 if $kgm_kdebug_class == 2
7989 printf "NET "
7990 else
7991 if $kgm_kdebug_class == 3
7992 printf "FS "
7993 else
7994 if $kgm_kdebug_class == 4
7995 printf "BSD "
7996 else
7997 if $kgm_kdebug_class == 5
7998 printf "IOK "
7999 else
8000 if $kgm_kdebug_class == 6
8001 printf "DRVR"
8002 else
8003 if $kgm_kdebug_class == 7
8004 printf "TRAC"
8005 else
8006 if $kgm_kdebug_class == 8
8007 printf "DLIL"
8008 else
8009 if $kgm_kdebug_class == 8
8010 printf "SEC "
8011 else
8012 if $kgm_kdebug_class == 20
8013 printf "MISC"
8014 else
8015 if $kgm_kdebug_class == 31
8016 printf "DYLD"
8017 else
8018 if $kgm_kdebug_class == 32
8019 printf "QT "
8020 else
8021 if $kgm_kdebug_class == 33
8022 printf "APPS"
8023 else
8024 if $kgm_kdebug_class == 255
8025 printf "MIG "
8026 else
8027 printf "0x%02X", $kgm_kdebug_class
8028 end
8029 end
8030 end
8031 end
8032 end
8033 end
8034 end
8035 end
8036 end
8037 end
8038 end
8039 end
8040 end
8041 end
8042
8043 # subclass and code
8044
8045 printf " 0x%02X %5d ", $kgm_kdebug_subclass, $kgm_kdebug_code
8046
8047 # space for debugid-specific processing
8048
8049 # EVPROC from bsd/kern/sys_generic.c
8050
8051 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT)
8052 if $kgm_debugid == 0x14100048
8053 printf "waitevent "
8054 if $kgm_kdebug_arg1 == 1
8055 printf "before sleep"
8056 else
8057 if $kgm_kdebug_arg1 == 2
8058 printf "after sleep"
8059 else
8060 printf "????????????"
8061 end
8062 end
8063 printf " chan=0x%08X ", $kgm_kdebug_arg2
8064 else
8065 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_START)
8066 if $kgm_debugid == 0x14100049
8067 printf "waitevent "
8068 else
8069 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_END)
8070 if $kgm_debugid == 0x1410004a
8071 printf "waitevent error=%d ", $kgm_kdebug_arg1
8072 printf "eqp=0x%08X ", $kgm_kdebug_arg4
8073 _printevflags $kgm_kdebug_arg3
8074 printf "er_handle=%d ", $kgm_kdebug_arg2
8075 else
8076 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_START)
8077 if $kgm_debugid == 0x14100059
8078 printf "evprocdeque proc=0x%08X ", $kgm_kdebug_arg1
8079 if $kgm_kdebug_arg2 == 0
8080 printf "remove first "
8081 else
8082 printf "remove 0x%08X ", $kgm_kdebug_arg2
8083 end
8084 else
8085 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_END)
8086 if $kgm_debugid == 0x1410005a
8087 printf "evprocdeque "
8088 if $kgm_kdebug_arg1 == 0
8089 printf "result=NULL "
8090 else
8091 printf "result=0x%08X ", $kgm_kdebug_arg1
8092 end
8093 else
8094 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_START)
8095 if $kgm_debugid == 0x14100041
8096 printf "postevent "
8097 _printevflags $kgm_kdebug_arg1
8098 else
8099 # MISCDBG_CODE(DBG_EVENT,DBG_POST)
8100 if $kgm_debugid == 0x14100040
8101 printf "postevent "
8102 printf "evq=0x%08X ", $kgm_kdebug_arg1
8103 printf "er_eventbits="
8104 _printevflags $kgm_kdebug_arg2
8105 printf "mask="
8106 _printevflags $kgm_kdebug_arg3
8107 else
8108 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_END)
8109 if $kgm_debugid == 0x14100042
8110 printf "postevent "
8111 else
8112 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_START)
8113 if $kgm_debugid == 0x14100055
8114 printf "evprocenque eqp=0x%08d ", $kgm_kdebug_arg1
8115 if $kgm_kdebug_arg2 & 1
8116 printf "EV_QUEUED "
8117 end
8118 _printevflags $kgm_kdebug_arg3
8119 else
8120
8121 # MISCDBG_CODE(DBG_EVENT,DBG_EWAKEUP)
8122 if $kgm_debugid == 0x14100050
8123 printf "evprocenque before wakeup eqp=0x%08d ", $kgm_kdebug_arg4
8124 else
8125 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_END)
8126 if $kgm_debugid == 0x14100056
8127 printf "evprocenque "
8128 else
8129 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_START)
8130 if $kgm_debugid == 0x1410004d
8131 printf "modwatch "
8132 else
8133 # MISCDBG_CODE(DBG_EVENT,DBG_MOD)
8134 if $kgm_debugid == 0x1410004c
8135 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
8136 _printevflags $kgm_kdebug_arg2
8137 printf "evq=0x%08X ", $kgm_kdebug_arg3
8138 else
8139 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_END)
8140 if $kgm_debugid == 0x1410004e
8141 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
8142 printf "ee_eventmask="
8143 _printevflags $kgm_kdebug_arg2
8144 printf "sp=0x%08X ", $kgm_kdebug_arg3
8145 printf "flag="
8146 _printevflags $kgm_kdebug_arg4
8147 else
8148 printf "arg1=0x%08X ", $kgm_kdebug_arg1
8149 printf "arg2=0x%08X ", $kgm_kdebug_arg2
8150 printf "arg3=0x%08X ", $kgm_kdebug_arg3
8151 printf "arg4=0x%08X ", $kgm_kdebug_arg4
8152 end
8153 end
8154 end
8155 end
8156 end
8157 end
8158 end
8159 end
8160 end
8161 end
8162 end
8163 end
8164 end
8165 end
8166
8167 # finish up
8168
8169 printf "\n"
8170 end
8171
8172 define showkerneldebugbuffercpu
8173 set $kgm_cpu_number = (int) $arg0
8174 set $kgm_entry_count = (int) $arg1
8175 set $kgm_debugentriesfound = 0
8176
8177 #if kdebug_flags & KDBG_BFINIT
8178 if (kdebug_flags & 0x80000000)
8179 showkerneldebugheader
8180
8181 if $kgm_entry_count == 0
8182 printf "<count> is 0, dumping 50 entries\n"
8183 set $kgm_entry_count = 50
8184 end
8185
8186 if $kgm_cpu_number >= kd_cpus
8187 printf "cpu number too big\n"
8188 else
8189 set $kgm_kdbp = &kdbip[$kgm_cpu_number]
8190 set $kgm_kdsp = $kgm_kdbp->kd_list_head
8191 while (($kgm_kdsp != 0) && ($kgm_entry_count > 0))
8192 if $kgm_kdsp->kds_readlast != $kgm_kdsp->kds_bufptr
8193 set $kgm_kds_bufptr = $kgm_kdsp->kds_bufptr
8194 while (($kgm_kds_bufptr > $kgm_kdsp->kds_readlast) && ($kgm_entry_count > 0))
8195 set $kgm_kds_bufptr = $kgm_kds_bufptr - 1
8196 set $kgm_entry_count = $kgm_entry_count - 1
8197 showkerneldebugbufferentry $kgm_kds_bufptr
8198 end
8199 end
8200 set $kgm_kdsp = $kgm_kdsp->kds_next
8201 end
8202 end
8203 else
8204 printf "Trace buffer not enabled\n"
8205 end
8206 end
8207
8208 document showkerneldebugbuffercpu
8209 Syntax: showkerneldebugbuffercpu <cpu> <count>
8210 | Prints the last N entries in the kernel debug buffer for CPU x.
8211 end
8212
8213 define showkerneldebugbuffer
8214
8215 #if kdebug_flags & KDBG_BFINIT
8216 if (kdebug_flags & 0x80000000)
8217
8218 set $kgm_entrycount = (int) $arg0
8219
8220 if $kgm_entrycount == 0
8221 printf "<count> is 0, dumping 50 entries per cpu\n"
8222 set $kgm_entrycount = 50
8223 end
8224
8225 set $kgm_cpu = (int) 0
8226
8227 while $kgm_cpu < kd_cpus
8228 showkerneldebugbuffercpu $kgm_cpu $kgm_entrycount
8229 set $kgm_cpu = $kgm_cpu + 1
8230 end
8231 else
8232 printf "Trace buffer not enabled\n"
8233 end
8234 end
8235
8236 document showkerneldebugbuffer
8237 Syntax: showkerneldebugbuffer <count>
8238 | Prints the last N entries in the kernel debug buffer per cpu. i.e. showkerneldebugbuffer 50 will
8239 | display the last 50 entries in each CPU's debug buffer.
8240 end
8241
8242 define showallvmstats
8243 printf " pid command #ents wired vsize rsize max rsize\n"
8244 printf " (pages) (pages) (pages) (pages)\n"
8245 set $kgm_head_taskp = &tasks
8246 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
8247 while $kgm_taskp != $kgm_head_taskp
8248 set $kgm_procp = (struct proc *)($kgm_taskp->bsd_info)
8249 set $kgm_mapp = (struct _vm_map *)($kgm_taskp->map)
8250 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
8251 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
8252 end
8253 end
8254
8255 document showallvmstats
8256 Syntax: showallvmstats
8257 | prints a summary of vm statistics in a table format
8258 end
8259
8260 define show_user_registers
8261 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
8262 set $kgm_thread = (thread_t)$arg0
8263 if ((*(thread_t)$kgm_thread)->machine.xxx_pcb.iss.flavor == 15)
8264 p/x ($kgm_thread)->machine.xxx_pcb.iss->uss.ss_64
8265 else
8266 p/x ($kgm_thread)->machine.xxx_pcb.iss->uss.ss_32
8267 end
8268 end
8269 if ($kgm_mtype == $kgm_mtype_ppc)
8270 set $kgm_thread = (thread_t)$arg0
8271 p/x *($kgm_thread)->machine.pcb
8272 end
8273 end
8274
8275 document show_user_registers
8276 Syntax: show_user_registers <thread_address>
8277 | Display user registers associated with a kernel thread
8278 | properly displays the 32 bit or 64 bit registers for intel architecture
8279 end
8280
8281 define _cmp
8282 set $cmp0 = $arg0
8283 set $cmp1 = $arg1
8284
8285 # check for end of string. cmp0 can be longer than cmp1. it
8286 # can't be shorter.
8287 if $cmp1 == '\0'
8288 set $kgm_strcmp_result = 0
8289 set $kgm_strcmp_done = 1
8290 end
8291
8292 if !$kgm_strcmp_done && $cmp0 == '\0'
8293 set $kgm_strcmp_result = -1
8294 set $kgm_strcmp_done = 1
8295 end
8296
8297 # do they match?
8298 if !$kgm_strcmp_done
8299 set $kgm_strcmp_result = (uint8_t) $cmp0 - (uint8_t) $cmp1
8300 if $kgm_strcmp_result != 0
8301 set $kgm_strcmp_done = 1
8302 end
8303 end
8304 end
8305
8306 define _cmp_arg64
8307 set $cmp = $arg1
8308 set $masked = $cmp & 0xFF
8309 _cmp $arg0[0] $masked
8310
8311 if !$kgm_strcmp_done
8312 set $cmp = $cmp >> 8
8313 set $masked = $cmp & 0xFF
8314 _cmp $arg0[1] $masked
8315 end
8316 if !$kgm_strcmp_done
8317 set $cmp = $cmp >> 8
8318 set $masked = $cmp & 0xFF
8319 _cmp $arg0[2] $masked
8320 end
8321 if !$kgm_strcmp_done
8322 set $cmp = $cmp >> 8
8323 set $masked = $cmp & 0xFF
8324 _cmp $arg0[3] $masked
8325 end
8326 if !$kgm_strcmp_done
8327 set $cmp = $cmp >> 8
8328 set $masked = $cmp & 0xFF
8329 _cmp $arg0[4] $masked
8330 end
8331 if !$kgm_strcmp_done
8332 set $cmp = $cmp >> 8
8333 set $masked = $cmp & 0xFF
8334 _cmp $arg0[5] $masked
8335 end
8336 if !$kgm_strcmp_done
8337 set $cmp = $cmp >> 8
8338 set $masked = $cmp & 0xFF
8339 _cmp $arg0[6] $masked
8340 end
8341 if !$kgm_strcmp_done
8342 set $cmp = $cmp >> 8
8343 set $masked = $cmp & 0xFF
8344 _cmp $arg0[7] $masked
8345 end
8346 end
8347
8348 define strcmp_arg_pack64
8349 set $kgm_strcmp_arg = ((((((((((((((uint64_t) $arg7 << 8) | $arg6) << 8) | $arg5) << 8) | $arg4) << 8) | $arg3) << 8) | $arg2) << 8) | $arg1) << 8) | $arg0
8350 end
8351
8352 document strcmp_arg_pack64
8353 Syntax: strcmp_arg_pack64 <a> <b> <c> <d> <e <f> <g> <h>
8354 | Packs a string given as 8 character arguments into a 64-bit int stored in
8355 | $kgm_strcmp_arg. Use 0 or '\0' for unused arguments. The encoded string
8356 | is suitable for use by strcmp_nomalloc and setfindregistrystr.
8357 | e.g., strcmp_arg_pack64 'H' 'e' 'l' 'l' 'o' 0 0 0
8358 | packs "Hello" into $kgm_strcmp_arg.
8359 |
8360 end
8361
8362 define strcmp_nomalloc
8363 set $str = $arg0
8364 set $count = $argc - 1
8365
8366 set $kgm_strcmp_result = 0
8367 set $kgm_strcmp_done = 0
8368
8369 if $count > 0
8370 _cmp_arg64 $str $arg1
8371 end
8372 if !$kgm_strcmp_done && $count > 1
8373 set $str = $str + 8
8374 _cmp_arg64 $str $arg2
8375 end
8376 if !$kgm_strcmp_done && $count > 2
8377 set $str = $str + 8
8378 _cmp_arg64 $str $arg3
8379 end
8380 if !$kgm_strcmp_done && $count > 3
8381 set $str = $str + 8
8382 _cmp_arg64 $str $arg4
8383 end
8384 if !$kgm_strcmp_done && $count > 4
8385 set $str = $str + 8
8386 _cmp_arg64 $str $arg5
8387 end
8388 if !$kgm_strcmp_done && $count > 5
8389 set $str = $str + 8
8390 _cmp_arg64 $str $arg6
8391 end
8392 if !$kgm_strcmp_done && $count > 6
8393 set $str = $str + 8
8394 _cmp_arg64 $str $arg7
8395 end
8396 if !$kgm_strcmp_done && $count > 7
8397 set $str = $str + 8
8398 _cmp_arg64 $str $arg8
8399 end
8400 if !$kgm_strcmp_done && $count > 8
8401 set $str = $str + 8
8402 _cmp_arg64 $str $arg9
8403 end
8404 end
8405
8406 document strcmp_nomalloc
8407 Syntax: strcmp_nomalloc <string> <a> [b] [c] [d] [e] [f] [g] [h] [i]
8408 | Given a pre-allocated <string>, perform a string compare with the
8409 | encoded string stored in arguments a - i. The result is stored in
8410 | $kgm_strcmp_result.
8411 |
8412 | For example, the following will result in $kgm_strcmp_result == 0:
8413 | strcmp_arg_pack64 'D' 'a' 'r' 'w' 'i' 'n' ' ' 'K'
8414 | strcmp_nomalloc version $kgm_strcmp_arg
8415 end
8416
8417 # _pci_cfg_addr_value $addr $size
8418 define _pci_cfg_addr_value
8419 readphysint $arg0 $arg1 $kgm_lcpu_self
8420 set $kgm_pci_cfg_value = $kgm_readphysint_result
8421 end
8422
8423
8424 set $kgm_pci_cfg_init = 0
8425 define _pci_cfg_init
8426 # get this from the registry if it exists there
8427 if $kgm_pci_cfg_init == 0
8428 strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
8429 set $AppleACP = $kgm_strcmp_arg
8430 strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
8431 set $IPlatfor = $kgm_strcmp_arg
8432 strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
8433 set $mExpert = $kgm_strcmp_arg
8434 setfindregistrystr $AppleACP $IPlatfor $mExpert
8435
8436 set $olddepth = $kgm_reg_depth_max
8437 set $kgm_reg_depth_max = 2
8438 _findregistryentry
8439 set $kgm_reg_depth_max = $olddepth
8440
8441 if $kgm_registry_entry
8442 strcmp_arg_pack64 'a' 'c' 'p' 'i' '-' 'm' 'm' 'c'
8443 set $acpi_mmc = $kgm_strcmp_arg
8444 strcmp_arg_pack64 'f' 'g' '-' 's' 'e' 'g' '0' 0
8445 set $fg_seg0 = $kgm_strcmp_arg
8446 setfindregistrystr $acpi_mmc $fg_seg0
8447
8448 _findregistryprop $kgm_registry_entry
8449 if $kgm_registry_value
8450 set $kgm_pci_cfg_base = ((OSNumber *) $kgm_registry_value)->value
8451 set $kgm_pci_cfg_init = 1
8452 end
8453 end
8454 end
8455
8456 # if the above fails, search for 0:0:0 in likely places.
8457 if $kgm_pci_cfg_init == 0
8458 set $kgm_pci_cfg_base = 0xF0000000
8459 while $kgm_pci_cfg_init == 0 && $kgm_pci_cfg_base > 0xA0000000
8460 _pci_cfg_addr_value $kgm_pci_cfg_base 8
8461 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xFF
8462 set $kgm_pci_cfg_init = 1
8463 else
8464 set $kgm_pci_cfg_base = $kgm_pci_cfg_base - 0x10000000
8465 end
8466 end
8467 end
8468 end
8469
8470 # _pci_cfg_addr $bus $dev $fcn $off
8471 define _pci_cfg_addr
8472 set $bus = $arg0
8473 set $dev = $arg1
8474 set $fcn = $arg2
8475 set $off = $arg3
8476
8477 _pci_cfg_init
8478 set $kgm_pci_cfg_addr = $kgm_pci_cfg_base | ($bus << 20) | ($dev << 15) | ($fcn << 12) | $off
8479 end
8480
8481 define _pci_cfg_value
8482 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8483 _pci_cfg_addr_value $kgm_pci_cfg_addr $arg4
8484 end
8485
8486 define pci_cfg_read8
8487 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 8
8488 printf "%08X: %02X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8489 end
8490
8491 define pci_cfg_read16
8492 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 16
8493 printf "%08X: %04X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8494 end
8495
8496 define pci_cfg_read32
8497 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 32
8498 printf "%08X: %08X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
8499 end
8500
8501 document pci_cfg_read8
8502 Syntax: (gdb) pci_cfg_read8 <bus> <dev> <fcn> <off>
8503 | read 8 bits for the given <off> of the pci device located at
8504 | <bus>:<dev>:<fcn>.
8505 end
8506
8507 document pci_cfg_read16
8508 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
8509 | read 16 bits for the given <off> of the pci device located at
8510 | <bus>:<dev>:<fcn>.
8511 end
8512
8513 document pci_cfg_read32
8514 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
8515 | read 32 bits for the given <off> of the pci device located at
8516 | <bus>:<dev>:<fcn>.
8517 end
8518
8519 define pci_cfg_write8
8520 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8521 writephysint $kgm_pci_cfg_addr 8 $arg4 $kgm_lcpu_self
8522 end
8523
8524 define pci_cfg_write16
8525 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8526 writephysint $kgm_pci_cfg_addr 16 $arg4 $kgm_lcpu_self
8527 end
8528
8529 define pci_cfg_write32
8530 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
8531 writephysint $kgm_pci_cfg_addr 32 $arg4 $kgm_lcpu_self
8532 end
8533
8534 document pci_cfg_write8
8535 Syntax: (gdb) pci_cfg_write8 <bus> <dev> <fcn> <off> <value>
8536 | write an 8-bit <value> into the given <off> of the pci device located at
8537 | <bus>:<dev>:<fcn>.
8538 end
8539
8540 document pci_cfg_write16
8541 Syntax: (gdb) pci_cfg_write16 <bus> <dev> <fcn> <off> <value>
8542 | write a 16-bit <value> into the given <off> of the pci device located at
8543 | <bus>:<dev>:<fcn>.
8544 end
8545
8546 document pci_cfg_write32
8547 Syntax: (gdb) pci_cfg_write32 <bus> <dev> <fcn> <off> <value>
8548 | write a 32-bit <value> into the given <off> of the pci device located at
8549 | <bus>:<dev>:<fcn>.
8550 end
8551
8552
8553 define pci_cfg_dump
8554 set $bus = $arg0
8555 set $dev = $arg1
8556 set $fcn = $arg2
8557 set $off = 0
8558
8559 # check for a valid pci device
8560 _pci_cfg_value $bus $dev $fcn $off 8
8561 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xff
8562 printf " address: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
8563 printf "---------------------------------------------------------"
8564
8565 while $off < 256
8566 _pci_cfg_value $bus $dev $fcn $off 32
8567 if ($off & 0xF) == 0
8568 printf "\n%08X: ", $kgm_pci_cfg_addr
8569 end
8570 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
8571 set $off = $off + 4
8572 end
8573 printf "\n"
8574
8575 # check for pcie extended capability config space
8576 _pci_cfg_value $bus $dev $fcn $off 8
8577 if $kgm_pci_cfg_value < 0xff
8578 while $off < 4096
8579 _pci_cfg_value $bus $dev $fcn $off 32
8580 if ($off & 0xF) == 0
8581 printf "\n%08X: ", $kgm_pci_cfg_addr
8582 end
8583 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
8584 set $off = $off + 4
8585 end
8586 printf "\n"
8587 end
8588 end
8589 end
8590
8591 document pci_cfg_dump
8592 Syntax: (gdb) pci_cfg_dump <bus> <dev> <fcn>
8593 | dump config space for the pci device located at <bus>:<dev>:<fcn>
8594 | if you specify an invalid/inaccessible pci device, nothing will be
8595 | printed out.
8596 end
8597
8598 set $kgm_pci_cfg_bus_start = 0
8599 set $kgm_pci_cfg_bus_max = 8
8600 set $kgm_pci_cfg_device_max = 32
8601 set $kgm_pci_cfg_function_max = 8
8602 define _pci_cfg_scan
8603 set $dump = $arg0
8604
8605 set $bus = $kgm_pci_cfg_bus_start
8606 while $bus < $kgm_pci_cfg_bus_max
8607 # check for bus:0:0 to see if we should
8608 # probe this bus further
8609 _pci_cfg_value $bus 0x0 0x0 0x0 32
8610 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
8611
8612 set $dev = 0
8613 while $dev < $kgm_pci_cfg_device_max
8614
8615 set $fcn = 0
8616 while $fcn < $kgm_pci_cfg_function_max
8617 _pci_cfg_value $bus $dev $fcn 0x0 32
8618 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
8619 if $dump == 0
8620 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
8621 _pci_cfg_value $bus $dev $fcn 0x8 32
8622 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
8623 else
8624 printf " device: %03X:%03X:%03X\n", $bus, $dev, $fcn
8625 pci_cfg_dump $bus $dev $fcn
8626 printf "\n"
8627 end
8628 end
8629 set $fcn = $fcn + 1
8630 end
8631 set $dev = $dev + 1
8632 end
8633 end
8634 set $bus = $bus + 1
8635 end
8636 end
8637
8638 define pci_cfg_dump_all
8639 _pci_cfg_scan 1
8640 end
8641
8642 document pci_cfg_dump_all
8643 Syntax: (gdb) pci_cfg_dump_all
8644 | dump config spaces for scanned pci devices. the number of busses to scan
8645 | is stored in $kgm_pci_cfg_bus_max. the default for that is 8. you can also
8646 | specify the starting bus with $kgm_pci_cfg_bus_start.
8647 end
8648
8649 define pci_cfg_scan
8650 printf "bus:dev:fcn: vendor device rev | class\n"
8651 printf "---------------------------------------\n"
8652 _pci_cfg_scan 0
8653 end
8654
8655 document pci_cfg_scan
8656 Syntax: (gdb) pci_cfg_scan
8657 | scan for pci devices. the number of busses to scan is stored in
8658 | $kgm_pci_cfg_bus_max. the default for that is 8. you can also specify the
8659 | starting bus with $kgm_pci_cfg_bus_start.
8660 end
8661
8662 define readioportint
8663 set $kgm_readioportint_result = 0xBAD10AD
8664 # set up the manual KDP packet
8665 set manual_pkt.input = 0
8666 set manual_pkt.len = sizeof(kdp_readioport_req_t)
8667 set $kgm_pkt = (kdp_readioport_req_t *)&manual_pkt.data
8668 set $kgm_pkt->hdr.request = KDP_READIOPORT
8669 set $kgm_pkt->hdr.len = sizeof(kdp_readioport_req_t)
8670 set $kgm_pkt->hdr.is_reply = 0
8671 set $kgm_pkt->hdr.seq = 0
8672 set $kgm_pkt->hdr.key = 0
8673 set $kgm_pkt->address = (uint16_t)$arg0
8674 set $kgm_pkt->nbytes = $arg1 >> 3
8675 set $kgm_pkt->lcpu = (uint16_t)$arg2
8676 set manual_pkt.input = 1
8677 # dummy to make sure manual packet is executed
8678 set $kgm_dummy = &_mh_execute_header
8679 set $kgm_pkt = (kdp_readioport_reply_t *)&manual_pkt.data
8680 if ($kgm_pkt->error == 0)
8681 if $arg1 == 8
8682 set $kgm_readioportint_result = *((uint8_t *) $kgm_pkt->data)
8683 end
8684 if $arg1 == 16
8685 set $kgm_readioportint_result = *((uint16_t *) $kgm_pkt->data)
8686 end
8687 if $arg1 == 32
8688 set $kgm_readioportint_result = *((uint32_t *) $kgm_pkt->data)
8689 end
8690 end
8691 end
8692
8693 define readioport8
8694 set $lcpu = $kgm_lcpu_self
8695 if $argc > 1
8696 set $lcpu = $arg1
8697 end
8698 readioportint $arg0 8 $lcpu
8699 output /a $arg0
8700 printf ":\t0x%02hhx\n", $kgm_readioportint_result
8701 end
8702
8703 define readioport16
8704 set $lcpu = $kgm_lcpu_self
8705 if $argc > 1
8706 set $lcpu = $arg1
8707 end
8708 readioportint $arg0 16 $lcpu
8709 output /a $arg0
8710 printf ":\t0x%04hx\n", $kgm_readioportint_result
8711 end
8712
8713 define readioport32
8714 set $lcpu = $kgm_lcpu_self
8715 if $argc > 1
8716 set $lcpu = $arg1
8717 end
8718 readioportint $arg0 32 $lcpu
8719 output /a $arg0
8720 printf ":\t0x%08x\n", $kgm_readioportint_result
8721 end
8722
8723 document readioport8
8724 | See readioport32.
8725 end
8726
8727 document readioport16
8728 | See readioport32.
8729 end
8730
8731 document readioport32
8732 Syntax: (gdb) readioport32 <port> [lcpu (kernel's numbering convention)]
8733 | Read value stored in the specified IO port. The CPU can be optionally
8734 | specified as well.
8735 end
8736
8737 define writeioportint
8738 # set up the manual KDP packet
8739 set manual_pkt.input = 0
8740 set manual_pkt.len = sizeof(kdp_writeioport_req_t)
8741 set $kgm_pkt = (kdp_writeioport_req_t *)&manual_pkt.data
8742 set $kgm_pkt->hdr.request = KDP_WRITEIOPORT
8743 set $kgm_pkt->hdr.len = sizeof(kdp_writeioport_req_t)
8744 set $kgm_pkt->hdr.is_reply = 0
8745 set $kgm_pkt->hdr.seq = 0
8746 set $kgm_pkt->hdr.key = 0
8747 set $kgm_pkt->address = (uint16_t)$arg0
8748 set $kgm_pkt->nbytes = $arg1 >> 3
8749 set $kgm_pkt->lcpu = (uint16_t)$arg3
8750 if $arg1 == 8
8751 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
8752 end
8753 if $arg1 == 16
8754 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
8755 end
8756 if $arg1 == 32
8757 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
8758 end
8759 set manual_pkt.input = 1
8760 # dummy to make sure manual packet is executed
8761 set $kgm_dummy = &_mh_execute_header
8762 set $kgm_pkt = (kdp_writeioport_reply_t *)&manual_pkt.data
8763 set $kgm_writeioportint_result = $kgm_pkt->error
8764 end
8765
8766 define writeioport8
8767 set $lcpu = $kgm_lcpu_self
8768 if $argc > 2
8769 set $lcpu = $arg2
8770 end
8771 writeioportint $arg0 8 $arg1 $lcpu
8772 end
8773
8774 define writeioport16
8775 set $lcpu = $kgm_lcpu_self
8776 if $argc > 2
8777 set $lcpu = $arg2
8778 end
8779 writeioportint $arg0 16 $arg1 $lcpu
8780 end
8781
8782 define writeioport32
8783 set $lcpu = $kgm_lcpu_self
8784 if $argc > 2
8785 set $lcpu = $arg2
8786 end
8787 writeioportint $arg0 32 $arg1 $lcpu
8788 end
8789
8790 document writeioport8
8791 | See writeioport32.
8792 end
8793
8794 document writeioport16
8795 | See writeioport32.
8796 end
8797
8798 document writeioport32
8799 Syntax: (gdb) writeioport32 <port> <value> [lcpu (kernel's numbering convention)]
8800 | Write the value to the specified IO port. The size of the value is
8801 | determined by the name of the command. The CPU used can be optionally
8802 | specified.
8803 end
8804
8805 define readmsr64int
8806 set $kgm_readmsr64int_result = 0xBAD10AD
8807 # set up the manual KDP packet
8808 set manual_pkt.input = 0
8809 set manual_pkt.len = sizeof(kdp_readmsr64_req_t)
8810 set $kgm_pkt = (kdp_readmsr64_req_t *)&manual_pkt.data
8811 set $kgm_pkt->hdr.request = KDP_READMSR64
8812 set $kgm_pkt->hdr.len = sizeof(kdp_readmsr64_req_t)
8813 set $kgm_pkt->hdr.is_reply = 0
8814 set $kgm_pkt->hdr.seq = 0
8815 set $kgm_pkt->hdr.key = 0
8816 set $kgm_pkt->address = (uint32_t)$arg0
8817 set $kgm_pkt->lcpu = (uint16_t)$arg1
8818 set manual_pkt.input = 1
8819 # dummy to make sure manual packet is executed
8820 set $kgm_dummy = &_mh_execute_header
8821 set $kgm_pkt = (kdp_readmsr64_reply_t *)&manual_pkt.data
8822 if ($kgm_pkt->error == 0)
8823 set $kgm_readmsr64int_result = *((uint64_t *) $kgm_pkt->data)
8824 end
8825 end
8826
8827 define readmsr64
8828 set $lcpu = $kgm_lcpu_self
8829 if $argc > 1
8830 set $lcpu = $arg1
8831 end
8832 readmsr64int $arg0 $lcpu
8833 output /a $arg0
8834 printf ":\t0x%016llx\n", $kgm_readmsr64int_result
8835 end
8836
8837 define writemsr64int
8838 # set up the manual KDP packet
8839 set manual_pkt.input = 0
8840 set manual_pkt.len = sizeof(kdp_writemsr64_req_t)
8841 set $kgm_pkt = (kdp_writemsr64_req_t *)&manual_pkt.data
8842 set $kgm_pkt->hdr.request = KDP_WRITEMSR64
8843 set $kgm_pkt->hdr.len = sizeof(kdp_writemsr64_req_t)
8844 set $kgm_pkt->hdr.is_reply = 0
8845 set $kgm_pkt->hdr.seq = 0
8846 set $kgm_pkt->hdr.key = 0
8847 set $kgm_pkt->address = (uint32_t)$arg0
8848 set $kgm_pkt->lcpu = (uint16_t)$arg2
8849 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg1
8850 set manual_pkt.input = 1
8851 # dummy to make sure manual packet is executed
8852 set $kgm_dummy = &_mh_execute_header
8853 set $kgm_pkt = (kdp_writemsr64_reply_t *)&manual_pkt.data
8854 set $kgm_writemsr64int_result = $kgm_pkt->error
8855 end
8856
8857 define writemsr64
8858 set $lcpu = $kgm_lcpu_self
8859 if $argc > 2
8860 set $lcpu = $arg2
8861 end
8862 writemsr64int $arg0 $arg1 $lcpu
8863 end
8864
8865 document writemsr64
8866 Syntax: (gdb) writemsr64 <msr> <value> [lcpu (kernel's numbering convention)]
8867 | Write <value> to the specified MSR. The CPU can be optionally specified.
8868 end
8869
8870 document readmsr64
8871 Syntax: (gdb) readmsr64 <msr> [lcpu (kernel's numbering convention)]
8872 | Read the specified MSR. The CPU can be optionally specified.
8873 end
8874
8875 # default if we can't find a registry entry
8876 set $kgm_ioapic_addr = 0xFEC00000
8877 set $kgm_ioapic_init = 0
8878
8879 set $_ioapic_index_off = 0x00
8880 set $_ioapic_data_off = 0x10
8881 set $_ioapic_eoi_off = 0x40
8882
8883 set $_ioapic_index_id = 0x00
8884 set $_ioapic_index_ver = 0x01
8885 set $_ioapic_index_redir_base = 0x10
8886
8887 set $_apic_vector_mask = 0xFF
8888 set $_apic_masked = 0x10000
8889 set $_apic_trigger_level = 0x08000
8890 set $_apic_polarity_high = 0x02000
8891 set $_apic_pending = 0x01000
8892
8893 define _ioapic_init
8894 if $kgm_ioapic_init == 0
8895 strcmp_arg_pack64 'i' 'o' '-' 'a' 'p' 'i' 'c' 0
8896 setfindregistrystr $kgm_strcmp_arg
8897
8898 set $olddepth = $kgm_reg_depth_max
8899 set $kgm_reg_depth_max = 3
8900 _findregistryentry
8901 set $kgm_reg_depth_max = $olddepth
8902
8903 if $kgm_registry_entry
8904 strcmp_arg_pack64 'P' 'h' 'y' 's' 'i' 'c' 'a' 'l'
8905 set $Physical = $kgm_strcmp_arg
8906 strcmp_arg_pack64 ' ' 'A' 'd' 'd' 'r' 'e' 's' 's'
8907 set $_Address = $kgm_strcmp_arg
8908 setfindregistrystr $Physical $_Address
8909
8910 _findregistryprop $kgm_registry_entry
8911 if $kgm_registry_value
8912 set $kgm_ioapic_addr = ((OSNumber *) $kgm_registry_value)->value
8913 end
8914 end
8915 set $kgm_ioapic_index_addr = $kgm_ioapic_addr + $_ioapic_index_off
8916 set $kgm_ioapic_data_addr = $kgm_ioapic_addr + $_ioapic_data_off
8917 set $kgm_ioapic_init = 1
8918 end
8919 end
8920
8921 define _ioapic_addr_value
8922 _ioapic_init
8923 writephysint $kgm_ioapic_index_addr 8 $arg0 $kgm_lcpu_self
8924 if $argc > 1
8925 writephysint $kgm_ioapic_data_addr 32 $arg1 $kgm_lcpu_self
8926 else
8927 readphysint $kgm_ioapic_data_addr 32 $kgm_lcpu_self
8928 set $kgm_ioapic_value = $kgm_readphysint_result
8929 end
8930 end
8931
8932 define _apic_print
8933 set $value = $arg0
8934
8935 printf "[VEC=%3d ", $value & $_apic_vector_mask
8936 if $value & $_apic_masked
8937 printf "MASK=yes "
8938 else
8939 printf "MASK=no "
8940 end
8941
8942 if $value & $_apic_trigger_level
8943 printf "TRIG=level "
8944 else
8945 printf "TRIG=edge "
8946 end
8947
8948 if $value & $_apic_polarity_high
8949 printf "POL=high"
8950 else
8951 printf "POL=low "
8952 end
8953
8954 if $value & $_apic_pending
8955 printf " PEND=yes]\n"
8956 else
8957 printf " PEND=no ]\n"
8958 end
8959 end
8960
8961 define ioapic_read32
8962 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
8963 printf "ioapic_read32 not supported on this architecture.\n"
8964 else
8965 _ioapic_addr_value $arg0
8966 printf "IOAPIC[0x%02X]: 0x%08X\n", $arg0, $kgm_ioapic_value
8967 end
8968 end
8969
8970 document ioapic_read32
8971 Syntax: (gdb) ioapic_read <offset>
8972 | Read the IOAPIC register at the offset specified.
8973 end
8974
8975 define ioapic_write32
8976 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
8977 printf "ioapic_write32 not supported on this architecture.\n"
8978 else
8979 _ioapic_addr_value $arg0 $arg1
8980 end
8981 end
8982
8983 document ioapic_write32
8984 Syntax: (gdb) ioapic_write32 <offset> <value>
8985 | Write the IOAPIC register at the offset specified.
8986 end
8987
8988 define ioapic_dump
8989 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
8990 printf "ioapic_dump not supported on this architecture.\n"
8991 else
8992 # id
8993 _ioapic_addr_value $_ioapic_index_id
8994 printf "IOAPIC[0x%02X] ID: 0x%08X\n", $_ioapic_index_id, $kgm_ioapic_value
8995
8996 # version
8997 _ioapic_addr_value $_ioapic_index_ver
8998 set $maxredir = (($kgm_ioapic_value & 0xFF0000) >> 16) + 1
8999
9000 printf "IOAPIC[0x%02X] VERSION: 0x%08X [", $_ioapic_index_ver, $kgm_ioapic_value
9001 printf "MAXREDIR=%02d PRQ=%d VERSION=0x%02X]\n", $maxredir, ($kgm_ioapic_value >> 15) & 0x1, $kgm_ioapic_value & 0xFF
9002
9003 # all the redir entries
9004 set $i = 0
9005 while $i < $maxredir
9006 set $addr0 = $_ioapic_index_redir_base + ($i << 1)
9007 set $addr1 = $addr0 + 1
9008 _ioapic_addr_value $addr1
9009 printf "IOAPIC[0x%02X] IOREDIR%02d: 0x%08X", $addr0, $i, $kgm_ioapic_value
9010
9011 _ioapic_addr_value $addr0
9012 printf "%08X ", $kgm_ioapic_value
9013 _apic_print $kgm_ioapic_value
9014 set $i = $i + 1
9015 end
9016 end
9017 end
9018
9019 document ioapic_dump
9020 Syntax: (gdb) ioapic_dump
9021 | Dump all the IOAPIC entries.
9022 end
9023
9024
9025 set $_lapic_base_addr = 0xFEE00000
9026 set $_lapic_id = 0x20
9027 set $_lapic_version = 0x30
9028 set $_lapic_tpr = 0x80
9029 set $_lapic_apr = 0x90
9030 set $_lapic_ppr = 0xA0
9031 set $_lapic_eoi = 0xB0
9032 set $_lapic_ldr = 0xD0
9033 set $_lapic_dfr = 0xE0
9034 set $_lapic_sivr = 0xF0
9035
9036 set $_lapic_isr_size = 0x10
9037 set $_lapic_isr_num = 8
9038 set $_lapic_isr0 = 0x100
9039 set $_lapic_tmr0 = 0x180
9040 set $_lapic_irr0 = 0x200
9041
9042 set $_lapic_esr = 0x280
9043 set $_lapic_esr_register = 0x80
9044 set $_lapic_esr_recv_vect = 0x40
9045 set $_lapic_esr_send_vect = 0x20
9046
9047 set $_lapic_icr0 = 0x300
9048 set $_lapic_icr1 = 0x310
9049
9050 set $_lapic_lvt_timer = 0x320
9051 set $_lapic_lvt_thermal = 0x330
9052 set $_lapic_lvt_pmcr = 0x340
9053 set $_lapic_lvt_lint0 = 0x350
9054 set $_lapic_lvt_lint1 = 0x360
9055 set $_lapic_lvt_error = 0x370
9056
9057 set $_lapic_icr = 0x380
9058 set $_lapic_ccr = 0x390
9059 set $_lapic_dcr = 0x3E0
9060
9061 set $_apic_cfg_msr = 0x1B
9062 set $_apic_cfg_msr_x2EN = 0x00000C00
9063 set $_x2apic_enabled = -1
9064
9065 # _lapic_addr $offset returns the actual address to use
9066 define _lapic_addr
9067 if $_x2apic_enabled < 0
9068 readmsr64int $_apic_cfg_msr $kgm_lcpu_self
9069 if ($kgm_readmsr64int_result & $_apic_cfg_msr_x2EN) == $_apic_cfg_msr_x2EN
9070 set $_x2apic_enabled = 1
9071 else
9072 set $_x2apic_enabled = 0
9073 end
9074 end
9075
9076 if $_x2apic_enabled
9077 # x2APIC addresses are MSRs that use xAPIC offsets that
9078 # are 4-bit shifted
9079 set $kgm_lapic_addr = $arg0 >> 4
9080 else
9081 set $kgm_lapic_addr = $_lapic_base_addr + $arg0
9082 end
9083 end
9084
9085 # _lapic_addr_value $offset $lcpu
9086 define _lapic_addr_value
9087 _lapic_addr $arg0
9088 if $_x2apic_enabled
9089 readmsr64int $kgm_lapic_addr $arg1
9090 set $kgm_lapic_value = $kgm_readmsr64int_result
9091 else
9092 readphysint $kgm_lapic_addr 32 $arg1
9093 set $kgm_lapic_value = $kgm_readphysint_result
9094 end
9095 end
9096
9097 # lapic_read32 $offset [$lcpu]
9098 define lapic_read32
9099 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9100 printf "lapic_read32 not supported on this architecture.\n"
9101 else
9102 set $lcpu = $kgm_lcpu_self
9103 if $argc > 1
9104 set $lcpu = $arg1
9105 end
9106 _lapic_addr_value $arg0 $lcpu
9107 printf "LAPIC[0x%03X]: 0x%08X\n", $arg0, $kgm_lapic_value
9108 end
9109 end
9110
9111 document lapic_read32
9112 Syntax: (gdb) apic_read32_cpu <offset> [lcpu (kernel's numbering convention)]
9113 | Read the LAPIC register at the offset specified. The CPU can be optionally
9114 | specified.
9115 end
9116
9117 # lapic_write32 $offset $value [$lcpu]
9118 define lapic_write32
9119 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9120 printf "lapic_write32_cpu not supported on this architecture.\n"
9121 else
9122 set $lcpu = $kgm_lcpu_self
9123 if $argc > 2
9124 set $lcpu = $arg2
9125 end
9126
9127 _lapic_addr $arg0
9128 if $_x2apic_enabled
9129 writemsr64int $kgm_lapic_addr $arg1 $lcpu
9130 else
9131 writephysint $kgm_lapic_addr 32 $arg1 $lcpu
9132 end
9133 end
9134 end
9135
9136 document lapic_write32
9137 Syntax: (gdb) lapic_write32 <offset> <value> [lcpu (kernel's numbering convention)]
9138 | Write the LAPIC register at the offset specified. The CPU can be optionally
9139 | specified.
9140 end
9141
9142 # lapic_dump [lcpu]
9143 define lapic_dump
9144 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9145 printf "lapic_dump not supported on this architecture.\n"
9146 else
9147 set $lcpu = $kgm_lcpu_self
9148 if $argc > 0
9149 set $lcpu = $arg0
9150 end
9151
9152 _lapic_addr_value $_lapic_id $lcpu
9153
9154 # the above also figures out if we're using an xAPIC or an x2APIC
9155 printf "LAPIC operating mode: "
9156 if $_x2apic_enabled
9157 printf " x2APIC\n"
9158 else
9159 printf " xAPIC\n"
9160 end
9161
9162 printf "LAPIC[0x%03X] ID: 0x%08X\n", $_lapic_id, $kgm_lapic_value
9163
9164 _lapic_addr_value $_lapic_version $lcpu
9165 set $lvt_num = ($kgm_lapic_value >> 16) + 1
9166 printf "LAPIC[0x%03X] VERSION: 0x%08X [VERSION=%d MaxLVT=%d]\n", $_lapic_version, $kgm_lapic_value, $kgm_lapic_value & 0xFF, $lvt_num
9167
9168 _lapic_addr_value $_lapic_tpr $lcpu
9169 printf "LAPIC[0x%03X] TASK PRIORITY: 0x%08X\n", $_lapic_tpr, $kgm_lapic_value
9170
9171 _lapic_addr_value $_lapic_ppr $lcpu
9172 printf "LAPIC[0x%03X] PROCESSOR PRIORITY: 0x%08X\n", $_lapic_ppr, $kgm_lapic_value
9173
9174 _lapic_addr_value $_lapic_ldr $lcpu
9175 printf "LAPIC[0x%03X] LOGICAL DEST: 0x%08X\n", $_lapic_ldr, $kgm_lapic_value
9176
9177 _lapic_addr_value $_lapic_dfr $lcpu
9178 printf "LAPIC[0x%03X] DEST FORMAT: 0x%08X\n", $_lapic_dfr, $kgm_lapic_value
9179
9180 _lapic_addr_value $_lapic_sivr $lcpu
9181 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,
9182
9183 set $i = 0
9184 while $i < $_lapic_isr_num
9185 set $addr = $_lapic_isr0 + $i * $_lapic_isr_size
9186 _lapic_addr_value $addr $lcpu
9187 printf "LAPIC[0x%03X] ISR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9188 set $i = $i + 1
9189 end
9190
9191 set $i = 0
9192 while $i < $_lapic_isr_num
9193 set $addr = $_lapic_tmr0 + $i * $_lapic_isr_size
9194 _lapic_addr_value $addr $lcpu
9195 printf "LAPIC[0x%03X] TMR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9196 set $i = $i + 1
9197 end
9198
9199 set $i = 0
9200 while $i < $_lapic_isr_num
9201 set $addr = $_lapic_irr0 + $i * $_lapic_isr_size
9202 _lapic_addr_value $addr $lcpu
9203 printf "LAPIC[0x%03X] IRR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
9204 set $i = $i + 1
9205 end
9206
9207 _lapic_addr_value $_lapic_esr $lcpu
9208 printf "LAPIC[0x%03X] ERROR STATUS: 0x%08X ", $_lapic_esr, $kgm_lapic_value
9209 if $kgm_lapic_value
9210 printf "["
9211 end
9212 if $kgm_lapic_value & $_lapic_esr_register
9213 printf "Register "
9214 end
9215 if $kgm_lapic_value & $_lapic_esr_recv_vect
9216 printf "Received Vector "
9217 end
9218 if $kgm_lapic_value & $_lapic_esr_send_vect
9219 printf "Send Vector"
9220 end
9221 if $kgm_lapic_value
9222 printf "]"
9223 end
9224 printf "\n"
9225
9226 _lapic_addr_value $_lapic_icr1 $lcpu
9227 printf "LAPIC[0x%03X] Interrupt Command: 0x%08X [DEST=%d]\n", $_lapic_icr0, $kgm_lapic_value, $kgm_lapic_value >> 24
9228 _lapic_addr_value $_lapic_icr0 $lcpu
9229 printf " 0x%08X ", $kgm_lapic_value
9230 _apic_print $kgm_lapic_value
9231
9232 if $lvt_num > 0
9233 _lapic_addr_value $_lapic_lvt_timer $lcpu
9234 printf "LAPIC[0x%03X] LVT Timer: 0x%08X ", $_lapic_lvt_timer, $kgm_lapic_value
9235 _apic_print $kgm_lapic_value
9236 end
9237
9238 if $lvt_num > 1
9239 _lapic_addr_value $_lapic_lvt_lint0 $lcpu
9240 printf "LAPIC[0x%03X] LVT LINT0: 0x%08X ", $_lapic_lvt_lint0, $kgm_lapic_value
9241 _apic_print $kgm_lapic_value
9242 end
9243
9244 if $lvt_num > 2
9245 _lapic_addr_value $_lapic_lvt_lint1 $lcpu
9246 printf "LAPIC[0x%03X] LVT LINT1: 0x%08X ", $_lapic_lvt_lint1, $kgm_lapic_value
9247 _apic_print $kgm_lapic_value
9248 end
9249
9250 if $lvt_num > 3
9251 _lapic_addr_value $_lapic_lvt_error $lcpu
9252 printf "LAPIC[0x%03X] LVT Error: 0x%08X ", $_lapic_lvt_error, $kgm_lapic_value
9253 _apic_print $kgm_lapic_value
9254 end
9255
9256 if $lvt_num > 4
9257 _lapic_addr_value $_lapic_lvt_pmcr $lcpu
9258 printf "LAPIC[0x%03X] LVT PerfMon: 0x%08X ", $_lapic_lvt_pmcr, $kgm_lapic_value
9259 _apic_print $kgm_lapic_value
9260 end
9261
9262 if $lvt_num > 5
9263 _lapic_addr_value $_lapic_lvt_thermal $lcpu
9264 printf "LAPIC[0x%03X] LVT Thermal: 0x%08X ", $_lapic_lvt_thermal, $kgm_lapic_value
9265 _apic_print $kgm_lapic_value
9266 end
9267
9268 _lapic_addr_value $_lapic_dcr $lcpu
9269 printf "LAPIC[0x%03X] Timer Divide: 0x%08X [Divide by ", $_lapic_dcr, $kgm_lapic_value
9270 set $kgm_lapic_value = ($kgm_lapic_value & 0x8) >> 1 | $kgm_lapic_value & 0x3
9271 if $kgm_lapic_value == 0x7
9272 printf "1]\n"
9273 else
9274 printf "%d]\n", 2 << $kgm_lapic_value
9275 end
9276
9277 _lapic_addr_value $_lapic_icr $lcpu
9278 printf "LAPIC[0x%03X] Timer Init Count: 0x%08X\n", $_lapic_icr, $kgm_lapic_value
9279
9280 _lapic_addr_value $_lapic_ccr $lcpu
9281 printf "LAPIC[0x%03X] Timer Cur Count: 0x%08X\n", $_lapic_ccr, $kgm_lapic_value
9282 end
9283 end
9284
9285 document lapic_dump
9286 Syntax: (gdb) lapic_dump [lcpu (kernel's numbering convention)]
9287 | Dump all the LAPIC entries. The CPU can be optionally specified.
9288 end
9289
9290 define showknoteheader
9291 printf " knote filter ident kn_ptr status\n"
9292 end
9293
9294 define showknoteint
9295 set $kgm_knotep = ((struct knote *) $arg0)
9296 printf " "
9297 showptr $kgm_knotep
9298 printf " "
9299 set $kgm_filt = -$kgm_knotep->kn_kevent.filter
9300 if ($kgm_filt == 1)
9301 printf "EVFILT_READ "
9302 end
9303 if ($kgm_filt == 2)
9304 printf "EVFILT_WRITE "
9305 end
9306 if ($kgm_filt == 3)
9307 printf "EVFILT_AIO "
9308 end
9309 if ($kgm_filt == 4)
9310 printf "EVFILT_VNODE "
9311 end
9312 if ($kgm_filt == 5)
9313 printf "EVFILT_PROC "
9314 end
9315 if ($kgm_filt == 6)
9316 printf "EVFILT_SIGNAL "
9317 end
9318 if ($kgm_filt == 7)
9319 printf "EVFILT_TIMER "
9320 end
9321 if ($kgm_filt == 8)
9322 printf "EVFILT_MACHPORT"
9323 end
9324 if ($kgm_filt == 9)
9325 printf "EVFILT_FS "
9326 end
9327 if ($kgm_filt == 10)
9328 printf "EVFILT_USER "
9329 end
9330 if ($kgm_filt == 11)
9331 printf "EVFILT_SESSION "
9332 end
9333 printf "%7d ", $kgm_knotep->kn_kevent.ident
9334 showptr $kgm_knotep->kn_ptr.p_fp
9335 printf " "
9336 if ($kgm_knotep->kn_status == 0)
9337 printf "-"
9338 else
9339 if ($kgm_knotep->kn_status & 0x01)
9340 printf "A"
9341 end
9342 if ($kgm_knotep->kn_status & 0x02)
9343 printf "Q"
9344 end
9345 if ($kgm_knotep->kn_status & 0x04)
9346 printf "Dis"
9347 end
9348 if ($kgm_knotep->kn_status & 0x08)
9349 printf "Dr"
9350 end
9351 if ($kgm_knotep->kn_status & 0x10)
9352 printf "Uw"
9353 end
9354 if ($kgm_knotep->kn_status & 0x20)
9355 printf "Att"
9356 end
9357 if ($kgm_knotep->kn_status & 0x40)
9358 printf "Stq"
9359 end
9360 end
9361 printf "\n"
9362 end
9363
9364 define showprocknotes
9365 showknoteheader
9366 set $kgm_fdp = ((proc_t)$arg0)->p_fd
9367 set $kgm_knlist = $kgm_fdp->fd_knlist
9368 set $i = 0
9369 while (($i < $kgm_fdp->fd_knlistsize) && ($kgm_knlist != 0))
9370 set $kgm_kn = ((struct knote *)$kgm_knlist[$i].slh_first)
9371 while ($kgm_kn != 0)
9372 showknoteint $kgm_kn
9373 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
9374 end
9375 set $i = $i + 1
9376 end
9377 set $kgm_knhash = $kgm_fdp->fd_knhash
9378 set $i = 0
9379 while (($i < $kgm_fdp->fd_knhashmask + 1) && ($kgm_knhash != 0))
9380 set $kgm_kn = ((struct knote *)$kgm_knhash[$i].slh_first)
9381 while ($kgm_kn != 0)
9382 showknoteint $kgm_kn
9383 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
9384 end
9385 set $i = $i + 1
9386 end
9387 end
9388
9389 define showallknotes
9390 set $kgm_head_taskp = &tasks
9391 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9392 while $kgm_taskp != $kgm_head_taskp
9393 showtaskheader
9394 showtaskint $kgm_taskp
9395 showprocknotes $kgm_taskp->bsd_info
9396 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9397 end
9398 end
9399 document showprocknotes
9400 Syntax: showprocknotes <proc>
9401 | Displays filter and status information for every kevent registered for
9402 | the process.
9403 end
9404
9405 #
9406 # Device node related debug macros
9407 #
9408
9409 define _showtty
9410 set $kgm_tty = (struct tty *) $arg0
9411 printf "tty struct at "
9412 showptr $kgm_tty
9413 printf "\n"
9414 printf "-last input to raw queue:\n"
9415 p $kgm_tty->t_rawq->c_cs
9416 printf "-last input to canonical queue:\n"
9417 p $kgm_tty->t_canq->c_cs
9418 printf "-last output data:\n"
9419 p $kgm_tty->t_outq->c_cs
9420 printf "state:\n"
9421 if ($kgm_tty->t_state & 0x00000001)
9422 printf " TS_SO_OLOWAT (Wake up when output <= low water)\n"
9423 end
9424 if ($kgm_tty->t_state & 0x00000002)
9425 printf " TS_ASYNC (async I/O mode)\n"
9426 else
9427 printf " - (synchronous I/O mode)\n"
9428 end
9429 if ($kgm_tty->t_state & 0x00000004)
9430 printf " TS_BUSY (Draining output)\n"
9431 end
9432 if ($kgm_tty->t_state & 0x00000008)
9433 printf " TS_CARR_ON (Carrier is present)\n"
9434 else
9435 printf " - (Carrier is NOT present)\n"
9436 end
9437 if ($kgm_tty->t_state & 0x00000010)
9438 printf " TS_FLUSH (Outq has been flushed during DMA)\n"
9439 end
9440 if ($kgm_tty->t_state & 0x00000020)
9441 printf " TS_ISOPEN (Open has completed)\n"
9442 else
9443 printf " - (Open has NOT completed)\n"
9444 end
9445 if ($kgm_tty->t_state & 0x00000040)
9446 printf " TS_TBLOCK (Further input blocked)\n"
9447 end
9448 if ($kgm_tty->t_state & 0x00000080)
9449 printf " TS_TIMEOUT (Wait for output char processing)\n"
9450 end
9451 if ($kgm_tty->t_state & 0x00000100)
9452 printf " TS_TTSTOP (Output paused)\n"
9453 end
9454 if ($kgm_tty->t_state & 0x00000200)
9455 printf " TS_WOPEN (Open in progress)\n"
9456 end
9457 if ($kgm_tty->t_state & 0x00000400)
9458 printf " TS_XCLUDE (Tty requires exclusivity)\n"
9459 end
9460 if ($kgm_tty->t_state & 0x00000800)
9461 printf " TS_BKSL (State for lowercase \\ work)\n"
9462 end
9463 if ($kgm_tty->t_state & 0x00001000)
9464 printf " TS_CNTTB (Counting tab width, ignore FLUSHO)\n"
9465 end
9466 if ($kgm_tty->t_state & 0x00002000)
9467 printf " TS_ERASE (Within a \\.../ for PRTRUB)\n"
9468 end
9469 if ($kgm_tty->t_state & 0x00004000)
9470 printf " TS_LNCH (Next character is literal)\n"
9471 end
9472 if ($kgm_tty->t_state & 0x00008000)
9473 printf " TS_TYPEN (Retyping suspended input (PENDIN))\n"
9474 end
9475 if ($kgm_tty->t_state & 0x00010000)
9476 printf " TS_CAN_BYPASS_L_RINT (Device in "raw" mode)\n"
9477 end
9478 if ($kgm_tty->t_state & 0x00020000)
9479 printf " TS_CONNECTED (Connection open)\n"
9480 else
9481 printf " - (Connection NOT open)\n"
9482 end
9483 if ($kgm_tty->t_state & 0x00040000)
9484 printf " TS_SNOOP (Device is being snooped on)\n"
9485 end
9486 if ($kgm_tty->t_state & 0x80000)
9487 printf " TS_SO_OCOMPLETE (Wake up when output completes)\n"
9488 end
9489 if ($kgm_tty->t_state & 0x00100000)
9490 printf " TS_ZOMBIE (Connection lost)\n"
9491 end
9492 if ($kgm_tty->t_state & 0x00200000)
9493 printf " TS_CAR_OFLOW (For MDMBUF - handle in driver)\n"
9494 end
9495 if ($kgm_tty->t_state & 0x00400000)
9496 printf " TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)\n"
9497 end
9498 if ($kgm_tty->t_state & 0x00800000)
9499 printf " TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)\n"
9500 end
9501 # xxx todo: do we care about decoding flags?
9502 printf "flags: 0x%08x\n", $kgm_tty->t_flags
9503 printf "foreground process group: "
9504 showptr $kgm_tty->t_pgrp
9505 printf "\n"
9506 printf "enclosing session: "
9507 showptr $kgm_tty->t_session
9508 printf "\n"
9509 printf "Termios:\n"
9510 # XXX todo: decode these flags, someday
9511 printf " Input flags: 0x%08x\n", $kgm_tty->t_termios.c_iflag
9512 printf " Output flags: 0x%08x\n", $kgm_tty->t_termios.c_oflag
9513 printf " Control flags: 0x%08x\n", $kgm_tty->t_termios.c_cflag
9514 printf " Local flags: 0x%08x\n", $kgm_tty->t_termios.c_lflag
9515 printf " Input speed: %d\n", $kgm_tty->t_termios.c_ispeed
9516 printf " Output speed: %d\n", $kgm_tty->t_termios.c_ospeed
9517 # XXX todo: useful to decode t_winsize? t_iokit? c_cc? anything else?
9518 printf "high watermark: %d bytes\n", $kgm_tty->t_hiwat
9519 printf "low watermark: %d bytes\n", $kgm_tty->t_lowat
9520 end
9521
9522 define _showwhohas
9523 # _showwhohas <major> <minor>
9524 printf "fd "
9525 printf "fileglob "
9526 showptrhdrpad
9527 printf "vnode "
9528 showptrhdrpad
9529 printf "process "
9530 showptrhdrpad
9531 printf "name\n"
9532
9533 set $kgm_swh_devnode_dev = (((int) $arg0) << 24) | (int) $arg1
9534 # iterate all tasks to iterate all processes to iterate all
9535 # open files in each process to see who has a given major/minor
9536 # device open
9537 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9538 while $kgm_taskp != $kgm_head_taskp
9539 set $kgm_procp = (proc_t) $kgm_taskp->bsd_info
9540 set $kgm_spf_filedesc = $kgm_procp->p_fd
9541 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
9542 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
9543 set $kgm_spf_count = 0
9544 while (($kgm_spf_ofiles != 0) && ($kgm_spf_count <= $kgm_spf_last))
9545 # only files currently open
9546 if ($kgm_spf_ofiles[$kgm_spf_count] != 0)
9547 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
9548 if ($kgm_spf_fg->fg_type == 1)
9549 # display fd #, fileglob & vnode address, proc name
9550 set $kgm_swh_m_vnode = (vnode_t) $kgm_spf_fg->fg_data
9551 set $kgm_swh_m_vtype = (enum vtype) $kgm_swh_m_vnode->v_type
9552 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)
9553 printf "%-5d ", $kgm_spf_count
9554 showptr $kgm_spf_fg
9555 printf " "
9556 showptr $kgm_swh_m_vnode
9557 printf " "
9558 showptr $kgm_procp
9559 printf " %s\n", $kgm_procp->p_comm
9560 end
9561 end
9562 end
9563 set $kgm_spf_count = $kgm_spf_count + 1
9564 end
9565
9566 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9567 end
9568 end
9569
9570 define _showvnodedev_cpty
9571 set $kgm_ptmx_major = (int) $arg0
9572 set $kgm_ptmx_minor = (int) $arg1
9573 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
9574 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
9575 printf " ptmx_ioctl struct at "
9576 showptr $kgm_ptmx_ioctl
9577 printf "\n"
9578 printf " flags:\n"
9579 if ($kgm_ptmx_ioctl->pt_flags & 0x0008)
9580 printf " PF_PKT (packet mode)\n"
9581 end
9582 if ($kgm_ptmx_ioctl->pt_flags & 0x0010)
9583 printf " PF_STOPPED (user told stopped)\n"
9584 end
9585 if ($kgm_ptmx_ioctl->pt_flags & 0x0020)
9586 printf " PF_REMOTE (remote and flow controlled input)\n"
9587 end
9588 if ($kgm_ptmx_ioctl->pt_flags & 0x0040)
9589 printf " PF_NOSTOP"
9590 end
9591 if ($kgm_ptmx_ioctl->pt_flags & 0x0080)
9592 printf " PF_UCNTL (user control mode)\n"
9593 end
9594 if ($kgm_ptmx_ioctl->pt_flags & 0x0100)
9595 printf " PF_UNLOCKED (slave unlock - master open resets)\n"
9596 end
9597 if ($kgm_ptmx_ioctl->pt_flags & 0x0200)
9598 printf " PF_OPEN_M (master is open)\n"
9599 # XXX we should search for who has the master open, but
9600 # XXX each master gets the same minor, even though it
9601 # XXX gets a different vnode. we chold probably change
9602 # XXX this, but to do it we would need some way of
9603 # XXX expressing the information in the vnode structure
9604 # XXX somewhere. If we *did* change it, it would buy us
9605 # XXX the ability to determine who has the corresponding
9606 # XXX master end of the pty open
9607 else
9608 printf " PF_OPEN_M (master is closed)\n"
9609 end
9610 if ($kgm_ptmx_ioctl->pt_flags & 0x0400)
9611 printf " PF_OPEN_S (slave is open)\n"
9612 printf "---vvvvv--- fds open on this device ---vvvvv---\n"
9613 _showwhohas ($kgm_ptmx_major) ($kgm_ptmx_minor)
9614 printf "---^^^^^--- fds open on this device ---^^^^^---\n"
9615 else
9616 printf " - (slave is closed)\n"
9617 end
9618 printf "TTY Specific Information\n"
9619 _showtty $kgm_ptmx_ioctl->pt_tty
9620 end
9621
9622 define showvnodedev
9623 if ($argc == 1)
9624 set $kgm_vnode = (vnode_t) $arg0
9625 set $kgm_vtype = (enum vtype) $kgm_vnode->v_type
9626 if (($kgm_vtype == VBLK) || ($kgm_vtype == VCHR))
9627 set $kgm_devnode = (devnode_t *) $kgm_vnode->v_data
9628 set $kgm_devnode_dev = $kgm_devnode->dn_typeinfo.dev
9629 set $kgm_devnode_major = ($kgm_devnode_dev >> 24) & 0xff
9630 set $kgm_devnode_minor = $kgm_devnode_dev & 0x00ffffff
9631
9632 # boilerplate device information for a vnode
9633 printf "Device Info:\n"
9634 printf " vnode: "
9635 showptr $kgm_vnode
9636 printf "\n"
9637 printf " type: "
9638 if ($kgm_vtype == VBLK)
9639 printf "VBLK "
9640 end
9641 if ($kgm_vtype == VCHR)
9642 printf "VCHR"
9643 end
9644 printf "\n"
9645 printf " name: %s\n", $kgm_vnode->v_name
9646 printf " major, minor: %d, %d\n", $kgm_devnode_major, $kgm_devnode_minor
9647 printf " mode 0%o\n", $kgm_devnode->dn_mode
9648 printf " owner (u,g): %d %d", $kgm_devnode->dn_uid, $kgm_devnode->dn_gid
9649 printf "\n"
9650
9651 # decode device specific data
9652 printf "Device Specific Information: "
9653 if ($kgm_vtype == VBLK)
9654 printf " Sorry, I do not know how to decode block devices yet!\n"
9655 printf " Maybe you can write me!"
9656 end
9657 if ($kgm_vtype == VCHR)
9658 # Device information; this is scanty
9659 # range check
9660 if ($kgm_devnode_major > 42) || ($kgm_devnode_major < 0)
9661 printf "Invalid major #\n"
9662 else
9663 # static assignments in conf
9664 if ($kgm_devnode_major == 0)
9665 printf "Console mux device\n"
9666 else
9667 if ($kgm_devnode_major == 2)
9668 printf "Current tty alias\n"
9669 else
9670 if ($kgm_devnode_major == 3)
9671 printf "NULL device\n"
9672 else
9673 if ($kgm_devnode_major == 4)
9674 printf "Old pty slave\n"
9675 else
9676 if ($kgm_devnode_major == 5)
9677 printf "Old pty master\n"
9678 else
9679 if ($kgm_devnode_major == 6)
9680 printf "Kernel log\n"
9681 else
9682 if ($kgm_devnode_major == 12)
9683 printf "Memory devices\n"
9684 else
9685 # Statically linked dynamic assignments
9686 if cdevsw[$kgm_devnode_major].d_open == ptmx_open
9687 printf "Cloning pty master\n"
9688 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
9689 else
9690 if cdevsw[$kgm_devnode_major].d_open == ptsd_open
9691 printf "Cloning pty slave\n"
9692 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
9693 else
9694 printf "RESERVED SLOT\n"
9695 end
9696 end
9697 end
9698 end
9699 end
9700 end
9701 end
9702 end
9703 end
9704 end
9705 end
9706 else
9707 showptr $kgm_vnode
9708 printf " is not a device\n"
9709 end
9710 else
9711 printf "| Usage:\n|\n"
9712 help showvnodedev
9713 end
9714 end
9715 document showvnodedev
9716 Syntax: (gdb) showvnodedev <vnode>
9717 | showvnodedev Display information about a device vnode
9718 end
9719
9720 define showtty
9721 if ($argc == 1)
9722 _showtty $arg0
9723 else
9724 printf "| Usage:\n|\n"
9725 help showtty
9726 end
9727 end
9728 document showtty
9729 Syntax: (gdb) showtty <tty struct>
9730 | showtty Display information about a struct tty
9731 end
9732
9733 define showeventsourceobject
9734 set $kgm_vt = *((void **) $arg1)
9735 if $kgm_lp64
9736 set $kgm_vt = $kgm_vt - 16
9737 end
9738 pcprint $kgm_vt
9739 end
9740 document showeventsourceobject
9741 Syntax: (gdb) showeventsourceobject <prefix> <object>
9742 | Routine to display information about an IOEventSource subclass.
9743 end
9744
9745 define showworkloopeventsources
9746 set $kgm_eventsource = (struct IOEventSource*)$arg0
9747 while $kgm_eventsource != 0
9748 printf " "
9749 printf "EventSource:\t"
9750 showptr $kgm_eventsource
9751 printf " Description: "
9752 showeventsourceobject _ $kgm_eventsource
9753 printf "\n"
9754 if $kgm_eventsource->action != 0
9755 printf " "
9756 printf "Action: \t"
9757 pcprint $kgm_eventsource->action
9758 printf "\n"
9759 end
9760 if $kgm_eventsource->owner != 0
9761 printf " "
9762 printf "Owner: \t"
9763 showptr $kgm_eventsource->owner
9764 printf " Description: "
9765 showeventsourceobject _ $kgm_eventsource->owner
9766 printf "\n"
9767 end
9768 set $kgm_eventsource = $kgm_eventsource->eventChainNext
9769 printf "\n"
9770 end
9771 end
9772 document showworkloopeventsources
9773 Syntax: (gdb) showworkloopeventsources
9774 | Routine to walk an IOEventSource chain associated with an IOWorkLoop and print information
9775 | about each event source in the chain.
9776 end
9777
9778 define showworkloopheader
9779 printf "thread "
9780 showptrhdrpad
9781 printf " workloop "
9782 showptrhdrpad
9783 printf " pri state\tLockGroupName\n"
9784 end
9785 document showworkloopheader
9786 Syntax: (gdb) showworkloopheader
9787 | Routine to print out header info about an IOKit workloop.
9788 end
9789
9790 define showworkloop
9791 set $kgm_workloopthread = (struct thread*)$arg0
9792 set $kgm_workloop = (struct IOWorkLoop*)$arg1
9793 showptr $kgm_workloopthread
9794 printf " "
9795 showptr $kgm_workloop
9796 printf " %3d ", $kgm_workloopthread.sched_pri
9797 set $kgm_state = $kgm_workloopthread.state
9798 if $kgm_state & 0x80
9799 printf "I"
9800 end
9801 if $kgm_state & 0x40
9802 printf "P"
9803 end
9804 if $kgm_state & 0x20
9805 printf "A"
9806 end
9807 if $kgm_state & 0x10
9808 printf "H"
9809 end
9810 if $kgm_state & 0x08
9811 printf "U"
9812 end
9813 if $kgm_state & 0x04
9814 printf "R"
9815 end
9816 if $kgm_state & 0x02
9817 printf "S"
9818 end
9819 if $kgm_state & 0x01
9820 printf "W"
9821 end
9822 printf "\t\t"
9823 set $kgm_gateLock = ( struct _IORecursiveLock *)$kgm_workloop->gateLock
9824 set $kgm_lockGroup = (struct _lck_grp_*)($kgm_gateLock->group)
9825 printf "%s", $kgm_lockGroup->lck_grp_name
9826 printf "\n"
9827 showworkloopeventsources $kgm_workloop->eventChain
9828 end
9829 document showworkloop
9830 Syntax: (gdb) showworkloop <thread> <workloop>
9831 | Routine to print out info about an IOKit workloop.
9832 end
9833
9834 define showallworkloopthreads
9835 set $kgm_head_taskp = &tasks
9836 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9837 set $kgm_head_actp = &($kgm_taskp->threads)
9838 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
9839 while $kgm_actp != $kgm_head_actp
9840 if ($kgm_actp->continuation == _ZN10IOWorkLoop10threadMainEv)
9841 showworkloopheader
9842 showworkloop $kgm_actp $kgm_actp->parameter
9843 else
9844 if ($kgm_actp->kernel_stack != 0)
9845 if ($kgm_mtype == $kgm_mtype_x86_64)
9846 #Warning: Grokking stack looking for hopeful workloops until we squirrel some info in thread_t.
9847 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0xB8))
9848 else
9849 if ($kgm_mtype == $kgm_mtype_i386)
9850 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0x3C))
9851 end
9852 end
9853 if ($kgm_workloop != 0)
9854 set $kgm_vt = *((void **) $kgm_workloop)
9855 if $kgm_lp64
9856 set $kgm_vt = $kgm_vt - 16
9857 end
9858 if ($kgm_vt == &_ZTV10IOWorkLoop)
9859 showworkloopheader
9860 showworkloop $kgm_actp $kgm_workloop
9861 end
9862 end
9863 end
9864 end
9865 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
9866 end
9867 printf "\n"
9868 end
9869 document showallworkloopthreads
9870 Syntax: (gdb) showallworkloopthreads
9871 | Routine to print out info about all IOKit workloop threads in the system. This macro will find
9872 | all IOWorkLoop threads blocked in continuations and on i386 and x86_64 systems will make a
9873 | best-effort guess to find any workloops that are actually not blocked in a continuation. For a
9874 | complete list, it is best to compare the output of this macro against the output of 'showallstacks'.
9875 end
9876 define showthreadfortid
9877 set $kgm_id_found = 0
9878
9879 set $kgm_head_taskp = &tasks
9880 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
9881 while $kgm_taskp != $kgm_head_taskp
9882 set $kgm_head_actp = &($kgm_taskp->threads)
9883 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
9884 while $kgm_actp != $kgm_head_actp
9885 set $kgm_thread = *(struct thread *)$kgm_actp
9886 set $kgm_thread_id = $kgm_thread.thread_id
9887 if ($kgm_thread_id == $arg0)
9888 showptr $kgm_actp
9889 printf "\n"
9890 set $kgm_id_found = 1
9891 loop_break
9892 end
9893 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
9894 end
9895 if ($kgm_id_found == 1)
9896 loop_break
9897 end
9898 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9899 end
9900 if ($kgm_id_found == 0)
9901 printf "Not a valid thread_id\n"
9902 end
9903 end
9904
9905 document showthreadfortid
9906 Syntax: showthreadfortid <thread_id>
9907 |The thread structure contains a unique thread_id value for each thread.
9908 |This command is used to retrieve the address of the thread structure(thread_t)
9909 |corresponding to a given thread_id.
9910 end
9911
9912 define showtaskbusyports
9913 set $kgm_isp = ((task_t)$arg0)->itk_space
9914 set $kgm_iindex = 0
9915 while ( $kgm_iindex < $kgm_isp->is_table_size )
9916 set $kgm_iep = &($kgm_isp->is_table[$kgm_iindex])
9917 if $kgm_iep->ie_bits & 0x00020000
9918 set $kgm_port = ((ipc_port_t)$kgm_iep->ie_object)
9919 if $kgm_port->ip_messages.data.port.msgcount > 0
9920 showport $kgm_port
9921 end
9922 end
9923 set $kgm_iindex = $kgm_iindex + 1
9924 end
9925 end
9926
9927 document showtaskbusyports
9928 Syntax: showtaskbusyports <task>
9929 |Routine to print information about receive rights belonging to this task that
9930 |have enqueued messages. This is often a sign of a blocked or hung process.
9931 end
9932
9933 define showallbusyports
9934 set $kgm_head_taskp = &tasks
9935 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
9936 while $kgm_cur_taskp != $kgm_head_taskp
9937 showtaskbusyports $kgm_cur_taskp
9938 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
9939 end
9940 end
9941
9942 document showallbusyports
9943 Syntax: showallbusyports
9944 |Routine to print information about all receive rights on the system that
9945 |have enqueued messages.
9946 end