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