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