]> git.saurik.com Git - apple/xnu.git/blob - kgmacros
a2c6879f82ad2eaf238e1de2b40292de84613fcd
[apple/xnu.git] / kgmacros
1
2 # Kernel gdb macros
3 #
4 # These gdb macros should be useful during kernel development in
5 # determining what's going on in the kernel.
6 #
7 # All the convenience variables used by these macros begin with $kgm_
8
9 set print asm-demangle on
10 set cp-abi gnu-v2
11
12 # This option tells gdb to relax its stack tracing heuristics
13 # Useful for debugging across stack switches
14 # (to the interrupt stack, for instance). Requires gdb-675 or greater.
15 set backtrace sanity-checks off
16
17 echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n
18
19 define kgm
20 printf ""
21 echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n
22 end
23
24 document kgm
25 | These are the kernel gdb macros. These gdb macros are intended to be
26 | used when debugging a remote kernel via the kdp protocol. Typically, you
27 | would connect to your remote target like so:
28 | (gdb) target remote-kdp
29 | (gdb) attach <name-of-remote-host>
30 |
31 | The following macros are available in this package:
32 | showversion Displays a string describing the remote kernel version
33 |
34 | showalltasks Display a summary listing of all tasks
35 | showallthreads Display info about all threads in the system
36 | showallstacks Display the stack for each thread in the system
37 | showcurrentthreads Display info about the thread running on each cpu
38 | showcurrentstacks Display the stack for the thread running on each cpu
39 | showallvm Display a summary listing of all the vm maps
40 | showallvme Display a summary listing of all the vm map entries
41 | showallipc Display a summary listing of all the ipc spaces
42 | showipcsummary Display a summary listing of the ipc spaces of all tasks
43 | showallrights Display a summary listing of all the ipc rights
44 | showallkexts Display a summary listing of all loaded kexts (alias: showallkmods)
45 | showallknownkexts Display a summary listing of all kexts, loaded or not
46 | showallbusyports Display a listing of all ports with unread messages
47 | showallprocessors Display a listing of all psets and processors
48 |
49 | showallclasses Display info about all OSObject subclasses in the system
50 | showobject Show info about an OSObject - its vtable ptr and retain count, & more info for simple container classes.
51 | showregistry Show info about all registry entries in the current plane
52 | showregistryprops Show info about all registry entries in the current plane, and their properties
53 | showregistryentry Show info about a registry entry; its properties and descendants in the current plane
54 | setregistryplane Set the plane to be used for the iokit registry macros (pass zero for list)
55 |
56 | setfindregistrystr Set the encoded string for matching with
57 | findregistryentry or findregistryprop (created from
58 | strcmp_arg_pack64)
59 | findregistryentry Find a registry entry that matches the encoded string
60 | findregistryentries Find all the registry entries that match the encoded string
61 | findregistryprop Search the registry entry for a property that matches
62 | the encoded string
63 |
64 | showtask Display info about the specified task
65 | showtaskthreads Display info about the threads in the task
66 | showtaskstacks Display the stack for each thread in the task
67 | showtaskvm Display info about the specified task's vm_map
68 | showtaskvme Display info about the task's vm_map entries
69 | showtaskipc Display info about the specified task's ipc space
70 | showtaskrights Display info about the task's ipc space entries
71 | showtaskrightsbt Display info about the task's ipc space entries with back traces
72 | showtaskbusyports Display all of the task's ports with unread messages
73 |
74 | showact Display info about a thread specified by activation
75 | showactstack Display the stack for a thread specified by activation
76 |
77 | showmap Display info about the specified vm_map
78 | showmapvme Display a summary list of the specified vm_map's entries
79 |
80 | showipc Display info about the specified ipc space
81 | showrights Display a summary list of all the rights in an ipc space
82 |
83 | showpid Display info about the process identified by pid
84 | showproc Display info about the process identified by proc struct
85 | showprocinfo Display detailed info about the process identified by proc struct
86 | showprocfiles Given a proc_t pointer, display the list of open file descriptors
87 | showproclocks Given a proc_t pointer, display the list of advisory file locks
88 | zombproc Print out all procs in the zombie list
89 | showproctree Show all the processes in a hierarchical tree form
90 | allproc Print out all process in the system not in the zombie list
91 | zombstacks Print out all stacks of tasks that are exiting
92 |
93 | showinitchild Print out all processes in the system which are children of init process
94 |
95 | showkext Display info about a kext (alias: showkmod)
96 | showkextaddr Given an address, display the kext and offset (alias: showkmodaddr)
97 |
98 | dumpcallqueue Dump out all the entries given a queue head
99 |
100 | showallmtx Display info about mutexes usage
101 | showallrwlck Display info about reader/writer locks usage
102 |
103 | zprint Display info about the memory zones
104 | showioalloc Display info about iokit allocations
105 | paniclog Display the panic log info
106 |
107 | switchtoact Switch to different context specified by activation
108 | switchtoctx Switch to different context
109 | showuserstack Display numeric backtrace of the user stack for an
110 | activation
111 | showtaskuserstacks Display user stacks for a specified task
112 | showuserregisters Display user registers for the specified thread
113 | showtaskuserregisters Display user registers for the specified task
114 |
115 | switchtouserthread Switch to the user context of the specified thread
116 | resetstacks Return to the original kernel context
117 |
118 | resetctx Reset context
119 | resume_on Resume when detaching from gdb
120 | resume_off Don't resume when detaching from gdb
121 |
122 | sendcore Configure kernel to send a coredump to the specified IP
123 | sendsyslog Configure kernel to send a system log to the specified IP
124 | sendpaniclog Configure kernel to send a panic log to the specified IP
125 | disablecore Configure the kernel to disable coredump transmission
126 | getdumpinfo Retrieve the current remote dump parameters
127 | setdumpinfo Configure the remote dump parameters
128 |
129 | switchtocorethread Corefile version of "switchtoact"
130 | resetcorectx Corefile version of "resetctx"
131 |
132 | readphys8 Reads the specified untranslated address (8-bit read)
133 | readphys16 Reads the specified untranslated address (16-bit read)
134 | readphys32 Reads the specified untranslated address (32-bit read)
135 | readphys64 Reads the specified untranslated address (64-bit read)
136 | writephys8 Writes to the specified untranslated address (8-bit write)
137 | writephys16 Writes to the specified untranslated address (16-bit write)
138 | writephys32 Writes to the specified untranslated address (32-bit write)
139 | writephys64 Writes to the specified untranslated address (64-bit write)
140 |
141 | readioport8 Read 8-bits from the specified I/O Port
142 | readioport16 Read 16-bits from the specified I/O Port
143 | readioport32 Read 32-bits from the specified I/O Port
144 | writeioport8 Write 8-bits into the specified I/O Port
145 | writeioport16 Write 16-bits into the specified I/O Port
146 | writeioport32 Write 32-bits into the specified I/O Port
147 |
148 | readmsr64 Read 64-bits from the specified MSR
149 | writemsr64 Write 64-bits into the specified MSR
150 |
151 | rtentry_showdbg Print the debug information of a route entry
152 | rtentry_trash Walk the list of trash route entries
153 |
154 | inifa_showdbg Print the debug information of an IPv4 interface address
155 | in6ifa_showdbg Print the debug information of an IPv6 interface address
156 | inm_showdbg Print the debug information of an IPv4 multicast address
157 | ifma_showdbg Print the debug information of a link multicast address
158 | ifpref_showdbg Print the debug information of an interface ref count
159 |
160 | ndpr_showdbg Print the debug information of a nd_prefix structure
161 | nddr_showdbg Print the debug information of a nd_defrouter structure
162 |
163 | imo_showdbg Print the debug information of a ip_moptions structure
164 | im6o_showdbg Print the debug information of a ip6_moptions structure
165 |
166 | inifa_trash Walk the list of trash in_ifaddr entries
167 | in6ifa_trash Walk the list of trash in6_ifaddr entries
168 | inm_trash Walk the list of trash in_multi entries
169 | in6m_trash Walk the list of trash in6_multi entries
170 | ifma_trash Walk the list of trash ifmultiaddr entries
171 |
172 | mbuf_walkpkt Walk the mbuf packet chain (m_nextpkt)
173 | mbuf_walk Walk the mbuf chain (m_next)
174 | mbuf_buf2slab Find the slab structure of the corresponding buffer
175 | mbuf_buf2mca Find the mcache audit structure of the corresponding mbuf
176 | mbuf_showmca Print the contents of an mbuf mcache audit structure
177 | mbuf_showactive Print all active/in-use mbuf objects
178 | mbuf_showinactive Print all freed/in-cache mbuf objects
179 | mbuf_showall Print all mbuf objects
180 | mbuf_slabs Print all slabs in the group
181 | mbuf_slabstbl Print slabs table
182 | mbuf_stat Print extended mbuf allocator statistics
183 | mbuf_countchain Count the length of an mbuf chain
184 | mbuf_topleak Print the top suspected mbuf leakers
185 | mbuf_traceleak Print the leak information for a given leak address
186 |
187 | mcache_walkobj Walk the mcache object chain (obj_next)
188 | mcache_stat Print all mcaches in the system
189 | mcache_showcache Display the number of objects in the cache
190 |
191 | showbootargs Display boot arguments passed to the target kernel
192 | showbootermemorymap Dump phys memory map from EFI
193 |
194 | systemlog Display the kernel's printf ring buffer
195 |
196 | hexdump Show the contents of memory as a hex/ASCII dump
197 |
198 | showvnodepath Print the path for a vnode
199 | showvnodelocks Display list of advisory locks held/blocked on a vnode
200 | showvnodedev Display information about a device vnode
201 | showtty Display information about a struct tty
202 | showallvols Display a summary of mounted volumes
203 | showvnode Display info about one vnode
204 | showvolvnodes Display info about all vnodes of a given volume
205 | showvolbusyvnodes Display info about busy (iocount!=0) vnodes of a given volume
206 | showallbusyvnodes Display info about all busy (iocount!=0) vnodes
207 | showallvnodes Display info about all vnodes
208 | print_vnode Print out the fields of a vnode struct
209 | showprocvnodes Print out all the open fds which are vnodes in a process
210 | showallprocvnodes Print out all the open fds which are vnodes in any process
211 | showmountvnodes Print the vnode list
212 | showmountallvnodes Print the vnode inactive list
213 | showworkqvnodes Print the vnode worker list
214 | shownewvnodes Print the new vnode list
215 |
216 | ifconfig display ifconfig-like output
217 | showifnets show the list of attached and detached interfaces
218 | showifaddrs show the list of addresses for the given ifp
219 | showifmultiaddrs show the list of multicast addresses for the given ifp
220 | showinmultiaddrs show the list of IPv4 multicast addresses records
221 | showin6multiaddrs show the list of IPv6 multicast addresses records
222 |
223 | showsocket Display information about a socket
224 | showprocsockets Given a proc_t pointer, display information about its sockets
225 | showallprocsockets Display information about the sockets of all the processes
226 |
227 | show_tcp_pcbinfo Display the list of the TCP protocol control blocks
228 | show_tcp_timewaitslots Display the list of the TCP protocol control blocks in TIMEWAIT
229 | show_udp_pcbinfo Display the list of UDP protocol control blocks
230 |
231 | show_rt_inet Display the IPv4 routing table
232 | show_rt_inet6 Display the IPv6 routing table
233 |
234 | showpmworkqueue Display the IOPMWorkQueue object
235 | showregistrypmstate Display power management state for all IOPower registry entries
236 | showioservicepm Display the IOServicePM object
237 | showstacksaftertask showallstacks starting after a given task
238 | showstacksafterthread showallstacks starting after a given thread
239 |
240 | showMCAstate Print machine-check register state after MC exception.
241 |
242 | showallgdbstacks Cause GDB to trace all thread stacks
243 | showallgdbcorestacks Corefile equivalent of "showallgdbstacks"
244 | kdp-reenter Schedule reentry into the debugger and continue.
245 | kdp-reboot Restart remote target
246 | kdp-version Get KDP version number
247 |
248 | zstack Print zalloc caller stack (zone leak debugging)
249 | findoldest Find oldest zone leak debugging record
250 | countpcs Print how often a pc occurs in the zone leak log
251 |
252 | showtopztrace Print the ztrace with the most outstanding allocated memory
253 | showztrace Print a backtrace record given its index
254 | showzalloc Print an allocation record + stacktrace at index
255 | showztraceaddr Print a backtrace record given its address
256 | showztracesabove Print all the backtrace records with a size bigger than X
257 | showzstacktrace Symbolicate and print a stored OSBacktrace
258 |
259 | showztraces Finds all in-use traces in the ztraces table
260 | showzallocs Finds all in-use allocations in the zallocs table
261 | showzstats Shows the statistics gathered about the hash tables
262 |
263 | showzallocsfortrace Print all the allocations that refer to a trace
264 | showztracehistogram Prints a histogram of the ztraces table
265 | showzallochistogram Prints a histogram of the zallocs table
266 |
267 | pmap_walk Perform a page-table walk
268 | pmap_vtop Translate a virtual address to physical address
269 |
270 | showuserdyldinfo Show dyld information and error messages
271 | in the target task
272 | showuserlibraries Show binary images known by dyld in the
273 | target task
274 | showallvmstats Prints a summary of vm statistics in a table format
275 | memstats Displays memory statistics in a table format
276 |
277 | showthreadfortid Displays the address of the thread structure
278 | for a given thread_id value.
279 |
280 | strcmp_nomalloc A version of strcmp that avoids the use of malloc
281 | through the use of encoded strings created via
282 | strcmp_arg_pack64.
283 | strcmp_arg_pack64 Pack a string into a 64-bit quantity for use by
284 | strcmp_nomalloc
285 |
286 | pci_cfg_read8 Read 8-bits from a PCI config space register
287 | pci_cfg_read16 Read 16-bits from a PCI config space register
288 | pci_cfg_read32 Read 32-bits from a PCI config space register
289 | pci_cfg_write8 Write 8-bits into a PCI config space register
290 | pci_cfg_write16 Write 16-bits into a PCI config space register
291 | pci_cfg_write32 Write 32-bits into a PCI config space register
292 | pci_cfg_dump Dump entire config space for a PCI device
293 | pci_cfg_scan Perform a scan for PCI devices
294 | pci_cfg_dump_all Dump config spaces for all detected PCI devices
295 |
296 | lapic_read32 Read APIC entry
297 | lapic_write32 Write APIC entry
298 | lapic_dump Dump APIC entries
299 |
300 | ioapic_read32 Read IOAPIC entry
301 | ioapic_write32 Write IOAPIC entry
302 | ioapic_dump Dump IOAPIC entries
303 |
304 | showallproviders Display summary listing of all dtrace_providers
305 | showallmodctls Display summary listing of all dtrace modctls
306 | showmodctl Display info about a dtrace modctl
307 | showfbtprobe Display info about an fbt probe given an id (traverses fbt_probetab)
308 | processortimers Display all processor timers, noting any inconsistencies
309 |
310 | Type "help <macro>" for more specific help on a particular macro.
311 | Type "show user <macro>" to see what the macro is really doing.
312 end
313
314 # This macro should appear before any symbol references, to facilitate
315 # a gdb "source" without a loaded symbol file.
316 define showversion
317 kdp-kernelversion
318 end
319
320 document showversion
321 Syntax: showversion
322 | Read the kernel version string from a fixed address in low
323 | memory. Useful if you don't know which kernel is on the other end,
324 | and need to find the appropriate symbols. Beware that if you've
325 | loaded a symbol file, but aren't connected to a remote target,
326 | the version string from the symbol file will be displayed instead.
327 | This macro expects to be connected to the remote kernel to function
328 | correctly.
329 end
330
331 set $kgm_mtype_ppc = 0x00000012
332 set $kgm_mtype_arm = 0x0000000C
333
334 set $kgm_mtype_i386 = 0x00000007
335 set $kgm_mtype_x86_64 = 0x01000007
336 set $kgm_mtype_x86_any = $kgm_mtype_i386
337 set $kgm_mtype_x86_mask = 0xFEFFFFFF
338
339 set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
340 set $kgm_lp64 = $kgm_mtype & 0x01000000
341
342 set $kgm_manual_pkt_ppc = 0x549C
343 set $kgm_manual_pkt_i386 = 0x249C
344 set $kgm_manual_pkt_x86_64 = 0xFFFFFF8000002930
345 set $kgm_manual_pkt_arm = 0xFFFF04A0
346
347 set $kgm_kdp_pkt_data_len = 128
348
349 # part of data packet
350 set $kgm_kdp_pkt_hdr_req_off = 0
351 set $kgm_kdp_pkt_hdr_seq_off = 1
352 set $kgm_kdp_pkt_hdr_len_off = 2
353 set $kgm_kdp_pkt_hdr_key_off = 4
354
355 # after data packet
356 set $kgm_kdp_pkt_len_off = $kgm_kdp_pkt_data_len
357 set $kgm_kdp_pkt_input_off = $kgm_kdp_pkt_data_len + 4
358
359 set $kgm_kdp_pkt_hostreboot = 0x13
360 set $kgm_kdp_pkt_hdr_size = 8
361
362
363 set $kgm_readphys_force_kdp = 0
364 set $kgm_readphys_force_physmap = 0
365
366 set $kgm_lcpu_self = 0xFFFE
367
368 set $kgm_reg_depth = 0
369 set $kgm_reg_depth_max = 0xFFFF
370 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
371 set $kgm_namekey = (OSSymbol *) 0
372 set $kgm_childkey = (OSSymbol *) 0
373
374 set $kgm_show_object_addrs = 0
375 set $kgm_show_object_retain = 0
376 set $kgm_show_props = 0
377 set $kgm_show_data_alwaysbytes = 0
378
379 set $kgm_show_kmod_syms = 0
380
381 # send a manual packet header that doesn't require knowing the location
382 # of everything.
383 define manualhdrint
384 set $req = $arg0
385
386 set $hdrp = (uint32_t *) $kgm_manual_pkt_i386
387 if ($kgm_mtype == $kgm_mtype_ppc)
388 set $hdrp = (uint32_t *) $kgm_manual_pkt_ppc
389 set $req = $req << 1 # shift to deal with endiannness
390 end
391 if ($kgm_mtype == $kgm_mtype_x86_64)
392 set $hdrp = (uint64_t *) $kgm_manual_pkt_x86_64
393 end
394 if ($kgm_mtype == $kgm_mtype_arm)
395 set $hdrp = (uint32_t *) $kgm_manual_pkt_arm
396 end
397
398 set $pkt_hdr = *$hdrp
399 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off)) = 0
400 set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_len_off)) = $kgm_kdp_pkt_hdr_size
401
402 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_req_off)) = $req
403 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_seq_off)) = 0
404 set *((uint16_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_len_off)) = $kgm_kdp_pkt_hdr_size
405 set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_key_off)) = 0
406 set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off)) = 1
407
408 # dummy to make sure manual packet is executed
409 set $kgm_dummy = &_mh_execute_header
410 end
411
412 # Print a pointer
413 define showptr
414 if $kgm_lp64
415 printf "0x%016llx", $arg0
416 else
417 printf "0x%08x", $arg0
418 end
419 end
420
421 # for headers, leave 8 chars for LP64 pointers
422 define showptrhdrpad
423 if $kgm_lp64
424 printf " "
425 end
426 end
427
428 # Print a userspace pointer, using $kgm_tasp
429 define showuserptr
430 set $kgm_userptr_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
431 if $kgm_userptr_task_64
432 printf "0x%016llx", $arg0
433 else
434 printf "0x%08x", $arg0
435 end
436 end
437
438 define showkmodheader
439 printf "kmod_info "
440 showptrhdrpad
441 printf " address "
442 showptrhdrpad
443 printf " size "
444 showptrhdrpad
445 printf " id refs version name\n"
446 end
447
448 define showkmodint
449 set $kgm_kmodp = (struct kmod_info *)$arg0
450 showptr $kgm_kmodp
451 printf " "
452 showptr $kgm_kmodp->address
453 printf " "
454 showptr $kgm_kmodp->size
455 printf " "
456 printf "%3d ", $kgm_kmodp->id
457 printf "%5d ", $kgm_kmodp->reference_count
458 printf "%10s ", $kgm_kmodp->version
459 printf "%s\n", $kgm_kmodp->name
460 end
461
462 # cached info of the last kext found, to speed up subsequent lookups
463 set $kgm_pkmod = 0
464 set $kgm_pkmodst = 0
465 set $kgm_pkmoden = 0
466
467 define showkmodaddrint
468 showptr $arg0
469 if ((unsigned long)$arg0 >= (unsigned long)$kgm_pkmodst) && ((unsigned long)$arg0 < (unsigned long)$kgm_pkmoden)
470 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_pkmodst)
471 printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off
472 else
473 set $kgm_kmodp = (struct kmod_info *)kmod
474 if ($kgm_mtype == $kgm_mtype_x86_64) && ($arg0 >= (unsigned long)&_mh_execute_header)
475 # kexts are loaded below the kernel for x86_64
476 set $kgm_kmodp = 0
477 end
478 while $kgm_kmodp
479 set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_kmodp->address)
480 if ($kgm_kmodp->address <= $arg0) && ($kgm_off < $kgm_kmodp->size)
481 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off
482 set $kgm_pkmod = $kgm_kmodp
483 set $kgm_pkmodst = $kgm_kmodp->address
484 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmodp->size
485 set $kgm_kmodp = 0
486 else
487 set $kgm_kmodp = $kgm_kmodp->next
488 end
489 end
490 end
491 end
492
493 define showkmodaddr
494 showkmodaddrint $arg0
495 end
496 document showkmodaddr
497 Syntax: (gdb) showkmodaddr <addr>
498 | Given an address, print the offset and name for the kmod containing it
499 end
500
501 define showkmod
502 showkmodheader
503 showkmodint $arg0
504 end
505 document showkmod
506 Syntax: (gdb) showkmod <kmod>
507 | Routine to print info about a kext
508 end
509
510 define showkext
511 showkmod $arg0
512 end
513 document showkext
514 Syntax: (gdb) showkext <kmod_info_address>
515 | Routine to print info about a kext
516 end
517
518 define showallkmods
519 showkmodheader
520 set $kgm_kmodp = (struct kmod_info *)kmod
521 while $kgm_kmodp
522 showkmodint $kgm_kmodp
523 set $kgm_kmodp = $kgm_kmodp->next
524 end
525 end
526 document showallkmods
527 Syntax: (gdb) showallkmods
528 | Routine to print a summary listing of all loaded kexts
529 end
530
531 define showallkexts
532 showallkmods
533 end
534 document showallkexts
535 Syntax: (gdb) showallkexts
536 | Routine to print a summary listing of all loaded kexts
537 end
538
539 # See OSKextVersion.c for the C code this is based on
540 #
541 set $KGM_OSKEXT_VERS_MAJ_MULT = 100000000
542 set $KGM_OSKEXT_VERS_MIN_MULT = 1000000
543 set $KGM_OSKEXT_VERS_REV_MULT = 10000
544 set $KGM_OSKEXT_VERS_STAGE_MULT = 1000
545
546 define printoskextversion
547 set $vers_scratch = $arg0
548
549 if ($vers_scratch == -1)
550 printf "(invalid)"
551 else
552
553 set $vers_major = $vers_scratch / $KGM_OSKEXT_VERS_MAJ_MULT
554
555 set $vers_scratch = $vers_scratch - ($vers_major * $KGM_OSKEXT_VERS_MAJ_MULT)
556 set $vers_minor = $vers_scratch / $KGM_OSKEXT_VERS_MIN_MULT
557
558 set $vers_scratch = $vers_scratch - ( $vers_minor * $KGM_OSKEXT_VERS_MIN_MULT)
559 set $vers_revision = $vers_scratch / $KGM_OSKEXT_VERS_REV_MULT
560
561 set $vers_scratch = $vers_scratch - ( $vers_revision * $KGM_OSKEXT_VERS_REV_MULT)
562 set $vers_stage = $vers_scratch / $KGM_OSKEXT_VERS_STAGE_MULT
563
564 set $vers_scratch = $vers_scratch - ( $vers_stage * $KGM_OSKEXT_VERS_STAGE_MULT)
565 set $vers_stagelevel = $vers_scratch
566
567 printf "%d.%d", $vers_major, $vers_minor
568 if ($vers_revision > 0)
569 printf ".%d", $vers_revision
570 end
571
572 if ($vers_stage == 1)
573 printf "d"
574 end
575 if ($vers_stage == 3)
576 printf "a"
577 end
578 if ($vers_stage == 5)
579 printf "b"
580 end
581 if ($vers_stage == 7)
582 printf "fc"
583 end
584 if ($vers_stage == 1 || $vers_stage == 3 || $vers_stage == 5 || $vers_stage == 7)
585 printf "%d", $vers_stagelevel
586 end
587 end
588 end
589
590 define showallknownkexts
591 set $kext_count = sKextsByID->count
592 set $kext_index = 0
593 printf "%d kexts in sKextsByID:\n", $kext_count
594
595 printf "OSKext * "
596 showptrhdrpad
597 printf "load_addr "
598 showptrhdrpad
599
600 printf " id name (version)\n"
601
602 while $kext_index < $kext_count
603 set $kext_id = sKextsByID->dictionary[$kext_index].key->string
604 set $oskext = (OSKext *)sKextsByID->dictionary[$kext_index].value
605
606 showptr $oskext
607 printf " "
608
609 if ($oskext->flags.loaded)
610 showptr $oskext->kmod_info
611 printf " "
612 printf "%3d", $oskext->loadTag
613 else
614 showptrhdrpad
615 printf " -------- "
616 printf " "
617 printf " --"
618 end
619 printf " "
620
621 printf "%.64s (", $kext_id
622 printoskextversion (uint64_t)$oskext->version
623 printf ")\n"
624 set $kext_index = $kext_index + 1
625 end
626 end
627 document showallknownkexts
628 Syntax: (gdb) showallknownkexts
629 | Routine to print a summary listing of all kexts, loaded or not
630 end
631
632 define showactheader
633 printf " "
634 showptrhdrpad
635 printf " thread "
636 showptrhdrpad
637 printf " thread_id "
638 showptrhdrpad
639 printf " processor "
640 showptrhdrpad
641 printf " pri io_policy state wait_queue"
642 showptrhdrpad
643 printf " wait_event\n"
644 end
645
646
647 define showactint
648 printf " "
649 showptrhdrpad
650 set $kgm_thread = *(struct thread *)$arg0
651 showptr $arg0
652 if ($kgm_thread.static_param)
653 printf "[WQ]"
654 else
655 printf " "
656 end
657 printf " 0x%llx ", $kgm_thread.thread_id
658 showptr $kgm_thread.last_processor
659 printf " %3d ", $kgm_thread.sched_pri
660 if ($kgm_thread.uthread != 0)
661 set $kgm_printed = 0
662 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
663 if ($kgm_uthread->uu_flag & 0x400)
664 printf "RAGE "
665 else
666 printf " "
667 end
668 set $diskpolicy = 0
669 if ($kgm_thread->ext_actionstate.hw_disk != 0)
670 set $diskpolicy = $kgm_thread->ext_actionstate.hw_disk
671 else
672 if ($kgm_thread->actionstate.hw_disk != 0)
673 set $diskpolicy = $kgm_thread->actionstate.hw_disk
674 end
675 end
676 if ($kgm_thread->ext_actionstate.hw_bg != 0)
677 set $diskpolicy = 5
678 end
679 if ($kgm_thread->actionstate.hw_bg != 0)
680 set $diskpolicy = 4
681 end
682 if ($diskpolicy == 2)
683 printf "PASS "
684 set $kgm_printed = 1
685 end
686 if ($diskpolicy == 3)
687 printf "THROT "
688 set $kgm_printed = 1
689 end
690 if ($diskpolicy == 4)
691 printf "BG_THRT "
692 set $kgm_printed = 1
693 end
694 if ($diskpolicy == 5)
695 printf "EBG_THRT"
696 set $kgm_printed = 1
697 end
698 if ($kgm_printed == 0)
699 printf " "
700 end
701 end
702 set $kgm_state = $kgm_thread.state
703 if $kgm_state & 0x80
704 printf "I"
705 end
706 if $kgm_state & 0x40
707 printf "P"
708 end
709 if $kgm_state & 0x20
710 printf "A"
711 end
712 if $kgm_state & 0x10
713 printf "H"
714 end
715 if $kgm_state & 0x08
716 printf "U"
717 end
718 if $kgm_state & 0x04
719 printf "R"
720 end
721 if $kgm_state & 0x02
722 printf "S"
723 end
724 if $kgm_state & 0x01
725 printf "W"
726 printf "\t "
727 showptr $kgm_thread.wait_queue
728 printf " "
729 if (((unsigned long)$kgm_thread.wait_event > (unsigned long)&last_kernel_symbol) \
730 && ($arg1 != 2) && ($kgm_show_kmod_syms == 0))
731 showkmodaddr $kgm_thread.wait_event
732 else
733 output /a $kgm_thread.wait_event
734 end
735 if ($kgm_thread.uthread != 0)
736 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
737 if ($kgm_uthread->uu_wmesg != 0)
738 printf "\t \"%s\"", $kgm_uthread->uu_wmesg
739 end
740 end
741 end
742 if ($kgm_thread.uthread != 0)
743 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
744 if ($kgm_uthread->pth_name && $kgm_uthread->pth_name[0])
745 printf "\n\t\tThread Name: %s", $kgm_uthread->pth_name
746 end
747 end
748 if $arg1 != 0
749 if ($kgm_thread.kernel_stack != 0)
750 if ($kgm_thread.uthread != 0)
751 printf "\n "
752 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
753 if ($kgm_uthread->uu_kwe.kwe_kwqqueue != 0)
754 set $kwq = (ksyn_wait_queue_t)$kgm_uthread->uu_kwe.kwe_kwqqueue
755 printf " kwq_lockcount:0x%x; kwq_retval:0x%x", $kgm_uthread->uu_kwe.kwe_lockseq, $kgm_uthread->uu_kwe.kwe_psynchretval
756 printf "\n "
757 show_kwq $kwq
758 printf " "
759 end
760 end
761 if ($kgm_thread.reserved_stack != 0)
762 printf "\n "
763 showptrhdrpad
764 printf " reserved_stack="
765 showptr $kgm_thread.reserved_stack
766 end
767 printf "\n "
768 showptrhdrpad
769 printf " kernel_stack="
770 showptr $kgm_thread.kernel_stack
771 if ($kgm_mtype == $kgm_mtype_ppc)
772 set $mysp = $kgm_thread.machine.pcb->save_r1
773 end
774 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
775 set $kgm_statep = (struct x86_kernel_state *) \
776 ($kgm_thread->kernel_stack + kernel_stack_size \
777 - sizeof(struct x86_kernel_state))
778 if ($kgm_mtype == $kgm_mtype_i386)
779 set $mysp = $kgm_statep->k_ebp
780 else
781 set $mysp = $kgm_statep->k_rbp
782 end
783 end
784 if ($kgm_mtype == $kgm_mtype_arm)
785 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
786 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
787 set $mysp = $r7
788 else
789 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
790 set $mysp = $kgm_statep->r[7]
791 end
792 end
793 set $prevsp = $mysp - 16
794 printf "\n "
795 showptrhdrpad
796 printf " stacktop="
797 showptr $mysp
798 if ($kgm_mtype == $kgm_mtype_ppc)
799 set $stkmask = 0xf
800 else
801 set $stkmask = 0x3
802 end
803 set $kgm_return = 0
804 set $kgm_actint_framecount = 0
805 while ($mysp != 0) && (($mysp & $stkmask) == 0) \
806 && ($mysp != $prevsp) \
807 && ((((unsigned long) $mysp ^ (unsigned long) $prevsp) < 0x2000) \
808 || (((unsigned long)$mysp < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
809 && ((unsigned long)$mysp > (unsigned long) ($kgm_thread->kernel_stack)))) \
810 && ($kgm_actint_framecount < 128)
811 printf "\n "
812 set $kgm_actint_framecount = $kgm_actint_framecount + 1
813 showptrhdrpad
814 printf " "
815 showptr $mysp
816 printf " "
817 if ($kgm_mtype == $kgm_mtype_ppc)
818 set $kgm_return = *($mysp + 8)
819 end
820 if ($kgm_mtype == $kgm_mtype_i386)
821 set $kgm_return = *($mysp + 4)
822 end
823 if ($kgm_mtype == $kgm_mtype_x86_64)
824 set $kgm_return = *(unsigned long *)($mysp + 8)
825 end
826 if ($kgm_mtype == $kgm_mtype_arm)
827 set $kgm_return = *($mysp + 4)
828 end
829 if (((unsigned long) $kgm_return < (unsigned long) &_mh_execute_header || \
830 (unsigned long) $kgm_return >= (unsigned long) &last_kernel_symbol ) \
831 && ($kgm_show_kmod_syms == 0))
832 showkmodaddr $kgm_return
833 else
834 output /a $kgm_return
835 end
836 set $prevsp = $mysp
837 set $mysp = *(unsigned long *)$mysp
838 end
839 set $kgm_return = 0
840 printf "\n "
841 showptrhdrpad
842 printf " stackbottom="
843 showptr $prevsp
844 else
845 printf "\n "
846 showptrhdrpad
847 printf " continuation="
848 output /a $kgm_thread.continuation
849 end
850 printf "\n"
851 else
852 printf "\n"
853 end
854 end
855
856 define showact
857 showactheader
858 showactint $arg0 0
859 end
860 document showact
861 Syntax: (gdb) showact <activation>
862 | Routine to print out the state of a specific thread.
863 end
864
865
866 define showactstack
867 showactheader
868 showactint $arg0 1
869 end
870 document showactstack
871 Syntax: (gdb) showactstack <activation>
872 | Routine to print out the stack of a specific thread.
873 end
874
875
876 define showallthreads
877 set $kgm_head_taskp = &tasks
878 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
879 while $kgm_taskp != $kgm_head_taskp
880 showtaskheader
881 showtaskint $kgm_taskp
882 showactheader
883 set $kgm_head_actp = &($kgm_taskp->threads)
884 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
885 while $kgm_actp != $kgm_head_actp
886 showactint $kgm_actp 0
887 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
888 end
889 printf "\n"
890 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
891 end
892 end
893 document showallthreads
894 Syntax: (gdb) showallthreads
895 | Routine to print out info about all threads in the system.
896 end
897
898 define showprocessorint
899 set $kgm_processor_int = (struct processor *)$arg0
900 printf "Processor "
901 showptr $kgm_processor_int
902 printf " State %d (cpu_id 0x%x)\n", ($kgm_processor_int)->state, ($kgm_processor_int)->cpu_id
903 end
904
905 define showcurrentthreads
906 set $kgm_prp = (struct processor *)processor_list
907 while $kgm_prp != 0
908 showprocessorint $kgm_prp
909 if ($kgm_prp)->active_thread != 0
910 set $kgm_actp = ($kgm_prp)->active_thread
911 showtaskheader
912 showtaskint ($kgm_actp)->task
913 showactheader
914 showactint $kgm_actp 0
915 printf "\n"
916 end
917 set $kgm_prp = ($kgm_prp)->processor_list
918 end
919 end
920 document showcurrentthreads
921 Syntax: (gdb) showcurrentthreads
922 | Routine to print out info about the thread running on each cpu.
923 end
924
925
926 define _showrunqint
927 set $kgm_runq = (struct run_queue *)$arg0
928
929 printf " Priority Run Queue Info: Count %d\n", $kgm_runq->count
930 set $kgm_runq_queue_i = 0
931 set $kgm_runq_queue_count = sizeof($kgm_runq->queues)/sizeof($kgm_runq->queues[0])
932 while $kgm_runq->count && $kgm_runq_queue_i < $kgm_runq_queue_count
933 set $kgm_runq_queue_head = &$kgm_runq->queues[$kgm_runq_queue_i]
934 set $kgm_runq_queue_p = $kgm_runq_queue_head->next
935 if $kgm_runq_queue_p != $kgm_runq_queue_head
936 set $kgm_runq_queue_this_count = 0
937 while $kgm_runq_queue_p != $kgm_runq_queue_head
938 set $kgm_runq_queue_this_count = $kgm_runq_queue_this_count + 1
939 showtask ((thread_t)$kgm_runq_queue_p)->task
940 showactstack $kgm_runq_queue_p
941 set $kgm_runq_queue_p = $kgm_runq_queue_p->next
942 end
943 printf " Queue Priority %3d [", $kgm_runq_queue_i
944 showptr $kgm_runq_queue_head
945 printf "] Count %d\n", $kgm_runq_queue_this_count
946 end
947 set $kgm_runq_queue_i = $kgm_runq_queue_i + 1
948 end
949
950 end
951
952 define _showgrrrint
953 set $kgm_grrr_runq = $arg0
954
955 printf " GRRR Info: Count %d Weight %d Current Group ", $kgm_grrr_runq->count, $kgm_grrr_runq->weight
956 showptr $kgm_grrr_runq->current_group
957 printf "\n"
958 set $kgm_grrr_group_i = 0
959 set $kgm_grrr_group_count = sizeof($kgm_grrr_runq->groups)/sizeof($kgm_grrr_runq->groups[0])
960 while $kgm_grrr_runq->count && $kgm_grrr_group_i < $kgm_grrr_group_count
961 set $kgm_grrr_group = &$kgm_grrr_runq->groups[$kgm_grrr_group_i]
962 if $kgm_grrr_group->count > 0
963 printf " Group %3d [", $kgm_grrr_group->index
964 showptr $kgm_grrr_group
965 printf "] Count %d Weight %d\n", $kgm_grrr_group->count, $kgm_grrr_group->weight
966 set $kgm_grrr_group_client_head = &$kgm_grrr_group->clients
967 set $kgm_grrr_group_client = $kgm_grrr_group_client_head->next
968 while $kgm_grrr_group_client != $kgm_grrr_group_client_head
969 # showtask ((thread_t)$kgm_grrr_group_client)->task
970 # showactstack $kgm_grrr_group_client
971 set $kgm_grrr_group_client = $kgm_grrr_group_client->next
972 end
973 end
974 set $kgm_grrr_group_i = $kgm_grrr_group_i + 1
975 end
976 end
977
978 define showallprocessors
979 set $kgm_pset = &pset0
980
981 set $kgm_show_grrr = 0
982 set $kgm_show_priority_runq = 0
983 set $kgm_show_priority_pset_runq = 0
984 set $kgm_show_fairshare_grrr = 0
985 set $kgm_show_fairshare_list = 0
986
987 if _sched_enum == 1
988 set $kgm_show_priority_runq = 1
989 set $kgm_show_fairshare_list = 1
990 end
991 if _sched_enum == 2
992 set $kgm_show_priority_pset_runq = 1
993 set $kgm_show_fairshare_list = 1
994 end
995 if _sched_enum == 4
996 set $kgm_show_grrr = 1
997 set $kgm_show_fairshare_grrr = 1
998 end
999 if _sched_enum == 5
1000 set $kgm_show_priority_runq = 1
1001 set $kgm_show_fairshare_list = 1
1002 end
1003 if _sched_enum == 6
1004 set $kgm_show_priority_pset_runq = 1
1005 set $kgm_show_fairshare_list = 1
1006 end
1007
1008 while $kgm_pset != 0
1009 printf "Processor Set "
1010 showptr $kgm_pset
1011 printf " Count %d (cpu_id 0x%x-0x%x)\n", ($kgm_pset)->cpu_set_count, ($kgm_pset)->cpu_set_low, ($kgm_pset)->cpu_set_hi
1012 printf " Active Processors:\n"
1013 set $kgm_active_queue_head = &($kgm_pset)->active_queue
1014 set $kgm_active_elt = $kgm_active_queue_head->next
1015 while $kgm_active_elt != $kgm_active_queue_head
1016 set $kgm_processor = (processor_t)$kgm_active_elt
1017 printf " "
1018 showprocessorint $kgm_processor
1019
1020 if $kgm_show_priority_runq
1021 set $kgm_runq = &$kgm_processor->runq
1022 _showrunqint $kgm_runq
1023 end
1024 if $kgm_show_grrr
1025 set $kgm_grrr_runq = &$kgm_processor->grrr_runq
1026 _showgrrrint $kgm_grrr_runq
1027 end
1028
1029 if $kgm_processor->processor_meta != 0 && $kgm_processor->processor_meta->primary == $kgm_processor
1030 set $kgm_processor_meta_idle_head = &$kgm_processor->processor_meta->idle_queue
1031 set $kgm_processor_meta_idle = $kgm_processor_meta_idle_head->next
1032 while $kgm_processor_meta_idle != $kgm_processor_meta_idle_head
1033 printf " Idle Meta Processor: "
1034 showprocessorint $kgm_processor_meta_idle
1035 set $kgm_processor_meta_idle = $kgm_processor_meta_idle->next
1036 end
1037 end
1038
1039 set $kgm_active_elt = $kgm_active_elt->next
1040 end
1041 printf " Idle Processors:\n"
1042 set $kgm_idle_queue_head = &($kgm_pset)->idle_queue
1043 set $kgm_idle_elt = $kgm_idle_queue_head->next
1044 while $kgm_idle_elt != $kgm_idle_queue_head
1045 set $kgm_processor = (processor_t)$kgm_idle_elt
1046 printf " "
1047 showprocessorint $kgm_processor
1048
1049 if $kgm_processor->processor_meta != 0 && $kgm_processor->processor_meta->primary == $kgm_processor
1050 set $kgm_processor_meta_idle_head = &$kgm_processor->processor_meta->idle_queue
1051 set $kgm_processor_meta_idle = $kgm_processor_meta_idle_head->next
1052 while $kgm_processor_meta_idle != $kgm_processor_meta_idle_head
1053 printf " Idle Meta Processor: "
1054 showprocessorint $kgm_processor_meta_idle
1055 set $kgm_processor_meta_idle = $kgm_processor_meta_idle->next
1056 end
1057 end
1058
1059 set $kgm_idle_elt = $kgm_idle_elt->next
1060 end
1061
1062 if $kgm_show_priority_pset_runq
1063 set $kgm_runq = &$kgm_pset->pset_runq
1064 printf "\n"
1065 _showrunqint $kgm_runq
1066 end
1067 set $kgm_pset = ($kgm_pset)->pset_list
1068 end
1069
1070 printf "\n"
1071 printf "Realtime Queue Count %d\n", rt_runq.count
1072 set $kgm_rt_runq_head = &rt_runq.queue
1073 set $kgm_rt_runq = $kgm_rt_runq_head->next
1074 while $kgm_rt_runq != $kgm_rt_runq_head
1075 showtask ((thread_t)$kgm_rt_runq)->task
1076 showact $kgm_rt_runq
1077 set $kgm_rt_runq = $kgm_rt_runq->next
1078 end
1079
1080 printf "\n"
1081 if $kgm_show_fairshare_list
1082 printf "Fair Share Queue Count %d\n", fs_runq.count
1083 set $kgm_fs_runq_head = &fs_runq.queue
1084 set $kgm_fs_runq = $kgm_fs_runq_head->next
1085 while $kgm_fs_runq != $kgm_fs_runq_head
1086 showtask ((thread_t)$kgm_fs_runq)->task
1087 showact $kgm_fs_runq
1088 set $kgm_fs_runq = $kgm_fs_runq->next
1089 end
1090 end
1091 if $kgm_show_fairshare_grrr
1092 printf "Fair Share Queue Count %d\n", fs_grrr_runq.count
1093 set $kgm_fs_grrr = &fs_grrr_runq
1094 _showgrrrint $kgm_fs_grrr
1095 end
1096 end
1097 document showallprocessors
1098 Syntax: (gdb) showallprocessors
1099 | Routine to print out info about all psets and processors
1100 end
1101
1102 set $decode_wait_events = 0
1103 define showallstacks
1104 set $kgm_head_taskp = &tasks
1105 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1106 while $kgm_taskp != $kgm_head_taskp
1107 showtaskheader
1108 showtaskint $kgm_taskp
1109 set $kgm_head_actp = &($kgm_taskp->threads)
1110 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1111 while $kgm_actp != $kgm_head_actp
1112 showactheader
1113 if ($decode_wait_events > 0)
1114 showactint $kgm_actp 1
1115 else
1116 showactint $kgm_actp 2
1117 end
1118 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1119 end
1120 printf "\n"
1121 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1122 end
1123
1124 printf "\nZombie Processes:\n"
1125 zombstacks
1126 end
1127
1128 document showallstacks
1129 Syntax: (gdb) showallstacks
1130 | Routine to print out the stack for each thread in the system.
1131 | If the variable $decode_wait_events is non-zero, the routine attempts to
1132 | interpret thread wait_events as kernel module offsets, which can add to
1133 | processing time.
1134 end
1135
1136 define showcurrentstacks
1137 set $kgm_prp = processor_list
1138 while $kgm_prp != 0
1139 showprocessorint $kgm_prp
1140 if ($kgm_prp)->active_thread != 0
1141 set $kgm_actp = ($kgm_prp)->active_thread
1142 showtaskheader
1143 showtaskint ($kgm_actp)->task
1144 showactheader
1145 showactint $kgm_actp 1
1146 printf "\n"
1147 end
1148 set $kgm_prp = ($kgm_prp)->processor_list
1149 end
1150 end
1151
1152 document showcurrentstacks
1153 Syntax: (gdb) showcurrentstacks
1154 | Routine to print out the thread running on each cpu (incl. its stack)
1155 end
1156
1157 define showwaiterheader
1158 printf "waiters thread "
1159 printf "processor pri state wait_queue wait_event\n"
1160 end
1161
1162 define showwaitqwaiters
1163 set $kgm_w_waitqp = (WaitQueue*)$arg0
1164 set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue)
1165 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_linksp->next
1166 set $kgm_w_found = 0
1167 while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp)
1168 if ($kgm_w_wqe->wqe_type != &_wait_queue_link)
1169 if !$kgm_w_found
1170 set $kgm_w_found = 1
1171 showwaiterheader
1172 end
1173 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe
1174 showactint $kgm_w_shuttle 0
1175 end
1176 set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_wqe->wqe_links.next
1177 end
1178 end
1179
1180 define showwaitqwaitercount
1181 set $kgm_wc_waitqp = (WaitQueue*)$arg0
1182 set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue)
1183 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_linksp->next
1184 set $kgm_wc_count = 0
1185 while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp)
1186 if ($kgm_wc_wqe->wqe_type != &_wait_queue_link)
1187 set $kgm_wc_count = $kgm_wc_count + 1
1188 end
1189 set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_wqe->wqe_links.next
1190 end
1191 printf "0x%08x ", $kgm_wc_count
1192 end
1193
1194 define showwaitqmembercount
1195 set $kgm_mc_waitqsetp = (WaitQueueSet*)$arg0
1196 set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks)
1197 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_setlinksp->next
1198 set $kgm_mc_count = 0
1199 while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp)
1200 set $kgm_mc_count = $kgm_mc_count + 1
1201 set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_wql->wql_setlinks.next
1202 end
1203 printf "0x%08x ", $kgm_mc_count
1204 end
1205
1206
1207 define showwaitqmemberheader
1208 printf "set-members wait_queue interlock "
1209 printf "pol type member_cnt waiter_cnt\n"
1210 end
1211
1212 define showwaitqmemberint
1213 set $kgm_m_waitqp = (WaitQueue*)$arg0
1214 printf " 0x%08x ", $kgm_m_waitqp
1215 printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data
1216 if ($kgm_m_waitqp->wq_fifo)
1217 printf "Fifo "
1218 else
1219 printf "Prio "
1220 end
1221 if ($kgm_m_waitqp->wq_type == 0xf1d1)
1222 printf "Set "
1223 showwaitqmembercount $kgm_m_waitqp
1224 else
1225 printf "Que 0x00000000 "
1226 end
1227 showwaitqwaitercount $kgm_m_waitqp
1228 printf "\n"
1229 end
1230
1231
1232 define showwaitqmemberofheader
1233 printf "member-of wait_queue interlock "
1234 printf "pol type member_cnt waiter_cnt\n"
1235 end
1236
1237 define showwaitqmemberof
1238 set $kgm_mo_waitqp = (WaitQueue*)$arg0
1239 set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue)
1240 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_linksp->next
1241 set $kgm_mo_found = 0
1242 while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp)
1243 if ($kgm_mo_wqe->wqe_type == &_wait_queue_link)
1244 if !$kgm_mo_found
1245 set $kgm_mo_found = 1
1246 showwaitqmemberofheader
1247 end
1248 set $kgm_mo_wqlp = (WaitQueueLink *)$kgm_mo_wqe
1249 set $kgm_mo_wqsetp = (WaitQueue*)($kgm_mo_wqlp->wql_setqueue)
1250 showwaitqmemberint $kgm_mo_wqsetp
1251 end
1252 set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_wqe->wqe_links.next
1253 end
1254 end
1255
1256 define showwaitqmembers
1257 set $kgm_ms_waitqsetp = (WaitQueueSet*)$arg0
1258 set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks)
1259 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_setlinksp->next
1260 set $kgm_ms_found = 0
1261 while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp)
1262 set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue
1263 if !$kgm_ms_found
1264 showwaitqmemberheader
1265 set $kgm_ms_found = 1
1266 end
1267 showwaitqmemberint $kgm_ms_waitqp
1268 set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_wql->wql_setlinks.next
1269 end
1270 end
1271
1272 define showwaitqheader
1273 printf "wait_queue ref_count interlock "
1274 printf "pol type member_cnt waiter_cnt\n"
1275 end
1276
1277 define showwaitqint
1278 set $kgm_waitqp = (WaitQueue*)$arg0
1279 printf "0x%08x ", $kgm_waitqp
1280 if ($kgm_waitqp->wq_type == 0xf1d1)
1281 printf "0x%08x ", ((WaitQueueSet*)$kgm_waitqp)->wqs_refcount
1282 else
1283 printf "0x00000000 "
1284 end
1285 printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data
1286 if ($kgm_waitqp->wq_fifo)
1287 printf "Fifo "
1288 else
1289 printf "Prio "
1290 end
1291 if ($kgm_waitqp->wq_type == 0xf1d1)
1292 printf "Set "
1293 showwaitqmembercount $kgm_waitqp
1294 else
1295 printf "Que 0x00000000 "
1296 end
1297 showwaitqwaitercount $kgm_waitqp
1298 printf "\n"
1299 end
1300
1301 define showwaitq
1302 set $kgm_waitq1p = (WaitQueue*)$arg0
1303 showwaitqheader
1304 showwaitqint $kgm_waitq1p
1305 if ($kgm_waitq1p->wq_type == 0xf1d1)
1306 showwaitqmembers $kgm_waitq1p
1307 else
1308 showwaitqmemberof $kgm_waitq1p
1309 end
1310 showwaitqwaiters $kgm_waitq1p
1311 end
1312
1313 define showmapheader
1314 printf "vm_map "
1315 showptrhdrpad
1316 printf " pmap "
1317 showptrhdrpad
1318 printf " vm_size "
1319 showptrhdrpad
1320 printf " #ents rpage hint "
1321 showptrhdrpad
1322 printf " first_free\n"
1323 end
1324
1325 define showvmeheader
1326 printf " entry "
1327 showptrhdrpad
1328 printf " start prot #page object "
1329 showptrhdrpad
1330 printf " offset\n"
1331 end
1332
1333 define showvmint
1334 set $kgm_mapp = (vm_map_t)$arg0
1335 set $kgm_map = *$kgm_mapp
1336 showptr $arg0
1337 printf " "
1338 showptr $kgm_map.pmap
1339 printf " "
1340 showptr $kgm_map.size
1341 printf " %3d ", $kgm_map.hdr.nentries
1342 if $kgm_map.pmap
1343 printf "%5d ", $kgm_map.pmap->stats.resident_count
1344 else
1345 printf "<n/a> "
1346 end
1347 showptr $kgm_map.hint
1348 printf " "
1349 showptr $kgm_map.first_free
1350 printf "\n"
1351 if $arg1 != 0
1352 showvmeheader
1353 set $kgm_head_vmep = &($kgm_mapp->hdr.links)
1354 set $kgm_vmep = $kgm_map.hdr.links.next
1355 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
1356 set $kgm_vme = *$kgm_vmep
1357 printf " "
1358 showptr $kgm_vmep
1359 printf " 0x%016llx ", $kgm_vme.links.start
1360 printf "%1x", $kgm_vme.protection
1361 printf "%1x", $kgm_vme.max_protection
1362 if $kgm_vme.inheritance == 0x0
1363 printf "S"
1364 end
1365 if $kgm_vme.inheritance == 0x1
1366 printf "C"
1367 end
1368 if $kgm_vme.inheritance == 0x2
1369 printf "-"
1370 end
1371 if $kgm_vme.inheritance == 0x3
1372 printf "D"
1373 end
1374 if $kgm_vme.is_sub_map
1375 printf "s "
1376 else
1377 if $kgm_vme.needs_copy
1378 printf "n "
1379 else
1380 printf " "
1381 end
1382 end
1383 printf "%6d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
1384 showptr $kgm_vme.object.vm_object
1385 printf " 0x%016llx\n", $kgm_vme.offset
1386 set $kgm_vmep = $kgm_vme.links.next
1387 end
1388 end
1389 printf "\n"
1390 end
1391
1392
1393 define showmapwiredp
1394 set $kgm_mapp = (vm_map_t)$arg0
1395 set $kgm_map = *$kgm_mapp
1396 set $kgm_head_vmep = &($kgm_mapp->hdr.links)
1397 set $kgm_vmep = $kgm_map.hdr.links.next
1398 set $kgm_objp_prev = (struct vm_object *)0
1399 if $arg1 == 0
1400 set $kgm_saw_kernel_obj = 0
1401 set $kgm_wired_count = 0
1402 set $kgm_objp_print_space = 1
1403 else
1404 set $kgm_objp_print_space = 0
1405 end
1406 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
1407 set $kgm_vme = *$kgm_vmep
1408 set $kgm_objp = $kgm_vme.object.vm_object
1409 if $kgm_vme.is_sub_map
1410 if $arg1 == 0
1411 set $kgm_mapp_orig = $kgm_mapp
1412 set $kgm_vmep_orig = $kgm_vmep
1413 set $kgm_vme_orig = $kgm_vme
1414 set $kgm_head_vmep_orig = $kgm_head_vmep
1415 printf "\n****"
1416 showptr $kgm_objp
1417 showmapwiredp $kgm_objp 1
1418 set $kgm_vme = $kgm_vme_orig
1419 set $kgm_vmep = $kgm_vmep_orig
1420 set $kgm_mapp = $kgm_mapp_orig
1421 set $kgm_head_vmep = $kgm_head_vmep_orig
1422 set $kgm_objp = (struct vm_object *)0
1423 else
1424 printf "\n????"
1425 showptr $kgm_mapp
1426 printf " "
1427 showptr $kgm_vmep
1428 set $kgm_objp = (struct vm_object *)0
1429 printf "\n"
1430 end
1431 end
1432 if ($kgm_objp == $kgm_objp_prev)
1433 set $kgm_objp = (struct vm_object *)0
1434 end
1435 if $kgm_objp == kernel_object
1436 if $kgm_saw_kernel_obj
1437 set $kgm_objp = (struct vm_object *)0
1438 end
1439 set $kgm_saw_kernel_obj = 1
1440 end
1441 if $kgm_objp && $kgm_objp->wired_page_count
1442 if $kgm_objp_print_space == 1
1443 printf " "
1444 showptr $kgm_mapp
1445 end
1446 set $kgm_objp_print_space = 1
1447 printf " "
1448 showptr $kgm_vmep
1449 printf " 0x%016llx ", $kgm_vme.links.start
1450 printf "%5d", $kgm_vme.alias
1451 printf "%6d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
1452 showptr $kgm_objp
1453 printf "[%3d]", $kgm_objp->ref_count
1454 printf "%7d\n", $kgm_objp->wired_page_count
1455 set $kgm_wired_count = $kgm_wired_count + $kgm_objp->wired_page_count
1456 set $kgm_objp_prev = $kgm_objp
1457 end
1458 set $kgm_vmep = $kgm_vme.links.next
1459 end
1460 if $arg1 == 0
1461 printf "total wired count = %d\n", $kgm_wired_count
1462 end
1463 end
1464
1465 define showmapwired
1466 printf " map "
1467 showptrhdrpad
1468 printf " entry "
1469 showptrhdrpad
1470 printf " start alias #page object "
1471 showptrhdrpad
1472 printf " wired\n"
1473 showmapwiredp $arg0 0
1474 end
1475 document showmapwired
1476 Syntax: (gdb) showmapwired <vm_map>
1477 | Routine to print out a summary listing of all the entries with wired pages in a vm_map
1478 end
1479
1480 define showmapvme
1481 showmapheader
1482 showvmint $arg0 1
1483 end
1484 document showmapvme
1485 Syntax: (gdb) showmapvme <vm_map>
1486 | Routine to print out a summary listing of all the entries in a vm_map
1487 end
1488
1489
1490 define showmap
1491 showmapheader
1492 showvmint $arg0 0
1493 end
1494 document showmap
1495 Syntax: (gdb) showmap <vm_map>
1496 | Routine to print out info about the specified vm_map
1497 end
1498
1499 define showallvm
1500 set $kgm_head_taskp = &tasks
1501 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1502 while $kgm_taskp != $kgm_head_taskp
1503 showtaskheader
1504 showmapheader
1505 showtaskint $kgm_taskp
1506 showvmint $kgm_taskp->map 0
1507 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1508 end
1509 end
1510 document showallvm
1511 Syntax: (gdb) showallvm
1512 | Routine to print a summary listing of all the vm maps
1513 end
1514
1515
1516 define showallvme
1517 set $kgm_head_taskp = &tasks
1518 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1519 while $kgm_taskp != $kgm_head_taskp
1520 showtaskheader
1521 showmapheader
1522 showtaskint $kgm_taskp
1523 showvmint $kgm_taskp->map 1
1524 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1525 end
1526 end
1527 document showallvme
1528 Syntax: (gdb) showallvme
1529 | Routine to print a summary listing of all the vm map entries
1530 end
1531
1532
1533 define showipcheader
1534 printf "ipc_space "
1535 showptrhdrpad
1536 printf " is_table "
1537 showptrhdrpad
1538 printf " table_next"
1539 showptrhdrpad
1540 printf " flags ports splaysize "
1541 showptrhdrpad
1542 printf "splaybase\n"
1543 end
1544
1545 define showipceheader
1546 printf " "
1547 showptrhdrpad
1548 printf "object "
1549 showptrhdrpad
1550 showptrhdrpad
1551 printf "name rite urefs destname "
1552 showptrhdrpad
1553 printf "destination\n"
1554 end
1555
1556 define showipceint
1557 set $kgm_ie = *(ipc_entry_t)$arg0
1558 printf " "
1559 showptrhdrpad
1560 showptr $kgm_ie.ie_object
1561 showptrhdrpad
1562 printf " 0x%08x ", $arg1
1563 if $kgm_ie.ie_bits & 0x00100000
1564 printf "Dead "
1565 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1566 else
1567 if $kgm_ie.ie_bits & 0x00080000
1568 printf "SET "
1569 printf "%5d\n", $kgm_ie.ie_bits & 0xffff
1570 else
1571 if $kgm_ie.ie_bits & 0x00010000
1572 if $kgm_ie.ie_bits & 0x00020000
1573 printf " SR"
1574 else
1575 printf " S"
1576 end
1577 else
1578 if $kgm_ie.ie_bits & 0x00020000
1579 printf " R"
1580 end
1581 end
1582 if $kgm_ie.ie_bits & 0x00040000
1583 printf " O"
1584 end
1585 if $kgm_ie.index.request
1586 set $kgm_port = (ipc_port_t)$kgm_ie.ie_object
1587 set $kgm_requests = $kgm_port->ip_requests
1588 set $kgm_req_soright = $kgm_requests[$kgm_ie.index.request].notify.port
1589 if $kgm_req_soright
1590 # Armed send-possible notification?
1591 if (uintptr_t)$kgm_req_soright & 0x1
1592 printf "s"
1593 else
1594 # Delayed send-possible notification?
1595 if (uintptr_t)$kgm_req_soright & 0x2
1596 printf "d"
1597 else
1598 # Dead-name notification
1599 printf "n"
1600 end
1601 end
1602 else
1603 printf " "
1604 end
1605 else
1606 printf " "
1607 end
1608 # Collision (with tree)?
1609 if $kgm_ie.ie_bits & 0x00800000
1610 printf "c"
1611 else
1612 printf " "
1613 end
1614 printf "%5d ", $kgm_ie.ie_bits & 0xffff
1615 showportdest $kgm_ie.ie_object
1616 end
1617 end
1618 end
1619
1620 define showipcint
1621 set $kgm_isp = (ipc_space_t)$arg0
1622 set $kgm_is = *$kgm_isp
1623 showptr $arg0
1624 printf " "
1625 showptr $kgm_is.is_table
1626 printf " "
1627 showptr $kgm_is.is_table_next
1628 printf " "
1629 if $kgm_is.is_growing != 0
1630 printf "G"
1631 else
1632 printf " "
1633 end
1634 if $kgm_is.is_fast != 0
1635 printf "F"
1636 else
1637 printf " "
1638 end
1639 if $kgm_is.is_active != 0
1640 printf "A "
1641 else
1642 printf " "
1643 end
1644 printf "%5d ", $kgm_is.is_table_size + $kgm_is.is_tree_total
1645 showptr $kgm_is.is_tree_total
1646 printf " "
1647 showptr &$kgm_isp->is_tree
1648 printf "\n"
1649 if $arg1 != 0
1650 showipceheader
1651 set $kgm_iindex = 0
1652 set $kgm_iep = $kgm_is.is_table
1653 set $kgm_destspacep = (ipc_space_t)0
1654 while ( $kgm_iindex < $kgm_is.is_table_size )
1655 set $kgm_ie = *$kgm_iep
1656 if $kgm_ie.ie_bits & 0x001f0000
1657 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24))
1658 showipceint $kgm_iep $kgm_name
1659 if $arg2 != 0
1660 if $kgm_ie.ie_object != 0 && ($kgm_ie.ie_bits & 0x00070000) && ((ipc_port_t) $kgm_ie.ie_object)->ip_callstack[0] != 0
1661 printf " user bt: "
1662 showportbt $kgm_ie.ie_object $kgm_is.is_task
1663 end
1664 end
1665 end
1666 set $kgm_iindex = $kgm_iindex + 1
1667 set $kgm_iep = &($kgm_is.is_table[$kgm_iindex])
1668 end
1669 if $kgm_is.is_tree_total
1670 printf "Still need to write tree traversal\n"
1671 end
1672 end
1673 printf "\n"
1674 end
1675
1676
1677 define showipc
1678 set $kgm_isp = (ipc_space_t)$arg0
1679 showipcheader
1680 showipcint $kgm_isp 0 0
1681 end
1682 document showipc
1683 Syntax: (gdb) showipc <ipc_space>
1684 | Routine to print the status of the specified ipc space
1685 end
1686
1687 define showrights
1688 set $kgm_isp = (ipc_space_t)$arg0
1689 showipcheader
1690 showipcint $kgm_isp 1 0
1691 end
1692 document showrights
1693 Syntax: (gdb) showrights <ipc_space>
1694 | Routine to print a summary list of all the rights in a specified ipc space
1695 end
1696
1697
1698 define showtaskipc
1699 set $kgm_taskp = (task_t)$arg0
1700 showtaskheader
1701 showtaskint $kgm_taskp
1702 showipcheader
1703 showipcint $kgm_taskp->itk_space 0 0
1704 end
1705 document showtaskipc
1706 Syntax: (gdb) showtaskipc <task>
1707 | Routine to print info about the ipc space for a task
1708 end
1709
1710
1711 define showtaskrights
1712 set $kgm_taskp = (task_t)$arg0
1713 showtaskheader
1714 showtaskint $kgm_taskp
1715 showipcheader
1716 showipcint $kgm_taskp->itk_space 1 0
1717 end
1718 document showtaskrights
1719 Syntax: (gdb) showtaskrights <task>
1720 | Routine to print info about the ipc rights for a task
1721 end
1722
1723 define showtaskrightsbt
1724 set $kgm_taskp = (task_t)$arg0
1725 showtaskheader
1726 showtaskint $kgm_taskp
1727 showipcheader
1728 showipcint $kgm_taskp->itk_space 1 1
1729 end
1730 document showtaskrightsbt
1731 Syntax: (gdb) showtaskrightsbt <task>
1732 | Routine to print info about the ipc rights for a task with backtraces
1733 end
1734
1735 define showallipc
1736 set $kgm_head_taskp = &tasks
1737 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1738 while $kgm_cur_taskp != $kgm_head_taskp
1739 showtaskheader
1740 showtaskint $kgm_cur_taskp
1741 showipcheader
1742 showipcint $kgm_cur_taskp->itk_space 0 0
1743 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1744 end
1745 end
1746 document showallipc
1747 Syntax: (gdb) showallipc
1748 | Routine to print a summary listing of all the ipc spaces
1749 end
1750
1751 define showipcsumheader
1752 printf "task "
1753 showptrhdrpad
1754 printf " pid "
1755 printf " #acts "
1756 printf " tsize "
1757 printf "command\n"
1758 end
1759
1760 define showipcsummaryint
1761 set $kgm_taskp = (struct task *)$arg0
1762 showptr $arg0
1763 printf "%7d", ((struct proc *)$kgm_taskp->bsd_info)->p_pid
1764 printf "%15d", $kgm_taskp->thread_count
1765 printf "%15d", $kgm_cur_taskp->itk_space.is_table_size
1766 printf " %s\n", ((struct proc *)$kgm_taskp->bsd_info)->p_comm
1767 end
1768
1769 define showipcsummary
1770 showipcsumheader
1771 set $kgm_head_taskp = &tasks
1772 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1773 while $kgm_cur_taskp != $kgm_head_taskp
1774 showipcsummaryint $kgm_cur_taskp
1775 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1776 end
1777 end
1778
1779 document showipcsummary
1780 Syntax: (gdb) showipcsummary
1781 | Summarizes the IPC state of all tasks. This is a convenient way to dump
1782 | some basic clues about IPC messaging. You can use the output to determine
1783 | tasks that are candidates for further investigation.
1784 end
1785
1786
1787 define showallrights
1788 set $kgm_head_taskp = &tasks
1789 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
1790 while $kgm_cur_taskp != $kgm_head_taskp
1791 showtaskheader
1792 showtaskint $kgm_cur_taskp
1793 showipcheader
1794 showipcint $kgm_cur_taskp->itk_space 1 0
1795 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
1796 end
1797 end
1798 document showallrights
1799 Syntax: (gdb) showallrights
1800 | Routine to print a summary listing of all the ipc rights
1801 end
1802
1803
1804 define showtaskvm
1805 set $kgm_taskp = (task_t)$arg0
1806 showtaskheader
1807 showmapheader
1808 showtaskint $kgm_taskp
1809 showvmint $kgm_taskp->map 0
1810 end
1811 document showtaskvm
1812 Syntax: (gdb) showtaskvm <task>
1813 | Routine to print out info about a task's vm_map
1814 end
1815
1816 define showtaskvme
1817 set $kgm_taskp = (task_t)$arg0
1818 showtaskheader
1819 showtaskint $kgm_taskp
1820 showmapheader
1821 showvmint $kgm_taskp->map 1
1822 end
1823 document showtaskvme
1824 Syntax: (gdb) showtaskvme <task>
1825 | Routine to print out info about a task's vm_map_entries
1826 end
1827
1828
1829 define showtaskheader
1830 printf "task "
1831 showptrhdrpad
1832 printf " vm_map "
1833 showptrhdrpad
1834 printf " ipc_space "
1835 showptrhdrpad
1836 printf " #acts "
1837 showprocheader
1838 end
1839
1840
1841 define showtaskint
1842 set $kgm_taskp = (struct task *)$arg0
1843 showptr $arg0
1844 printf " "
1845 showptr $kgm_taskp->map
1846 printf " "
1847 showptr $kgm_taskp->itk_space
1848 printf " %5d ", $kgm_taskp->thread_count
1849 showprocint $kgm_taskp->bsd_info
1850 end
1851
1852 define showtask
1853 showtaskheader
1854 showtaskint $arg0
1855 end
1856 document showtask
1857 Syntax (gdb) showtask <task>
1858 | Routine to print out info about a task.
1859 end
1860
1861
1862 define showtaskthreads
1863 showtaskheader
1864 set $kgm_taskp = (struct task *)$arg0
1865 showtaskint $kgm_taskp
1866 showactheader
1867 set $kgm_head_actp = &($kgm_taskp->threads)
1868 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1869 while $kgm_actp != $kgm_head_actp
1870 showactint $kgm_actp 0
1871 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1872 end
1873 end
1874 document showtaskthreads
1875 Syntax: (gdb) showtaskthreads <task>
1876 | Routine to print info about the threads in a task.
1877 end
1878
1879
1880 define showtaskstacks
1881 showtaskheader
1882 set $kgm_taskp = (struct task *)$arg0
1883 showtaskint $kgm_taskp
1884 set $kgm_head_actp = &($kgm_taskp->threads)
1885 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
1886 while $kgm_actp != $kgm_head_actp
1887 showactheader
1888 showactint $kgm_actp 1
1889 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
1890 end
1891 end
1892 document showtaskstacks
1893 Syntax: (gdb) showtaskstacks <task>
1894 | Routine to print out the stack for each thread in a task.
1895 end
1896
1897 define showqueue_elems
1898 set $queue_head = (struct queue_entry *)($arg0)
1899 set $queue = (struct queue_entry *)($queue_head->next)
1900 while $queue != $queue_head
1901 showptr $queue
1902 printf " "
1903 set $thread = (struct thread *)$queue
1904 set $task = (struct task *)$thread->task
1905 set $bsd = (struct proc *)$task->bsd_info
1906 set $guy = (char *)$bsd->p_comm
1907 showptr $thread
1908 printf " "
1909 showptr $task
1910 printf " "
1911 showptr $bsd
1912 printf " "
1913 showptr $guy
1914 #printf " %s\n", $kgm_procp->p_comm
1915 printf "\n"
1916 set $queue = (struct queue_entry *)($queue->next)
1917 end
1918 end
1919
1920 define showalltasks
1921 showtaskheader
1922 set $kgm_head_taskp = &tasks
1923 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
1924 while $kgm_taskp != $kgm_head_taskp
1925 showtaskint $kgm_taskp
1926 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
1927 end
1928 end
1929 document showalltasks
1930 Syntax: (gdb) showalltasks
1931 | Routine to print a summary listing of all the tasks
1932 | wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
1933 | if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
1934 | io_policy -> RAGE - rapid aging of vnodes requested
1935 | NORM - normal I/O explicitly requested (this is the default)
1936 | PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
1937 | THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
1938 end
1939
1940 define showprocheader
1941 printf " pid process "
1942 showptrhdrpad
1943 printf "io_policy wq_state command\n"
1944 end
1945
1946 define showprocint
1947 set $kgm_procp = (struct proc *)$arg0
1948 if $kgm_procp != 0
1949 set $kgm_printed = 0
1950 printf "%5d ", $kgm_procp->p_pid
1951 showptr $kgm_procp
1952 if ($kgm_procp->p_lflag & 0x400000)
1953 printf " RAGE "
1954 else
1955 printf " "
1956 end
1957 set $ptask = (struct task *)$kgm_procp->task
1958 set $diskpolicy = 0
1959 if ($ptask->ext_actionstate.hw_disk != 0)
1960 set $diskpolicy = $ptask->ext_actionstate.hw_disk
1961 else
1962 if ($ptask->actionstate.hw_disk != 0)
1963 set $diskpolicy = $ptask->actionstate.hw_disk
1964 end
1965 end
1966 if ($ptask->ext_actionstate.hw_bg != 0)
1967 set $diskpolicy = 5
1968 end
1969 if ($ptask->actionstate.hw_bg != 0)
1970 set $diskpolicy = 4
1971 end
1972 if ($diskpolicy == 2)
1973 printf "PASS "
1974 set $kgm_printed = 1
1975 end
1976 if ($diskpolicy == 3)
1977 printf "THROT "
1978 set $kgm_printed = 1
1979 end
1980 if ($diskpolicy == 4)
1981 printf "BG_THRT "
1982 set $kgm_printed = 1
1983 end
1984 if ($diskpolicy == 5)
1985 printf "EBG_THRT"
1986 set $kgm_printed = 1
1987 end
1988 if ($kgm_printed == 0)
1989 printf " "
1990 end
1991 set $kgm_wqp = (struct workqueue *)$kgm_procp->p_wqptr
1992 if $kgm_wqp != 0
1993 printf " %2d %2d %2d ", $kgm_wqp->wq_nthreads, $kgm_wqp->wq_thidlecount, $kgm_wqp->wq_itemcount
1994 else
1995 printf " "
1996 end
1997 printf " %s\n", $kgm_procp->p_comm
1998 else
1999 printf " *0* "
2000 showptr 0
2001 printf " --\n"
2002 end
2003 end
2004
2005 define showpid
2006 showtaskheader
2007 set $kgm_head_taskp = &tasks
2008 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
2009 while $kgm_taskp != $kgm_head_taskp
2010 set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info
2011 if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0))
2012 showtaskint $kgm_taskp
2013 set $kgm_taskp = $kgm_head_taskp
2014 else
2015 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
2016 end
2017 end
2018 end
2019 document showpid
2020 Syntax: (gdb) showpid <pid>
2021 | Routine to print a single process by pid
2022 end
2023
2024 define showproc
2025 showtaskheader
2026 set $kgm_procp = (struct proc *)$arg0
2027 showtaskint $kgm_procp->task
2028 end
2029
2030
2031 define kdb
2032 set switch_debugger=1
2033 continue
2034 end
2035 document kdb
2036 | kdb - Switch to the inline kernel debugger
2037 |
2038 | usage: kdb
2039 |
2040 | The kdb macro allows you to invoke the inline kernel debugger.
2041 end
2042
2043 define showpsetheader
2044 printf "portset "
2045 showptrhdrpad
2046 printf "waitqueue "
2047 showptrhdrpad
2048 showptrhdrpad
2049 printf "recvname flags refs recvname "
2050 showptrhdrpad
2051 printf "process\n"
2052 end
2053
2054 define showportheader
2055 printf "port "
2056 showptrhdrpad
2057 printf "mqueue "
2058 showptrhdrpad
2059 showptrhdrpad
2060 printf "recvname flags refs recvname "
2061 showptrhdrpad
2062 printf "dest\n"
2063 end
2064
2065 define showportmemberheader
2066 printf "members "
2067 showptrhdrpad
2068 printf "port "
2069 showptrhdrpad
2070 showptrhdrpad
2071 printf "recvname "
2072 printf "flags refs mqueue "
2073 showptrhdrpad
2074 printf "msgcount\n"
2075 end
2076
2077 define showkmsgheader
2078 printf "dest-port "
2079 showptrhdrpad
2080 printf "kmsg "
2081 showptrhdrpad
2082 showptrhdrpad
2083 printf "msgid "
2084 printf "disp size "
2085 printf "reply-port "
2086 showptrhdrpad
2087 printf "source\n"
2088 end
2089
2090 define showkmsgsrcint
2091 set $kgm_kmsgsrchp = ((ipc_kmsg_t)$arg0)->ikm_header
2092 # set $kgm_kmsgsrctp = (mach_msg_audit_trailer_t *)((uintptr_t)$kgm_kmsgsrchp + $kgm_kmsgsrchp->msgh_size)
2093 # set $kgm_kmsgpid = $kgm_kmsgsrctp->msgh_audit.val[5]
2094 set $kgm_kmsgpid = (pid_t)((uint *)((uintptr_t)$kgm_kmsgsrchp + $kgm_kmsgsrchp->msgh_size))[10]
2095 # compare against a well-known or cached value as this may be slow
2096 if ($kgm_kmsgpid == 0)
2097 set $kgm_kmsgsrcpid = (pid_t)0
2098 set $kgm_kmsgsrcprocp = (struct proc *)kernel_task->bsd_info
2099 else
2100 if ($kgm_kmsgpid != $kgm_kmsgsrcpid)
2101 set $kgm_kmsgsrchead_taskp = &tasks
2102 set $kgm_kmsgsrctaskp = (struct task *)($kgm_kmsgsrchead_taskp->next)
2103 while $kgm_kmsgsrctaskp != $kgm_kmsgsrchead_taskp
2104 set $kgm_kmsgsrcprocp = (struct proc *)$kgm_kmsgsrctaskp->bsd_info
2105 set $kgm_kmsgsrcpid = $kgm_kmsgsrcprocp->p_pid
2106 if (($kgm_kmsgsrcprocp != 0) && ($kgm_kmsgsrcprocp->p_pid == $kgm_kmsgpid))
2107 set $kgm_kmsgsrctaskp = $kgm_kmsgsrchead_taskp
2108 else
2109 set $kgm_kmsgsrctaskp = (struct task *)($kgm_kmsgsrctaskp->tasks.next)
2110 end
2111 end
2112 end
2113 end
2114 if ($kgm_kmsgsrcprocp->p_pid == $kgm_kmsgpid)
2115 printf "%s(%d)\n", $kgm_kmsgsrcprocp->p_comm, $kgm_kmsgpid
2116 else
2117 printf "unknown(%d)\n", $kgm_kmsgpid
2118 end
2119 end
2120
2121 define showkmsgint
2122 set $kgm_kmsghp = ((ipc_kmsg_t)$arg0)->ikm_header
2123 set $kgm_kmsgh = *$kgm_kmsghp
2124 if ($arg1 != 0)
2125 printf " "
2126 showptrhdrpad
2127 else
2128 showptr $kgm_kmsgh.msgh_remote_port
2129 end
2130 showptr $arg0
2131 showptrhdrpad
2132 printf " 0x%08x ", $kgm_kmsgh.msgh_id
2133 if (($kgm_kmsgh.msgh_bits & 0xff) == 19)
2134 printf "rC"
2135 else
2136 printf "rM"
2137 end
2138 if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 << 8))
2139 printf "lC"
2140 else
2141 printf "lM"
2142 end
2143 if ($kgm_kmsgh.msgh_bits & 0xf0000000)
2144 printf "c"
2145 else
2146 printf "s"
2147 end
2148 printf "%5d ", $kgm_kmsgh.msgh_size
2149 showptr $kgm_kmsgh.msgh_local_port
2150 printf " "
2151 set $kgm_kmsgsrcpid = (pid_t)0
2152 showkmsgsrcint $arg0
2153 end
2154
2155 define showkmsg
2156 showkmsgint $arg0 0
2157 end
2158
2159 define showkobject
2160 set $kgm_portp = (struct ipc_port *)$arg0
2161 showptr $kgm_portp->ip_kobject
2162 printf " kobject("
2163 set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff)
2164 if ($kgm_kotype == 1)
2165 printf "THREAD"
2166 end
2167 if ($kgm_kotype == 2)
2168 printf "TASK"
2169 end
2170 if ($kgm_kotype == 3)
2171 printf "HOST"
2172 end
2173 if ($kgm_kotype == 4)
2174 printf "HOST_PRIV"
2175 end
2176 if ($kgm_kotype == 5)
2177 printf "PROCESSOR"
2178 end
2179 if ($kgm_kotype == 6)
2180 printf "PSET"
2181 end
2182 if ($kgm_kotype == 7)
2183 printf "PSET_NAME"
2184 end
2185 if ($kgm_kotype == 8)
2186 printf "TIMER"
2187 end
2188 if ($kgm_kotype == 9)
2189 printf "PAGER_REQ"
2190 end
2191 if ($kgm_kotype == 10)
2192 printf "DEVICE"
2193 end
2194 if ($kgm_kotype == 11)
2195 printf "XMM_OBJECT"
2196 end
2197 if ($kgm_kotype == 12)
2198 printf "XMM_PAGER"
2199 end
2200 if ($kgm_kotype == 13)
2201 printf "XMM_KERNEL"
2202 end
2203 if ($kgm_kotype == 14)
2204 printf "XMM_REPLY"
2205 end
2206 if ($kgm_kotype == 15)
2207 printf "NOTDEF 15"
2208 end
2209 if ($kgm_kotype == 16)
2210 printf "NOTDEF 16"
2211 end
2212 if ($kgm_kotype == 17)
2213 printf "HOST_SEC"
2214 end
2215 if ($kgm_kotype == 18)
2216 printf "LEDGER"
2217 end
2218 if ($kgm_kotype == 19)
2219 printf "MASTER_DEV"
2220 end
2221 if ($kgm_kotype == 20)
2222 printf "ACTIVATION"
2223 end
2224 if ($kgm_kotype == 21)
2225 printf "SUBSYSTEM"
2226 end
2227 if ($kgm_kotype == 22)
2228 printf "IO_DONE_QUE"
2229 end
2230 if ($kgm_kotype == 23)
2231 printf "SEMAPHORE"
2232 end
2233 if ($kgm_kotype == 24)
2234 printf "LOCK_SET"
2235 end
2236 if ($kgm_kotype == 25)
2237 printf "CLOCK"
2238 end
2239 if ($kgm_kotype == 26)
2240 printf "CLOCK_CTRL"
2241 end
2242 if ($kgm_kotype == 27)
2243 printf "IOKIT_SPARE"
2244 end
2245 if ($kgm_kotype == 28)
2246 printf "NAMED_MEM"
2247 end
2248 if ($kgm_kotype == 29)
2249 printf "IOKIT_CON"
2250 end
2251 if ($kgm_kotype == 30)
2252 printf "IOKIT_OBJ"
2253 end
2254 if ($kgm_kotype == 31)
2255 printf "UPL"
2256 end
2257 if ($kgm_kotype == 34)
2258 printf "FD"
2259 end
2260 printf ")\n"
2261 end
2262
2263 define showportdestproc
2264 set $kgm_portp = (struct ipc_port *)$arg0
2265 set $kgm_spacep = $kgm_portp->data.receiver
2266 # check against the previous cached value - this is slow
2267 if ($kgm_spacep != $kgm_destspacep)
2268 set $kgm_destprocp = (struct proc *)0
2269 set $kgm_head_taskp = &tasks
2270 set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next)
2271 while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp))
2272 set $kgm_destspacep = $kgm_desttaskp->itk_space
2273 if ($kgm_destspacep == $kgm_spacep)
2274 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info
2275 else
2276 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->tasks.next)
2277 end
2278 end
2279 end
2280 if $kgm_destprocp != 0
2281 printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid
2282 else
2283 printf "task "
2284 showptr $kgm_desttaskp
2285 printf "\n"
2286 end
2287 end
2288
2289 define showportdest
2290 set $kgm_portp = (struct ipc_port *)$arg0
2291 set $kgm_spacep = $kgm_portp->data.receiver
2292 if ((uintptr_t)$kgm_spacep == (uintptr_t)ipc_space_kernel)
2293 showkobject $kgm_portp
2294 else
2295 if ($kgm_portp->ip_object.io_bits & 0x80000000)
2296 showptr $kgm_portp->ip_messages.data.port.receiver_name
2297 printf " "
2298 showportdestproc $kgm_portp
2299 else
2300 showptr $kgm_portp
2301 printf " inactive-port\n"
2302 end
2303 end
2304 end
2305
2306 define showportmember
2307 printf " "
2308 showptrhdrpad
2309 showptr $arg0
2310 showptrhdrpad
2311 set $kgm_portp = (struct ipc_port *)$arg0
2312 printf " 0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
2313 if ($kgm_portp->ip_object.io_bits & 0x80000000)
2314 printf "A"
2315 else
2316 printf " "
2317 end
2318 printf "Port"
2319 printf "%5d ", $kgm_portp->ip_object.io_references
2320 showptr &($kgm_portp->ip_messages)
2321 printf " 0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount
2322 end
2323
2324 define showportbt
2325 set $kgm_iebt = ((ipc_port_t) $arg0)->ip_callstack
2326 set $kgm_iepid = ((ipc_port_t) $arg0)->ip_spares[0]
2327 set $kgm_procpid = ((proc_t) (((task_t) $arg1)->bsd_info))->p_pid
2328 if $kgm_iebt[0] != 0
2329 showptr $kgm_iebt[0]
2330 set $kgm_iebt_loop_ctr = 1
2331 while ($kgm_iebt_loop_ctr < 16 && $kgm_iebt[$kgm_iebt_loop_ctr])
2332 printf " "
2333 showptr $kgm_iebt[$kgm_iebt_loop_ctr]
2334 set $kgm_iebt_loop_ctr = $kgm_iebt_loop_ctr + 1
2335 end
2336 if $kgm_iepid != $kgm_procpid
2337 printf " (%d)", $kgm_iepid
2338 end
2339 printf "\n"
2340 end
2341 end
2342
2343 define showportint
2344 showptr $arg0
2345 printf " "
2346 set $kgm_portp = (struct ipc_port *)$arg0
2347 showptr &($kgm_portp->ip_messages)
2348 showptrhdrpad
2349 printf " 0x%08x ", $kgm_portp->ip_messages.data.port.receiver_name
2350 if ($kgm_portp->ip_object.io_bits & 0x80000000)
2351 printf "A"
2352 else
2353 printf "D"
2354 end
2355 printf "Port"
2356 printf "%5d ", $kgm_portp->ip_object.io_references
2357 set $kgm_destspacep = (struct ipc_space *)0
2358 showportdest $kgm_portp
2359 set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base
2360 if $arg1 && $kgm_kmsgp
2361 showkmsgheader
2362 showkmsgint $kgm_kmsgp 1
2363 set $kgm_kmsgheadp = $kgm_kmsgp
2364 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
2365 while $kgm_kmsgp != $kgm_kmsgheadp
2366 showkmsgint $kgm_kmsgp 1
2367 set $kgm_kmsgp = $kgm_kmsgp->ikm_next
2368 end
2369 end
2370 end
2371
2372 define showpsetint
2373 showptr $arg0
2374 printf " "
2375 set $kgm_psetp = (struct ipc_pset *)$arg0
2376 showptr &($kgm_psetp->ips_messages)
2377 showptrhdrpad
2378 printf " 0x%08x ", $kgm_psetp->ips_messages.data.pset.local_name
2379 if ($kgm_psetp->ips_object.io_bits & 0x80000000)
2380 printf "A"
2381 else
2382 printf "D"
2383 end
2384 printf "Set "
2385 printf "%5d ", $kgm_psetp->ips_object.io_references
2386 showptr $kgm_psetp->ips_messages.data.pset.local_name
2387 printf " "
2388 set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.pset.set_queue.wqs_setlinks)
2389 set $kgm_wql = (WaitQueueLink *)$kgm_setlinksp->next
2390 set $kgm_found = 0
2391 while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp)
2392 set $kgm_portp = (struct ipc_port *)((uintptr_t)($kgm_wql->wql_element->wqe_queue) - (uintptr_t)$kgm_portoff)
2393 if !$kgm_found
2394 set $kgm_destspacep = (struct ipc_space *)0
2395 showportdestproc $kgm_portp
2396 showportmemberheader
2397 set $kgm_found = 1
2398 end
2399 showportmember $kgm_portp 0
2400 set $kgm_wql = (WaitQueueLink *)$kgm_wql->wql_setlinks.next
2401 end
2402 if !$kgm_found
2403 printf "--n/e--\n"
2404 end
2405 end
2406
2407 define showpset
2408 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
2409 showpsetheader
2410 showpsetint $arg0 1
2411 end
2412
2413 define showport
2414 showportheader
2415 showportint $arg0 1
2416 end
2417
2418 define showipcobject
2419 set $kgm_objectp = (ipc_object_t)$arg0
2420 if ($kgm_objectp->io_bits & 0x7fff0000)
2421 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
2422 showpset $kgm_objectp
2423 else
2424 showport $kgm_objectp
2425 end
2426 end
2427
2428 define showmqueue
2429 set $kgm_mqueue = *(struct ipc_mqueue *)$arg0
2430 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d1)
2431 set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages)
2432 set $kgm_pset = (((long)$arg0) - ((long)$kgm_psetoff))
2433 showpsetheader
2434 showpsetint $kgm_pset 1
2435 end
2436 if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d0)
2437 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
2438 set $kgm_port = (((long)$arg0) - ((long)$kgm_portoff))
2439 showportheader
2440 showportint $kgm_port 1
2441 end
2442 end
2443
2444 define zprint_one
2445 set $kgm_zone = (struct zone *)$arg0
2446
2447 showptr $kgm_zone
2448 printf " %8d ",$kgm_zone->count
2449 printf "%8x ",$kgm_zone->cur_size
2450 printf "%8x ",$kgm_zone->max_size
2451 printf "%8d ",$kgm_zone->elem_size
2452 printf "%8x ",$kgm_zone->alloc_size
2453 printf " %16ld ",$kgm_zone->num_allocs
2454 printf "%16ld ",$kgm_zone->num_frees
2455 printf "%s ",$kgm_zone->zone_name
2456
2457 if ($kgm_zone->exhaustible)
2458 printf "H"
2459 end
2460 if ($kgm_zone->collectable)
2461 printf "C"
2462 end
2463 if ($kgm_zone->expandable)
2464 printf "X"
2465 end
2466 if ($kgm_zone->noencrypt)
2467 printf "$"
2468 end
2469 printf "\n"
2470 end
2471
2472
2473 define zprint
2474 printf "ZONE "
2475 showptrhdrpad
2476 printf " COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ TOT_ALLOC TOT_FREE NAME\n"
2477 set $kgm_zone_ptr = (struct zone *)first_zone
2478 while ($kgm_zone_ptr != 0)
2479 zprint_one $kgm_zone_ptr
2480 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
2481 end
2482 printf "\n"
2483 end
2484 document zprint
2485 Syntax: (gdb) zprint
2486 | Routine to print a summary listing of all the kernel zones
2487 end
2488
2489 define showmtxgrp
2490 set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0
2491
2492 if ($kgm_mtxgrp->lck_grp_mtxcnt)
2493 showptr $kgm_mtxgrp
2494 printf " %8d ",$kgm_mtxgrp->lck_grp_mtxcnt
2495 printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
2496 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
2497 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
2498 printf "%s ",&$kgm_mtxgrp->lck_grp_name
2499 printf "\n"
2500 end
2501 end
2502
2503
2504 define showallmtx
2505 printf "LCK GROUP "
2506 showptrhdrpad
2507 printf " CNT UTIL MISS WAIT NAME\n"
2508 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
2509 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
2510 while ($kgm_mtxgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
2511 showmtxgrp $kgm_mtxgrp_ptr
2512 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
2513 end
2514 printf "\n"
2515 end
2516 document showallmtx
2517 Syntax: (gdb) showallmtx
2518 | Routine to print a summary listing of all mutexes
2519 end
2520
2521 define showrwlckgrp
2522 set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0
2523
2524 if ($kgm_rwlckgrp->lck_grp_rwcnt)
2525 showptr $kgm_rwlckgrp
2526 printf " %8d ",$kgm_rwlckgrp->lck_grp_rwcnt
2527 printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
2528 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
2529 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
2530 printf "%s ",&$kgm_rwlckgrp->lck_grp_name
2531 printf "\n"
2532 end
2533 end
2534
2535
2536 define showallrwlck
2537 printf "LCK GROUP "
2538 showptrhdrpad
2539 printf " CNT UTIL MISS WAIT NAME\n"
2540 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
2541 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
2542 while ($kgm_rwlckgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
2543 showrwlckgrp $kgm_rwlckgrp_ptr
2544 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
2545 end
2546 printf "\n"
2547 end
2548 document showallrwlck
2549 Syntax: (gdb) showallrwlck
2550 | Routine to print a summary listing of all read/writer locks
2551 end
2552
2553 set $kdp_act_counter = 0
2554 set $kdp_arm_act_counter = 0
2555
2556 set $r0_save = 0
2557 set $r1_save = 0
2558 set $r2_save = 0
2559 set $r3_save = 0
2560 set $r4_save = 0
2561 set $r5_save = 0
2562 set $r6_save = 0
2563 set $r7_save = 0
2564 set $r8_save = 0
2565 set $r9_save = 0
2566 set $r10_save = 0
2567 set $r11_save = 0
2568 set $r12_save = 0
2569 set $sp_save = 0
2570 set $lr_save = 0
2571 set $pc_save = 0
2572
2573 define showcontext_int
2574 echo Context switched, current instruction pointer:
2575 output/a $pc
2576 echo \n
2577 end
2578
2579 define switchtoact
2580 set $newact = (struct thread *) $arg0
2581 select 0
2582 if ($newact->kernel_stack == 0)
2583 echo This activation does not have a stack.\n
2584 echo continuation:
2585 output/a (unsigned) $newact.continuation
2586 echo \n
2587 else
2588 if ($kgm_mtype == $kgm_mtype_ppc)
2589 if ($kdp_act_counter == 0)
2590 set $kdpstate = (struct savearea *) kdp.saved_state
2591 end
2592 set $kdp_act_counter = $kdp_act_counter + 1
2593 set (struct savearea *) kdp.saved_state=$newact->machine->pcb
2594 flushregs
2595 flushstack
2596 set $pc=$newact->machine->pcb.save_srr0
2597 update
2598 end
2599 if ($kgm_mtype == $kgm_mtype_i386)
2600 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
2601 if ($kdp_act_counter == 0)
2602 set $kdpstate = *($kdpstatep)
2603 end
2604 set $kdp_act_counter = $kdp_act_counter + 1
2605
2606 set $kgm_statep = (struct x86_kernel_state *) \
2607 ($newact->kernel_stack + kernel_stack_size \
2608 - sizeof(struct x86_kernel_state))
2609 set $kdpstatep->ebx = $kgm_statep->k_ebx
2610 set $kdpstatep->ebp = $kgm_statep->k_ebp
2611 set $kdpstatep->edi = $kgm_statep->k_edi
2612 set $kdpstatep->esi = $kgm_statep->k_esi
2613 set $kdpstatep->eip = $kgm_statep->k_eip
2614 flushregs
2615 flushstack
2616 set $pc = $kgm_statep->k_eip
2617 update
2618 end
2619 if ($kgm_mtype == $kgm_mtype_x86_64)
2620 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
2621 if ($kdp_act_counter == 0)
2622 set $kdpstate = *($kdpstatep)
2623 end
2624 set $kdp_act_counter = $kdp_act_counter + 1
2625
2626 set $kgm_statep = (struct x86_kernel_state *) \
2627 ($newact->kernel_stack + kernel_stack_size \
2628 - sizeof(struct x86_kernel_state))
2629 set $kdpstatep->rbx = $kgm_statep->k_rbx
2630 set $kdpstatep->rbp = $kgm_statep->k_rbp
2631 set $kdpstatep->r12 = $kgm_statep->k_r12
2632 set $kdpstatep->r13 = $kgm_statep->k_r13
2633 set $kdpstatep->r14 = $kgm_statep->k_r14
2634 set $kdpstatep->r15 = $kgm_statep->k_r15
2635 set $kdpstatep->isf.rsp = $kgm_statep->k_rsp
2636 flushregs
2637 flushstack
2638 set $pc = $kgm_statep->k_rip
2639 update
2640 end
2641 if ($kgm_mtype == $kgm_mtype_arm)
2642 set $kdp_arm_act_counter = $kdp_arm_act_counter + 1
2643 if ($kdp_arm_act_counter == 1)
2644 set $r0_save = $r0
2645 set $r1_save = $r1
2646 set $r2_save = $r2
2647 set $r3_save = $r3
2648 set $r4_save = $r4
2649 set $r5_save = $r5
2650 set $r6_save = $r6
2651 set $r7_save = $r7
2652 set $r8_save = $r8
2653 set $r9_save = $r9
2654 set $r10_save = $r10
2655 set $r11_save = $r11
2656 set $r12_save = $r12
2657 set $sp_save = $sp
2658 set $lr_save = $lr
2659 set $pc_save = $pc
2660 end
2661 set $pc_ctx = load_reg+8
2662 set $kgm_statep = (struct arm_saved_state *)((struct thread*)$arg0)->machine.kstackptr
2663 set $r0 = $kgm_statep->r[0]
2664 set $r1 = $kgm_statep->r[1]
2665 set $r2 = $kgm_statep->r[2]
2666 set $r3 = $kgm_statep->r[3]
2667 set $r4 = $kgm_statep->r[4]
2668 set $r5 = $kgm_statep->r[5]
2669 set $r6 = $kgm_statep->r[6]
2670 set $r8 = $kgm_statep->r[8]
2671 set $r9 = $kgm_statep->r[9]
2672 set $r10 = $kgm_statep->r[10]
2673 set $r11 = $kgm_statep->r[11]
2674 set $r12 = $kgm_statep->r[12]
2675 set $sp = $kgm_statep->sp
2676 set $lr = $kgm_statep->lr
2677 set $pc = $pc_ctx
2678 set $r7 = $kgm_statep->r[7]
2679 flushregs
2680 flushstack
2681 end
2682 end
2683 showcontext_int
2684 end
2685
2686 document switchtoact
2687 Syntax: switchtoact <address of activation>
2688 | This command allows gdb to examine the execution context and call
2689 | stack for the specified activation. For example, to view the backtrace
2690 | for an activation issue "switchtoact <address>", followed by "bt".
2691 | Before resuming execution, issue a "resetctx" command, to
2692 | return to the original execution context.
2693 end
2694
2695 define switchtoctx
2696 select 0
2697 if ($kgm_mtype == $kgm_mtype_ppc)
2698 if ($kdp_act_counter == 0)
2699 set $kdpstate = (struct savearea *) kdp.saved_state
2700 end
2701 set $kdp_act_counter = $kdp_act_counter + 1
2702 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0
2703 flushregs
2704 flushstack
2705 set $pc=((struct savearea *) $arg0)->save_srr0
2706 update
2707 else
2708 if ($kgm_mtype == $kgm_mtype_arm)
2709 select 0
2710 set $kdp_arm_act_counter = $kdp_arm_act_counter + 1
2711 if ($kdp_arm_act_counter == 1)
2712 set $r0_save = $r0
2713 set $r1_save = $r1
2714 set $r2_save = $r2
2715 set $r3_save = $r3
2716 set $r4_save = $r4
2717 set $r5_save = $r5
2718 set $r6_save = $r6
2719 set $r7_save = $r7
2720 set $r8_save = $r8
2721 set $r9_save = $r9
2722 set $r10_save = $r10
2723 set $r11_save = $r11
2724 set $r12_save = $r12
2725 set $sp_save = $sp
2726 set $lr_save = $lr
2727 set $pc_save = $pc
2728 end
2729 set $kgm_statep = (struct arm_saved_state *)$arg0
2730 set $r0 = $kgm_statep->r[0]
2731 set $r1 = $kgm_statep->r[1]
2732 set $r2 = $kgm_statep->r[2]
2733 set $r3 = $kgm_statep->r[3]
2734 set $r4 = $kgm_statep->r[4]
2735 set $r5 = $kgm_statep->r[5]
2736 set $r6 = $kgm_statep->r[6]
2737 set $r8 = $kgm_statep->r[8]
2738 set $r9 = $kgm_statep->r[9]
2739 set $r10 = $kgm_statep->r[10]
2740 set $r11 = $kgm_statep->r[11]
2741 set $r12 = $kgm_statep->r[12]
2742 set $sp = $kgm_statep->sp
2743 set $lr = $kgm_statep->lr
2744 set $r7 = $kgm_statep->r[7]
2745 set $pc = $kgm_statep->pc
2746 flushregs
2747 flushstack
2748 update
2749 else
2750 echo switchtoctx not implemented for this architecture.\n
2751 end
2752 end
2753
2754 document switchtoctx
2755 Syntax: switchtoctx <address of pcb>
2756 | This command allows gdb to examine an execution context and dump the
2757 | backtrace for this execution context.
2758 | Before resuming execution, issue a "resetctx" command, to
2759 | return to the original execution context.
2760 end
2761
2762 define resetctx
2763 select 0
2764 if ($kdp_act_counter != 0)
2765 if ($kgm_mtype == $kgm_mtype_ppc)
2766 set (struct savearea *)kdp.saved_state=$kdpstate
2767 flushregs
2768 flushstack
2769 set $pc=((struct savearea *) kdp.saved_state)->save_srr0
2770 update
2771 set $kdp_act_counter = 0
2772 end
2773 if ($kgm_mtype == $kgm_mtype_i386)
2774 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
2775 set *($kdpstatep)=$kdpstate
2776 flushregs
2777 flushstack
2778 set $pc=$kdpstatep->eip
2779 update
2780 set $kdp_act_counter = 0
2781 end
2782 if ($kgm_mtype == $kgm_mtype_x86_64)
2783 set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
2784 set *($kdpstatep)=$kdpstate
2785 flushregs
2786 flushstack
2787 set $pc=$kdpstatep->isf.rip
2788 update
2789 set $kdp_act_counter = 0
2790 end
2791 showcontext_int
2792 end
2793 if ($kgm_mtype == $kgm_mtype_arm && $kdp_arm_act_counter != 0)
2794 echo Restoring context\n
2795 set $r0 = $r0_save
2796 flushregs
2797 set $r1 = $r1_save
2798 flushregs
2799 set $r2 = $r2_save
2800 flushregs
2801 set $r3 = $r3_save
2802 flushregs
2803 set $r4 = $r4_save
2804 flushregs
2805 set $r5 = $r5_save
2806 flushregs
2807 set $r6 = $r6_save
2808 flushregs
2809 set $r8 = $r8_save
2810 flushregs
2811 set $r9 = $r9_save
2812 flushregs
2813 set $r10 = $r10_save
2814 flushregs
2815 set $r11 = $r11_save
2816 flushregs
2817 set $r12 = $r12_save
2818 flushregs
2819 set $sp = $sp_save
2820 flushregs
2821 set $lr = $lr_save
2822 flushregs
2823 set $pc = $pc_save
2824 flushregs
2825 set $r7 = $r7_save
2826 flushregs
2827 flushstack
2828 update
2829 set $kdp_arm_act_counter = 0
2830 end
2831 end
2832
2833 document resetctx
2834 | Syntax: resetctx
2835 | Returns to the original execution context. This command should be
2836 | issued if you wish to resume execution after using the "switchtoact"
2837 | or "switchtoctx" commands.
2838 end
2839
2840 # This is a pre-hook for the continue command, to prevent inadvertent attempts
2841 # to resume from the context switched to for examination.
2842 define hook-continue
2843 resetctx
2844 end
2845
2846 # This is a pre-hook for the detach command, to prevent inadvertent attempts
2847 # to resume from the context switched to for examination.
2848 define hook-detach
2849 resetctx
2850 end
2851
2852 define resume_on
2853 set $resume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_RESUME
2854 dumpinfoint $resume
2855 end
2856
2857 document resume_on
2858 | Syntax: resume_on
2859 | The target system will resume when detaching or exiting from gdb.
2860 | This is the default behavior.
2861 end
2862
2863 define resume_off
2864 set $noresume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_NORESUME
2865 dumpinfoint $noresume
2866 end
2867
2868 document resume_off
2869 | Syntax: resume_off
2870 | The target system won't resume after detaching from gdb and
2871 | can be attached with a new gdb session
2872 end
2873
2874 define paniclog
2875 set $kgm_panic_bufptr = debug_buf
2876 set $kgm_panic_bufptr_max = debug_buf_ptr
2877 while $kgm_panic_bufptr < $kgm_panic_bufptr_max
2878 if *(char *)$kgm_panic_bufptr == 10
2879 printf "\n"
2880 else
2881 printf "%c", *(char *)$kgm_panic_bufptr
2882 end
2883 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1
2884 end
2885 end
2886
2887 document paniclog
2888 | Syntax: paniclog
2889 | Display the panic log information
2890 |
2891 end
2892
2893 define dumpcallqueue
2894 set $kgm_callhead = $arg0
2895 set $kgm_callentry = $kgm_callhead->next
2896 set $kgm_i = 0
2897 while $kgm_callentry != $kgm_callhead
2898 set $kgm_call = (struct call_entry *)$kgm_callentry
2899 printf "0x%08x ", $kgm_call
2900 printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1
2901 output $kgm_call->deadline
2902 printf "\t"
2903 output $kgm_call->func
2904 printf "\n"
2905 set $kgm_i = $kgm_i + 1
2906 set $kgm_callentry = $kgm_callentry->next
2907 end
2908 printf "%d entries\n", $kgm_i
2909 end
2910
2911 document dumpcallqueue
2912 | Syntax: dumpcallqueue <queue head>
2913 | Displays the contents of the specified call_entry queue.
2914 end
2915
2916 define showtaskacts
2917 showtaskthreads $arg0
2918 end
2919 document showtaskacts
2920 | See help showtaskthreads.
2921 end
2922
2923 define showallacts
2924 showallthreads
2925 end
2926 document showallacts
2927 | See help showallthreads.
2928 end
2929
2930
2931 define resetstacks
2932 _kgm_flush_loop
2933 set kdp_pmap = 0
2934 _kgm_flush_loop
2935 resetctx
2936 _kgm_flush_loop
2937 _kgm_update_loop
2938 resetctx
2939 _kgm_update_loop
2940 end
2941
2942 document resetstacks
2943 | Syntax: resetstacks
2944 | Internal kgmacro routine used by the "showuserstack" macro
2945 | to reset the target pmap to the kernel pmap.
2946 end
2947
2948 #Barely effective hacks to work around bugs in the "flush" and "update"
2949 #gdb commands in Tiger (up to 219); these aren't necessary with Panther
2950 #gdb, but do no harm.
2951 define _kgm_flush_loop
2952 set $kgm_flush_loop_ctr = 0
2953 while ($kgm_flush_loop_ctr < 30)
2954 flushregs
2955 flushstack
2956 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1
2957 end
2958 end
2959
2960 define _kgm_update_loop
2961 set $kgm_update_loop_ctr = 0
2962 while ($kgm_update_loop_ctr < 30)
2963 update
2964 set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1
2965 end
2966 end
2967 # Internal routine used by "_loadfrom" to read from 64-bit addresses
2968 # on 32-bit kernels
2969 define _loadk32m64
2970 # set up the manual KDP packet
2971 set manual_pkt.input = 0
2972 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
2973 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
2974 set $kgm_pkt->hdr.request = KDP_READMEM64
2975 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
2976 set $kgm_pkt->hdr.is_reply = 0
2977 set $kgm_pkt->hdr.seq = 0
2978 set $kgm_pkt->hdr.key = 0
2979 set $kgm_pkt->address = (uint64_t)$arg0
2980 set $kgm_pkt->nbytes = sizeof(uint64_t)
2981 set manual_pkt.input = 1
2982 # dummy to make sure manual packet is executed
2983 set $kgm_dummy = &_mh_execute_header
2984 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
2985 if ($kgm_pkt->error == 0)
2986 set $kgm_k32read64 = *(uint64_t *)$kgm_pkt->data
2987 else
2988 set $kgm_k32read64 = 0
2989 end
2990 end
2991
2992 # Internal routine used by "showx86backtrace" to abstract possible loads from
2993 # user space
2994 define _loadfrom
2995 if (kdp_pmap == 0)
2996 set $kgm_loadval = *(uintptr_t *)$arg0
2997 else
2998 if ($kgm_x86_abi == 0xe)
2999 set $kgm_loadval = *(uint32_t *)$arg0
3000 else
3001 if ($kgm_x86_abi == 0xf)
3002 if ($kgm_mtype == $kgm_mtype_i386)
3003 _loadk32m64 $arg0
3004 set $kgm_loadval = $kgm_k32read64
3005 else
3006 set $kgm_loadval = *(uint64_t *)$arg0
3007 end
3008 end
3009 end
3010 end
3011 end
3012
3013
3014 #This is necessary since gdb often doesn't do backtraces on x86 correctly
3015 #in the absence of symbols.The code below in showuserstack and
3016 #showx86backtrace also contains several workarouds for the gdb bug where
3017 #gdb stops macro evaluation because of spurious "Cannot read memory"
3018 #errors on x86. These errors appear on ppc as well, but they don't
3019 #always stop macro evaluation.
3020
3021 set $kgm_cur_frame = 0
3022 set $kgm_cur_pc = 0
3023 set $kgm_x86_abi = 0
3024 define showx86backtrace
3025 if ($kgm_mtype == $kgm_mtype_i386)
3026 set $kgm_frame_reg = $ebp
3027 set $kgm_pc = $eip
3028 set $kgm_ret_off = 4
3029 end
3030 if ($kgm_mtype == $kgm_mtype_x86_64)
3031 set $kgm_frame_reg = $rbp
3032 set $kgm_pc = $rip
3033 set $kgm_ret_off = 8
3034 end
3035
3036 if ($kgm_x86_abi == 0xe)
3037 set $kgm_ret_off = 4
3038 end
3039 if ($kgm_x86_abi == 0xf)
3040 set $kgm_ret_off = 8
3041 end
3042
3043 if ($kgm_cur_frame == 0)
3044 set $kgm_cur_frame = $kgm_frame_reg
3045 end
3046 if ($kgm_cur_pc == 0)
3047 set $kgm_cur_pc = $kgm_pc
3048 end
3049 printf "0: Frame: 0x%016llx PC: 0x%016llx\n", $kgm_cur_frame, $kgm_cur_pc
3050 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
3051 x/i $kgm_cur_pc
3052 end
3053 set $kgm_tmp_frame = $kgm_cur_frame
3054 set $kgm_cur_frame = 0
3055 set $kgm_cur_pc = 0
3056 _loadfrom ($kgm_tmp_frame)
3057 set $kgm_prev_frame = $kgm_loadval
3058 _loadfrom ($kgm_tmp_frame+$kgm_ret_off)
3059 set $kgm_prev_pc = $kgm_loadval
3060 set $kgm_frameno = 1
3061 while ($kgm_prev_frame != 0) && ($kgm_prev_frame != 0x0000000800000008)
3062 printf "%d: Saved frame: 0x%016llx Saved PC: 0x%016llx\n", $kgm_frameno, $kgm_prev_frame, $kgm_prev_pc
3063 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
3064 x/i $kgm_prev_pc
3065 end
3066 _loadfrom ($kgm_prev_frame+$kgm_ret_off)
3067 set $kgm_prev_pc = $kgm_loadval
3068 _loadfrom ($kgm_prev_frame)
3069 set $kgm_prev_frame = $kgm_loadval
3070 set $kgm_frameno = $kgm_frameno + 1
3071 end
3072 set kdp_pmap = 0
3073 set $kgm_x86_abi = 0
3074 end
3075
3076 define showx86backtrace2
3077 set $kgm_cur_frame = $arg0
3078 set $kgm_cur_pc = $arg1
3079 showx86backtrace
3080 end
3081
3082 define showuserstack
3083 select 0
3084 if ($kgm_mtype == $kgm_mtype_ppc)
3085 if ($kdp_act_counter == 0)
3086 set $kdpstate = (struct savearea *) kdp.saved_state
3087 end
3088 set $kdp_act_counter = $kdp_act_counter + 1
3089 set $newact = (struct thread *) $arg0
3090 _kgm_flush_loop
3091 set $checkpc = $newact->machine->upcb.save_srr0
3092 if ($checkpc == 0)
3093 echo This activation does not appear to have
3094 echo \20 a valid user context.\n
3095 else
3096 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
3097 set $pc = $checkpc
3098 #flush and update seem to be executed lazily by gdb on Tiger, hence the
3099 #repeated invocations - see 3743135
3100 _kgm_flush_loop
3101 # This works because the new pmap is used only for reads
3102 set kdp_pmap = $newact->task->map->pmap
3103 _kgm_flush_loop
3104 _kgm_update_loop
3105 bt
3106 resetstacks
3107 _kgm_flush_loop
3108 _kgm_update_loop
3109 resetstacks
3110 _kgm_flush_loop
3111 _kgm_update_loop
3112 end
3113 else
3114 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
3115 set $newact = (struct thread *) $arg0
3116 set $newiss = (x86_saved_state_t *) ($newact->machine->iss)
3117 set $kgm_x86_abi = $newiss.flavor
3118 if ($newiss.flavor == 0xf)
3119 set $checkpc = $newiss.uss.ss_64.isf.rip
3120 set $checkframe = $newiss.uss.ss_64.rbp
3121
3122 else
3123 set $checkpc = $newiss.uss.ss_32.eip
3124 set $checkframe = $newiss.uss.ss_32.ebp
3125 end
3126
3127 if ($checkpc == 0)
3128 echo This activation does not appear to have
3129 echo \20 a valid user context.\n
3130 else
3131 set $kgm_cur_frame = $checkframe
3132 set $kgm_cur_pc = $checkpc
3133 # When have more than one argument is present, don't print usage
3134 if ( $argc == 1 )
3135 printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread ("
3136 showptr $arg0
3137 printf "); you can also examine memory locations in this address space (pmap "
3138 showptr $newact->task->map->pmap
3139 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"
3140 end
3141 set kdp_pmap = $newact->task->map->pmap
3142 _kgm_flush_loop
3143 _kgm_update_loop
3144 end
3145 else
3146 if ($kgm_mtype == $kgm_mtype_arm)
3147 if (kdp->is_conn > 0)
3148 set $kgm_threadp = (struct thread *)$arg0
3149 set $kgm_saved_pmap = kdp_pmap
3150 showactheader
3151 showactint $kgm_threadp 0
3152 set $kgm_thread_pmap = $kgm_threadp->task->map->pmap
3153 set $kgm_thread_sp = $kgm_threadp.machine->PcbData.r[7]
3154 set kdp_pmap = $kgm_thread_pmap
3155 while ($kgm_thread_sp != 0)
3156 set $link_register = *($kgm_thread_sp + 4)
3157 showptrhdrpad
3158 printf " "
3159 showptr $kgm_thread_sp
3160 printf " "
3161 showptr $link_register
3162 printf "\n"
3163 set $kgm_thread_sp = *$kgm_thread_sp
3164 end
3165 set kdp_pmap = $kgm_saved_pmap
3166 else
3167 echo You must be connected via nanokdp to use this macro\n
3168 end
3169 else
3170 echo showuserstack not supported on this architecture\n
3171 end
3172 end
3173 end
3174 end
3175 document showuserstack
3176 Syntax: showuserstack <address of thread activation>
3177 |This command displays a numeric backtrace for the user space stack of
3178 |the given thread activation. It may, of course, fail to display a
3179 |complete backtrace if portions of the user stack are not mapped in.
3180 |Symbolic backtraces can be obtained either by running gdb on the
3181 |user space binary, or a tool such as "symbolicate".
3182 |Note that while this command works on Panther's gdb, an issue
3183 |with Tiger gdb (3743135) appears to hamper the evaluation of this
3184 |macro in some cases.
3185 end
3186
3187 define showtaskuserstacks
3188 set $kgm_taskp = (struct task *)$arg0
3189 set $kgm_head_actp = &($kgm_taskp->threads)
3190 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
3191 while $kgm_actp != $kgm_head_actp
3192 printf "For thread "
3193 showptr $kgm_actp
3194 printf "\n"
3195 showuserstack $kgm_actp quiet
3196 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
3197 showx86backtrace
3198 end
3199 set kdp_pmap=0
3200 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
3201 printf "\n"
3202 end
3203 showuserlibraries $kgm_taskp
3204 end
3205 document showtaskuserstacks
3206 Syntax: (gdb) showtaskuserstacks <task>
3207 | Print out the user stack for each thread in a task, followed by the user libraries.
3208 end
3209
3210
3211 define showuserregisters
3212 set $kgm_threadp = (struct thread *)$arg0
3213 set $kgm_taskp = $kgm_threadp->task
3214 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
3215 set $newiss = (x86_saved_state_t *) ($kgm_threadp->machine.iss)
3216 set $kgm_x86_abi = $newiss.flavor
3217 if ($newiss.flavor == 0xf)
3218 printf "X86 Thread State (64-bit):\n"
3219 set $kgm_ss64 = $newiss.uss.ss_64
3220
3221 printf " rax: "
3222 showuserptr $kgm_ss64.rax
3223 printf " rbx: "
3224 showuserptr $kgm_ss64.rbx
3225 printf " rcx: "
3226 showuserptr $kgm_ss64.rcx
3227 printf " rdx: "
3228 showuserptr $kgm_ss64.rdx
3229 printf "\n"
3230
3231 printf " rdi: "
3232 showuserptr $kgm_ss64.rdi
3233 printf " rsi: "
3234 showuserptr $kgm_ss64.rsi
3235 printf " rbp: "
3236 showuserptr $kgm_ss64.rbp
3237 printf " rsp: "
3238 showuserptr $kgm_ss64.isf.rsp
3239 printf "\n"
3240
3241 printf " r8: "
3242 showuserptr $kgm_ss64.r8
3243 printf " r9: "
3244 showuserptr $kgm_ss64.r9
3245 printf " r10: "
3246 showuserptr $kgm_ss64.r10
3247 printf " r11: "
3248 showuserptr $kgm_ss64.r11
3249 printf "\n"
3250
3251 printf " r12: "
3252 showuserptr $kgm_ss64.r12
3253 printf " r13: "
3254 showuserptr $kgm_ss64.r13
3255 printf " r14: "
3256 showuserptr $kgm_ss64.r14
3257 printf " r15: "
3258 showuserptr $kgm_ss64.r15
3259 printf "\n"
3260
3261 printf " rip: "
3262 showuserptr $kgm_ss64.isf.rip
3263 printf " rfl: "
3264 showuserptr $kgm_ss64.isf.rflags
3265 printf " cr2: "
3266 showuserptr $kgm_ss64.cr2
3267 printf "\n"
3268 else
3269 printf "X86 Thread State (32-bit):\n"
3270 set $kgm_ss32 = $newiss.uss.ss_32
3271
3272 printf " eax: "
3273 showuserptr $kgm_ss32.eax
3274 printf " ebx: "
3275 showuserptr $kgm_ss32.ebx
3276 printf " ecx: "
3277 showuserptr $kgm_ss32.ecx
3278 printf " edx: "
3279 showuserptr $kgm_ss32.edx
3280 printf "\n"
3281
3282 printf " edi: "
3283 showuserptr $kgm_ss32.edi
3284 printf " esi: "
3285 showuserptr $kgm_ss32.esi
3286 printf " ebp: "
3287 showuserptr $kgm_ss32.ebp
3288 printf " esp: "
3289 showuserptr $kgm_ss32.uesp
3290 printf "\n"
3291
3292 printf " ss: "
3293 showuserptr $kgm_ss32.ss
3294 printf " efl: "
3295 showuserptr $kgm_ss32.efl
3296 printf " eip: "
3297 showuserptr $kgm_ss32.eip
3298 printf " cs: "
3299 showuserptr $kgm_ss32.cs
3300 printf "\n"
3301
3302 printf " ds: "
3303 showuserptr $kgm_ss32.ds
3304 printf " es: "
3305 showuserptr $kgm_ss32.es
3306 printf " fs: "
3307 showuserptr $kgm_ss32.fs
3308 printf " gs: "
3309 showuserptr $kgm_ss32.gs
3310 printf "\n"
3311
3312 printf " cr2: "
3313 showuserptr $kgm_ss32.cr2
3314 printf "\n"
3315 end
3316 else
3317 if ($kgm_mtype == $kgm_mtype_arm)
3318 printf "ARM Thread State:\n"
3319 set $kgm_pcb = (arm_saved_state_t *) ($kgm_threadp->machine.upcb)
3320
3321 printf " r0: "
3322 showuserptr $kgm_pcb.r[0]
3323 printf " r1: "
3324 showuserptr $kgm_pcb.r[1]
3325 printf " r2: "
3326 showuserptr $kgm_pcb.r[2]
3327 printf " r3: "
3328 showuserptr $kgm_pcb.r[3]
3329 printf "\n"
3330
3331 printf " r4: "
3332 showuserptr $kgm_pcb.r[4]
3333 printf " r5: "
3334 showuserptr $kgm_pcb.r[5]
3335 printf " r6: "
3336 showuserptr $kgm_pcb.r[6]
3337 printf " r7: "
3338 showuserptr $kgm_pcb.r[7]
3339 printf "\n"
3340
3341 printf " r8: "
3342 showuserptr $kgm_pcb.r[8]
3343 printf " r9: "
3344 showuserptr $kgm_pcb.r[9]
3345 printf " r10: "
3346 showuserptr $kgm_pcb.r[10]
3347 printf " r11: "
3348 showuserptr $kgm_pcb.r[11]
3349 printf "\n"
3350
3351 printf " ip: "
3352 showuserptr $kgm_pcb.r[12]
3353 printf " sp: "
3354 showuserptr $kgm_pcb.sp
3355 printf " lr: "
3356 showuserptr $kgm_pcb.lr
3357 printf " pc: "
3358 showuserptr $kgm_pcb.pc
3359 printf "\n"
3360
3361 printf " cpsr: "
3362 showuserptr $kgm_pcb.cpsr
3363 printf "\n"
3364 else
3365 echo showuserregisters not supported on this architecture\n
3366 end
3367 end
3368 end
3369 document showuserregisters
3370 Syntax: showuserstack <address of thread>
3371 |This command displays the last known user register state
3372 |for the thread. This map not be correct for cases where
3373 |the thread is currently executing in userspace. However
3374 |for threads that have entered the kernel (either explicitly
3375 |with a system call or implicitly with a fault), it should
3376 |be accurate
3377 end
3378
3379 define showtaskuserregisters
3380 set $kgm_taskp = (struct task *)$arg0
3381 set $kgm_head_actp = &($kgm_taskp->threads)
3382 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
3383 while $kgm_actp != $kgm_head_actp
3384 printf "For thread "
3385 showptr $kgm_actp
3386 printf "\n"
3387 showuserregisters $kgm_actp
3388 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
3389 printf "\n"
3390 end
3391 end
3392 document showtaskuserregisters
3393 Syntax: (gdb) showtaskuserregisters <task>
3394 | Print out the user registers for each thread in a task
3395 end
3396
3397 define kdp-reboot
3398 # Alternatively, set *(*(unsigned **) 0x2498) = 1
3399 # (or 0x5498 on PPC, 0xffffff8000002928 on x86_64, 0xffff049c on arm)
3400 manualhdrint $kgm_kdp_pkt_hostreboot
3401 continue
3402 end
3403
3404 document kdp-reboot
3405 Syntax: kdp-reboot
3406 |Reboot the remote target machine; not guaranteed to succeed.
3407 end
3408
3409 define kdpversionint
3410 # set up the manual KDP packet
3411 set manual_pkt.input = 0
3412 set manual_pkt.len = sizeof(kdp_version_req_t)
3413 set $kgm_pkt = (kdp_version_req_t *)&manual_pkt.data
3414 set $kgm_pkt->hdr.request = KDP_VERSION
3415 set $kgm_pkt->hdr.len = sizeof(kdp_version_req_t)
3416 set $kgm_pkt->hdr.is_reply = 0
3417 set $kgm_pkt->hdr.seq = 0
3418 set $kgm_pkt->hdr.key = 0
3419 set manual_pkt.input = 1
3420 # dummy to make sure manual packet is executed
3421 set $kgm_dummy = &_mh_execute_header
3422 set $kgm_pkt = (kdp_version_reply_t *)&manual_pkt.data
3423 set $kgm_kdp_version = $kgm_pkt->version
3424 set $kgm_kdp_feature = $kgm_pkt->feature
3425 end
3426
3427 define kdp-version
3428 kdpversionint
3429 printf "KDP VERSION = %d, FEATURE = 0x%x\n", $kgm_kdp_version, $kgm_kdp_feature
3430 end
3431
3432 document kdp-version
3433 Syntax: kdp-version
3434 |Get the KDP protocol version being used by the kernel.
3435 end
3436
3437 define dumpinfoint
3438 # set up the manual KDP packet
3439 set manual_pkt.input = 0
3440
3441 set manual_pkt.len = sizeof(kdp_dumpinfo_req_t)
3442 set $kgm_pkt = (kdp_dumpinfo_req_t *)&manual_pkt.data
3443 set $kgm_pkt->hdr.request = KDP_DUMPINFO
3444 set $kgm_pkt->hdr.len = sizeof(kdp_dumpinfo_req_t)
3445 set $kgm_pkt->hdr.is_reply = 0
3446 set $kgm_pkt->hdr.seq = 0
3447 set $kgm_pkt->hdr.key = 0
3448 set $kgm_pkt->type = $arg0
3449 set $kgm_pkt->name = ""
3450 set $kgm_pkt->destip = ""
3451 set $kgm_pkt->routerip = ""
3452 set $kgm_pkt->port = 0
3453
3454 if $argc > 1
3455 set $kgm_pkt->name = "$arg1"
3456 end
3457 if $argc > 2
3458 set $kgm_pkt->destip = "$arg2"
3459 end
3460 if $argc > 3
3461 set $kgm_pkt->routerip = "$arg3"
3462 end
3463 if $argc > 4
3464 set $kgm_pkt->port = $arg4
3465 end
3466
3467 set manual_pkt.input = 1
3468 # dummy to make sure manual packet is executed
3469 set $kgm_dummy = &_mh_execute_header
3470 end
3471
3472 define sendcore
3473 if $argc > 1
3474 dumpinfoint KDP_DUMPINFO_CORE $arg1 $arg0
3475 else
3476 dumpinfoint KDP_DUMPINFO_CORE \0 $arg0
3477 end
3478 end
3479
3480 document sendcore
3481 Syntax: sendcore <IP address> [filename]
3482 |Configure the kernel to transmit a kernel coredump to a server (kdumpd)
3483 |at the specified IP address. This is useful when the remote target has
3484 |not been previously configured to transmit coredumps, and you wish to
3485 |preserve kernel state for later examination. NOTE: You must issue a "continue"
3486 |command after using this macro to trigger the kernel coredump. The kernel
3487 |will resume waiting in the debugger after completion of the coredump. You
3488 |may disable coredumps by executing the "disablecore" macro. You can
3489 |optionally specify the filename to be used for the generated core file.
3490 end
3491
3492 define sendsyslog
3493 if $argc > 1
3494 dumpinfoint KDP_DUMPINFO_SYSTEMLOG $arg1 $arg0
3495 else
3496 dumpinfoint KDP_DUMPINFO_SYSTEMLOG \0 $arg0
3497 end
3498 end
3499
3500 document sendsyslog
3501 Syntax: sendsyslog <IP address> [filename]
3502 |Configure the kernel to transmit a kernel system log to a server (kdumpd)
3503 |at the specified IP address. NOTE: You must issue a "continue"
3504 |command after using this macro to trigger the kernel system log. The kernel
3505 |will resume waiting in the debugger after completion. You can optionally
3506 |specify the name to be used for the generated system log.
3507 end
3508
3509 define sendpaniclog
3510 if panicstr
3511 if $argc > 1
3512 dumpinfoint KDP_DUMPINFO_PANICLOG $arg1 $arg0
3513 else
3514 dumpinfoint KDP_DUMPINFO_PANICLOG \0 $arg0
3515 end
3516 else
3517 printf "No panic log available.\n"
3518 end
3519 end
3520
3521 document sendpaniclog
3522 Syntax: sendpaniclog <IP address> [filename]
3523 |Configure the kernel to transmit a kernel paniclog to a server (kdumpd)
3524 |at the specified IP address. NOTE: You must issue a "continue"
3525 |command after using this macro to trigger the kernel panic log. The kernel
3526 |will resume waiting in the debugger after completion. You can optionally
3527 |specify the name to be used for the generated panic log.
3528 end
3529
3530 define getdumpinfo
3531 dumpinfoint KDP_DUMPINFO_GETINFO
3532 set $kgm_dumpinfo = (kdp_dumpinfo_reply_t *) manual_pkt.data
3533 if $kgm_dumpinfo->type & KDP_DUMPINFO_REBOOT
3534 printf "Sysem will reboot after kernel info gets dumped.\n"
3535 else
3536 printf "Sysem will not reboot after kernel info gets dumped.\n"
3537 end
3538 if $kgm_dumpinfo->type & KDP_DUMPINFO_NORESUME
3539 printf "System will allow a re-attach after a KDP disconnect.\n"
3540 else
3541 printf "System will resume after a KDP disconnect.\n"
3542 end
3543 set $kgm_dumpinfo_type = $kgm_dumpinfo->type & KDP_DUMPINFO_MASK
3544 if $kgm_dumpinfo_type == KDP_DUMPINFO_DISABLE
3545 printf "Kernel not setup for remote dumps.\n"
3546 else
3547 printf "Remote dump type: "
3548 if $kgm_dumpinfo_type == KDP_DUMPINFO_CORE
3549 printf "Core file\n"
3550 end
3551 if $kgm_dumpinfo_type == KDP_DUMPINFO_PANICLOG
3552 printf "Panic log\n"
3553 end
3554 if $kgm_dumpinfo_type == KDP_DUMPINFO_SYSTEMLOG
3555 printf "System log\n"
3556 end
3557
3558 printf "Name: "
3559 if $kgm_dumpinfo->name[0] == '\0'
3560 printf "(autogenerated)\n"
3561 else
3562 printf "%s\n", $kgm_dumpinfo->name
3563 end
3564
3565 printf "Network Info: %s[%d] ", $kgm_dumpinfo->destip, $kgm_dumpinfo->port
3566 if $kgm_dumpinfo->routerip[0] == '\0'
3567 printf "\n"
3568 else
3569 printf "Router: %s\n", $kgm_dumpinfo->routerip
3570 end
3571 end
3572 end
3573
3574 document getdumpinfo
3575 Syntax: getdumpinfo
3576 |Retrieve the current remote dump settings.
3577 end
3578
3579 define setdumpinfo
3580 dumpinfoint KDP_DUMPINFO_SETINFO $arg0 $arg1 $arg2 $arg3
3581 end
3582
3583 document setdumpinfo
3584 Syntax: setdumpinfo <filename> <ip> <router> <port>
3585 |Configure the current remote dump settings. Specify \0 if you
3586 |want to use the defaults (filename) or previously configured
3587 |settings (ip/router). Specify 0 for the port if you wish to
3588 |use the previously configured/default setting for that.
3589 end
3590
3591 define disablecore
3592 dumpinfoint KDP_DUMPINFO_DISABLE
3593 end
3594
3595 document disablecore
3596 Syntax: disablecore
3597 |Reconfigures the kernel so that it no longer transmits kernel coredumps. This
3598 |complements the "sendcore" macro, but it may be used if the kernel has been
3599 |configured to transmit coredumps through boot-args as well.
3600 end
3601
3602 define switchtocorethread
3603 set $newact = (struct thread *) $arg0
3604 select 0
3605 if ($newact->kernel_stack == 0)
3606 echo This thread does not have a stack.\n
3607 echo continuation:
3608 output/a (unsigned) $newact.continuation
3609 echo \n
3610 else
3611 if ($kgm_mtype == $kgm_mtype_ppc)
3612 loadcontext $newact->machine->pcb
3613 flushstack
3614 set $pc = $newact->machine->pcb.save_srr0
3615 else
3616 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
3617 set $kgm_cstatep = (struct x86_kernel_state *) \
3618 ($newact->kernel_stack + kernel_stack_size \
3619 - sizeof(struct x86_kernel_state))
3620 loadcontext $kgm_cstatep
3621 flushstack
3622 else
3623 echo switchtocorethread not supported on this architecture\n
3624 end
3625 end
3626 showcontext_int
3627 end
3628 end
3629
3630 document switchtocorethread
3631 Syntax: switchtocorethread <address of activation>
3632 | The corefile equivalent of "switchtoact". When debugging a kernel coredump
3633 | file, this command can be used to examine the execution context and stack
3634 | trace for a given thread activation. For example, to view the backtrace
3635 | for a thread issue "switchtocorethread <address>", followed by "bt".
3636 | Before resuming execution, issue a "resetcorectx" command, to
3637 | return to the original execution context. Note that this command
3638 | requires gdb support, as documented in Radar 3401283.
3639 end
3640
3641 define loadcontext
3642 select 0
3643 if ($kgm_mtype == $kgm_mtype_ppc)
3644 set $kgm_contextp = (struct savearea *) $arg0
3645 set $pc = $kgm_contextp.save_srr0
3646 set $r1 = $kgm_contextp.save_r1
3647 set $lr = $kgm_contextp.save_lr
3648
3649 set $r2 = $kgm_contextp.save_r2
3650 set $r3 = $kgm_contextp.save_r3
3651 set $r4 = $kgm_contextp.save_r4
3652 set $r5 = $kgm_contextp.save_r5
3653 set $r6 = $kgm_contextp.save_r6
3654 set $r7 = $kgm_contextp.save_r7
3655 set $r8 = $kgm_contextp.save_r8
3656 set $r9 = $kgm_contextp.save_r9
3657 set $r10 = $kgm_contextp.save_r10
3658 set $r11 = $kgm_contextp.save_r11
3659 set $r12 = $kgm_contextp.save_r12
3660 set $r13 = $kgm_contextp.save_r13
3661 set $r14 = $kgm_contextp.save_r14
3662 set $r15 = $kgm_contextp.save_r15
3663 set $r16 = $kgm_contextp.save_r16
3664 set $r17 = $kgm_contextp.save_r17
3665 set $r18 = $kgm_contextp.save_r18
3666 set $r19 = $kgm_contextp.save_r19
3667 set $r20 = $kgm_contextp.save_r20
3668 set $r21 = $kgm_contextp.save_r21
3669 set $r22 = $kgm_contextp.save_r22
3670 set $r23 = $kgm_contextp.save_r23
3671 set $r24 = $kgm_contextp.save_r24
3672 set $r25 = $kgm_contextp.save_r25
3673 set $r26 = $kgm_contextp.save_r26
3674 set $r27 = $kgm_contextp.save_r27
3675 set $r28 = $kgm_contextp.save_r28
3676 set $r29 = $kgm_contextp.save_r29
3677 set $r30 = $kgm_contextp.save_r30
3678 set $r31 = $kgm_contextp.save_r31
3679
3680 set $cr = $kgm_contextp.save_cr
3681 set $ctr = $kgm_contextp.save_ctr
3682 else
3683 if ($kgm_mtype == $kgm_mtype_i386)
3684 set $kgm_contextp = (struct x86_kernel_state *) $arg0
3685 set $ebx = $kgm_contextp->k_ebx
3686 set $ebp = $kgm_contextp->k_ebp
3687 set $edi = $kgm_contextp->k_edi
3688 set $esi = $kgm_contextp->k_esi
3689 set $eip = $kgm_contextp->k_eip
3690 set $pc = $kgm_contextp->k_eip
3691 else
3692 if ($kgm_mtype == $kgm_mtype_x86_64)
3693 set $kgm_contextp = (struct x86_kernel_state *) $arg0
3694 set $rbx = $kgm_contextp->k_rbx
3695 set $rbp = $kgm_contextp->k_rbp
3696 set $r12 = $kgm_contextp->k_r12
3697 set $r13 = $kgm_contextp->k_r13
3698 set $r14 = $kgm_contextp->k_r14
3699 set $r15 = $kgm_contextp->k_r15
3700 set $rip = $kgm_contextp->k_rip
3701 set $pc = $kgm_contextp->k_rip
3702 else
3703 echo loadcontext not supported on this architecture\n
3704 end
3705 end
3706 end
3707 end
3708
3709 define resetcorectx
3710 select 0
3711 if ($kgm_mtype == $kgm_mtype_ppc)
3712 set $kgm_corecontext = (struct savearea *) kdp.saved_state
3713 loadcontext $kgm_corecontext
3714 else
3715 if ($kgm_mtype == $kgm_mtype_i386)
3716 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
3717 set $ebx = $kdpstatep->ebx
3718 set $ebp = $kdpstatep->ebp
3719 set $edi = $kdpstatep->edi
3720 set $esi = $kdpstatep->esi
3721 set $eip = $kdpstatep->eip
3722 set $eax = $kdpstatep->eax
3723 set $ecx = $kdpstatep->ecx
3724 set $edx = $kdpstatep->edx
3725 flushregs
3726 flushstack
3727 set $pc = $kdpstatep->eip
3728 update
3729 else
3730 echo resetcorectx not supported on this architecture\n
3731 end
3732 end
3733 showcontext_int
3734 end
3735
3736 document resetcorectx
3737 Syntax: resetcorectx
3738 | The corefile equivalent of "resetctx". Returns to the original
3739 | execution context (that of the active thread at the time of the NMI or
3740 | panic). This command should be issued if you wish to resume
3741 | execution after using the "switchtocorethread" command.
3742 end
3743
3744 #Helper function for "showallgdbstacks"
3745
3746 define showgdbthread
3747 printf " 0x%08x ", $arg0
3748 set $kgm_thread = *(struct thread *)$arg0
3749 printf "0x%08x ", $arg0
3750 printf "%3d ", $kgm_thread.sched_pri
3751 set $kgm_state = $kgm_thread.state
3752 if $kgm_state & 0x80
3753 printf "I"
3754 end
3755 if $kgm_state & 0x40
3756 printf "P"
3757 end
3758 if $kgm_state & 0x20
3759 printf "A"
3760 end
3761 if $kgm_state & 0x10
3762 printf "H"
3763 end
3764 if $kgm_state & 0x08
3765 printf "U"
3766 end
3767 if $kgm_state & 0x04
3768 printf "R"
3769 end
3770 if $kgm_state & 0x02
3771 printf "S"
3772 end
3773 if $kgm_state & 0x01
3774 printf "W\t"
3775 printf "0x%08x ", $kgm_thread.wait_queue
3776 output /a (unsigned) $kgm_thread.wait_event
3777 if ($kgm_thread.uthread != 0)
3778 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
3779 if ($kgm_uthread->uu_wmesg != 0)
3780 printf " \"%s\"", $kgm_uthread->uu_wmesg
3781 end
3782 end
3783 end
3784 if $arg1 != 0
3785 if ($kgm_thread.kernel_stack != 0)
3786 if ($kgm_thread.reserved_stack != 0)
3787 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack
3788 end
3789 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack
3790 if ($kgm_mtype == $kgm_mtype_ppc)
3791 set $mysp = $kgm_thread.machine.pcb->save_r1
3792 end
3793 if ($kgm_mtype == $kgm_mtype_i386)
3794 set $kgm_statep = (struct x86_kernel_state *) \
3795 ($kgm_thread->kernel_stack + kernel_stack_size \
3796 - sizeof(struct x86_kernel_state))
3797 set $mysp = $kgm_statep->k_ebp
3798 end
3799 if ($kgm_mtype == $kgm_mtype_arm)
3800 if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
3801 && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
3802 set $mysp = $r7
3803 else
3804 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
3805 set $mysp = $kgm_statep->r[7]
3806 end
3807 end
3808 set $prevsp = 0
3809 printf "\n\t\tstacktop=0x%08x", $mysp
3810 if ($arg2 == 0)
3811 switchtoact $arg0
3812 else
3813 switchtocorethread $arg0
3814 end
3815 bt
3816 else
3817 printf "\n\t\t\tcontinuation="
3818 output /a (unsigned) $kgm_thread.continuation
3819 end
3820 printf "\n"
3821 else
3822 printf "\n"
3823 end
3824 end
3825
3826 #Use of this macro is currently (8/04) blocked by the fact that gdb
3827 #stops evaluating macros when encountering an error, such as a failure
3828 #to read memory from a certain location. Until this issue (described in
3829 #3758949) is addressed, evaluation of this macro may stop upon
3830 #encountering such an error.
3831
3832 define showallgdbstacks
3833 set $kgm_head_taskp = &tasks
3834 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
3835 while $kgm_taskp != $kgm_head_taskp
3836 showtaskheader
3837 showtaskint $kgm_taskp
3838 set $kgm_head_actp = &($kgm_taskp->threads)
3839 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
3840 while $kgm_actp != $kgm_head_actp
3841 showactheader
3842 showgdbthread $kgm_actp 1 0
3843 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
3844 end
3845 printf "\n"
3846 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
3847 end
3848 resetctx
3849 end
3850
3851 document showallgdbstacks
3852 Syntax: showallgdbstacks
3853 | An alternative to "showallstacks". Iterates through the task list and
3854 | displays a gdb generated backtrace for each kernel thread. It is
3855 | advantageous in that it is much faster than "showallstacks", and
3856 | decodes function call arguments and displays source level traces, but
3857 | it has the drawback that it doesn't determine if frames belong to
3858 | functions from kernel extensions, as with "showallstacks".
3859 | This command may terminate prematurely because of a gdb bug
3860 | (Radar 3758949), which stops macro evaluation on memory read
3861 | errors.
3862 end
3863
3864 define showallgdbcorestacks
3865 select 0
3866 set $kgm_head_taskp = &tasks
3867 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
3868 while $kgm_taskp != $kgm_head_taskp
3869 showtaskheader
3870 showtaskint $kgm_taskp
3871 set $kgm_head_actp = &($kgm_taskp->threads)
3872 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
3873 while $kgm_actp != $kgm_head_actp
3874 showactheader
3875 showgdbthread $kgm_actp 1 1
3876 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
3877 end
3878 printf "\n"
3879 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
3880 end
3881 resetcorectx
3882 end
3883
3884
3885 document showallgdbcorestacks
3886 Syntax: showallgdbcorestacks
3887 |Corefile version of "showallgdbstacks"
3888 end
3889
3890
3891 define switchtouserthread
3892 select 0
3893 if ($kgm_mtype == $kgm_mtype_ppc)
3894 if ($kdp_act_counter == 0)
3895 set $kdpstate = (struct savearea *) kdp.saved_state
3896 end
3897 set $kdp_act_counter = $kdp_act_counter + 1
3898 set $newact = (struct thread *) $arg0
3899 _kgm_flush_loop
3900 set $checkpc = $newact->machine->upcb.save_srr0
3901 if ($checkpc == 0)
3902 echo This activation does not appear to have
3903 echo \20 a valid user context.\n
3904 else
3905 set (struct savearea *) kdp.saved_state=$newact->machine->upcb
3906 set $pc = $checkpc
3907 #flush and update seem to be executed lazily by gdb on Tiger, hence the
3908 #repeated invocations - see 3743135
3909 _kgm_flush_loop
3910 # This works because the new pmap is used only for reads
3911 set kdp_pmap = $newact->task->map->pmap
3912 _kgm_flush_loop
3913 _kgm_update_loop
3914 end
3915 else
3916 echo switchtouserthread not implemented for this architecture.\n
3917 end
3918 end
3919
3920 document switchtouserthread
3921 Syntax: switchtouserthread <address of thread>
3922 | Analogous to switchtoact, but switches to the user context of a
3923 | specified thread address. Similar to the "showuserstack"
3924 | command, but this command does not return gdb to the kernel context
3925 | immediately. This is to assist with the following (rather risky)
3926 | manoeuvre - upon switching to the user context and virtual address
3927 | space, the user may choose to call remove-symbol-file on the
3928 | mach_kernel symbol file, and then add-symbol-file on the user space
3929 | binary's symfile. gdb can then generate symbolic backtraces
3930 | for the user space thread. To return to the
3931 | kernel context and virtual address space, the process must be
3932 | reversed, i.e. call remove-symbol-file on the user space symbols, and
3933 | then add-symbol-file on the appropriate mach_kernel, and issue the
3934 | "resetstacks" command. Note that gdb may not react kindly to all these
3935 | symbol file switches. The same restrictions that apply to "showuserstack"
3936 | apply here - pages that have been paged out cannot be read while in the
3937 | debugger context, so backtraces may terminate early.
3938 | If the virtual addresses in the stack trace do not conflict with those
3939 | of symbols in the kernel's address space, it may be sufficient to
3940 | just do an add-symbol-file on the user space binary's symbol file.
3941 | Note that while this command works on Panther's gdb, an issue
3942 | with Tiger gdb (3743135) appears to hamper the evaluation of this
3943 | macro in some cases.
3944 end
3945
3946 define showmetaclass
3947 set $kgm_metaclassp = (OSMetaClass *)$arg0
3948 printf "%-5d", $kgm_metaclassp->instanceCount
3949 printf "x %5d bytes", $kgm_metaclassp->classSize
3950 printf " %s\n", $kgm_metaclassp->className->string
3951 end
3952
3953 define showstring
3954 printf "\"%s\"", ((OSString *)$arg0)->string
3955 end
3956
3957 define shownumber
3958 printf "%lld", ((OSNumber *)$arg0)->value
3959 end
3960
3961 define showboolean
3962 if ($arg0 == gOSBooleanFalse)
3963 printf "No"
3964 else
3965 printf "Yes"
3966 end
3967 end
3968
3969 define showdatabytes
3970 set $kgm_data = (OSData *)$arg0
3971
3972 printf "<"
3973 set $kgm_datap = (const unsigned char *) $kgm_data->data
3974 set $kgm_idx = 0
3975 while ( $kgm_idx < $kgm_data->length )
3976 printf "%02X", *$kgm_datap
3977 set $kgm_datap = $kgm_datap + 1
3978 set $kgm_idx = $kgm_idx + 1
3979 end
3980 printf ">\n"
3981 end
3982
3983 define showdata
3984 set $kgm_data = (OSData *)$arg0
3985
3986 printf "<"
3987 set $kgm_datap = (const unsigned char *) $kgm_data->data
3988
3989 set $kgm_printstr = 0
3990 if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3))
3991 set $kgm_bytes = *(unsigned int *) $kgm_datap
3992 if (0xffff0000 & $kgm_bytes)
3993 set $kgm_idx = 0
3994 set $kgm_printstr = 1
3995 while ($kgm_idx++ < 4)
3996 set $kgm_bytes = $kgm_bytes >> 8
3997 set $kgm_char = 0xff & $kgm_bytes
3998 if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e)))
3999 set $kgm_printstr = 0
4000 end
4001 end
4002 end
4003 end
4004
4005 set $kgm_idx = 0
4006 if ($kgm_printstr)
4007 set $kgm_quoted = 0
4008 while ($kgm_idx < $kgm_data->length)
4009 set $kgm_char = $kgm_datap[$kgm_idx++]
4010 if ($kgm_char)
4011 if (0 == $kgm_quoted)
4012 set $kgm_quoted = 1
4013 if ($kgm_idx > 1)
4014 printf ",\""
4015 else
4016 printf "\""
4017 end
4018 end
4019 printf "%c", $kgm_char
4020 else
4021 if ($kgm_quoted)
4022 set $kgm_quoted = 0
4023 printf "\""
4024 end
4025 end
4026 end
4027 if ($kgm_quoted)
4028 printf "\""
4029 end
4030 else
4031 if (0 == (3 & (unsigned int)$kgm_datap))
4032 while (($kgm_idx + 3) <= $kgm_data->length)
4033 printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx]
4034 set $kgm_idx = $kgm_idx + 4
4035 end
4036 end
4037 while ($kgm_idx < $kgm_data->length)
4038 printf "%02x", $kgm_datap[$kgm_idx++]
4039 end
4040 end
4041 printf ">"
4042 end
4043
4044 define showdictionaryint
4045 set $kgm$arg0_dict = (OSDictionary *)$arg1
4046
4047 printf "{"
4048 set $kgm$arg0_idx = 0
4049 while ($kgm$arg0_idx < $kgm$arg0_dict->count)
4050 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key
4051 showobjectint _$arg0 $kgm_obj
4052 printf "="
4053 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value
4054 showobjectint _$arg0 $kgm_obj
4055 if ($kgm$arg0_idx < $kgm$arg0_dict->count)
4056 printf ","
4057 end
4058 end
4059 printf "}"
4060 end
4061
4062 define indent
4063 set $kgm_idx = 0
4064 while ($kgm_idx < $arg0)
4065 if ($arg1 & (1 << $kgm_idx++))
4066 printf "| "
4067 else
4068 printf " "
4069 end
4070 end
4071 end
4072
4073 define showregdictionary
4074 indent $kgm_reg_depth+2 $arg1
4075 printf "{\n"
4076
4077 set $kgm_reg_idx = 0
4078 while ($kgm_reg_idx < $arg0->count)
4079 indent $kgm_reg_depth+2 $arg1
4080 printf " "
4081 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key
4082 showobjectint _ $kgm_obj
4083 printf " = "
4084
4085 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value
4086 showobjectint _ $kgm_obj
4087 printf "\n"
4088 end
4089 indent $kgm_reg_depth+2 $arg1
4090 printf "}\n"
4091 end
4092
4093
4094 define showorderedsetarrayint
4095 set $kgm$arg0_array = (_Element *)$arg1
4096 set $kgm$arg0_count = $arg2
4097
4098 set $kgm$arg0_idx = 0
4099 while ($kgm$arg0_idx < $kgm$arg0_count)
4100 set $kgm_obj = $kgm$arg0_array[$kgm$arg0_idx++]
4101 showobjectint _$arg0 $kgm_obj
4102 if ($kgm$arg0_idx < $kgm$arg0_count)
4103 printf ","
4104 end
4105 end
4106 end
4107
4108 define showorderedsetint
4109 set $kgm_array = ((OSOrderedSet *)$arg1)->array
4110 set $count = ((OSOrderedSet *)$arg1)->count
4111 printf "["
4112 showorderedsetarrayint $arg0 $kgm_array $count
4113 printf "]"
4114 end
4115
4116 define showarraysetint
4117 set $kgm$arg0_array = (OSArray *)$arg1
4118
4119 set $kgm$arg0_idx = 0
4120 while ($kgm$arg0_idx < $kgm$arg0_array->count)
4121 set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++]
4122 showobjectint _$arg0 $kgm_obj
4123 if ($kgm$arg0_idx < $kgm$arg0_array->count)
4124 printf ","
4125 end
4126 end
4127 end
4128
4129 define showarrayint
4130 printf "("
4131 showarraysetint $arg0 $arg1
4132 printf ")"
4133 end
4134
4135 define showsetint
4136 set $kgm_array = ((OSSet *)$arg1)->members
4137 printf "["
4138 showarraysetint $arg0 $kgm_array
4139 printf "]"
4140 end
4141
4142
4143 define showobjectint
4144 set $kgm_obj = (OSObject *) $arg1
4145 set $kgm_vt = *((void **) $arg1)
4146
4147 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
4148 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
4149 end
4150
4151 if ($kgm_show_object_addrs)
4152 printf "`object "
4153 showptr $arg1
4154 printf ", vt "
4155 output /a (unsigned long) $kgm_vt
4156 if ($kgm_show_object_retain)
4157 printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16
4158 end
4159 printf "` "
4160 end
4161
4162 # No multiple-inheritance
4163 set $kgm_shown = 0
4164 if ($kgm_vt == &_ZTV8OSString)
4165 showstring $arg1
4166 set $kgm_shown = 1
4167 end
4168 if ($kgm_vt == &_ZTV8OSSymbol)
4169 showstring $arg1
4170 set $kgm_shown = 1
4171 end
4172 if ($kgm_vt == &_ZTV8OSNumber)
4173 shownumber $arg1
4174 set $kgm_shown = 1
4175 end
4176 if ($kgm_vt == &_ZTV6OSData)
4177 if $kgm_show_data_alwaysbytes == 1
4178 showdatabytes $arg1
4179 else
4180 showdata $arg1
4181 end
4182 set $kgm_shown = 1
4183 end
4184 if ($kgm_vt == &_ZTV9OSBoolean)
4185 showboolean $arg1
4186 set $kgm_shown = 1
4187 end
4188 if ($kgm_vt == &_ZTV12OSDictionary)
4189 showdictionaryint _$arg0 $arg1
4190 set $kgm_shown = 1
4191 end
4192 if ($kgm_vt == &_ZTV7OSArray)
4193 showarrayint _$arg0 $arg1
4194 set $kgm_shown = 1
4195 end
4196 if ($kgm_vt == &_ZTV5OSSet)
4197 showsetint _$arg0 $arg1
4198 set $kgm_shown = 1
4199 end
4200 if ($kgm_vt == &_ZTV12OSOrderedSet)
4201 showorderedsetint _$arg0 $arg1
4202 set $kgm_shown = 1
4203 end
4204
4205 if ($kgm_shown != 1)
4206 if ($kgm_show_object_addrs == 0)
4207 printf "`object "
4208 showptr $arg1
4209 printf ", vt "
4210 output /a (unsigned long) $kgm_vt
4211 printf "`"
4212 end
4213 end
4214 end
4215
4216 define showobject
4217 set $kgm_save = $kgm_show_object_addrs
4218 set $kgm_show_object_addrs = 1
4219 set $kgm_show_object_retain = 1
4220 showobjectint _ $arg0
4221 set $kgm_show_object_addrs = $kgm_save
4222 set $kgm_show_object_retain = 0
4223 printf "\n"
4224 end
4225 document showobject
4226 Syntax: (gdb) showobject <object address>
4227 | Show info about an OSObject - its vtable ptr and retain count.
4228 | If the object is a simple container class, more info will be shown.
4229 end
4230
4231 define dictget
4232 set $kgm_dictp = (OSDictionary *)$arg0
4233 set $kgm_keyp = (const OSSymbol *)$arg1
4234 set $kgm_idx = 0
4235 set $kgm_result = 0
4236 while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0))
4237 if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key)
4238 set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value
4239 end
4240 set $kgm_idx = $kgm_idx + 1
4241 end
4242 end
4243
4244
4245 define _registryentryrecurseinit
4246 set $kgm_re = (IOService *)$arg1
4247 set $kgm$arg0_stack = (unsigned long long) $arg2
4248
4249 if ($arg3)
4250 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
4251 else
4252 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
4253 end
4254
4255 dictget $kgm_re->fRegistryTable $kgm_childkey
4256 set $kgm$arg0_child_array = (OSArray *) $kgm_result
4257
4258 if ($kgm$arg0_child_array)
4259 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
4260 else
4261 set $kgm$arg0_child_count = 0
4262 end
4263
4264 if ($kgm$arg0_child_count)
4265 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
4266 else
4267 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
4268 end
4269 end
4270
4271 define findregistryentryrecurse
4272 set $kgm_registry_entry = 0
4273 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
4274
4275 dictget $kgm_re->fRegistryTable $kgm_namekey
4276 if ($kgm_result == 0)
4277 dictget $kgm_re->fRegistryTable gIONameKey
4278 end
4279 if ($kgm_result == 0)
4280 dictget $kgm_re->fPropertyTable gIOClassKey
4281 end
4282
4283 if ($kgm_result != 0)
4284 set $str = ((OSString *) $kgm_result)->string
4285 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
4286 if $kgm_findregistry_verbose
4287 echo .
4288 end
4289
4290 if $kgm_strcmp_result == 0
4291 if $kgm_findregistry_verbose
4292 printf "\n%s:\n | ", ((OSString *) $kgm_result)->string
4293 showobject $kgm_re
4294 printf " | "
4295 print $kgm_re
4296 end
4297
4298 # don't populate $kgm_registry_entry if we want to show everything
4299 if !$kgm_findregistry_continue
4300 set $kgm_registry_entry = $kgm_re
4301 end
4302 end
4303 end
4304
4305 # recurse
4306 if (!$kgm_registry_entry && ($kgm$arg0_child_count != 0))
4307 set $kgm_reg_depth = $kgm_reg_depth + 1
4308 set $kgm$arg0_child_idx = 0
4309
4310 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
4311 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
4312 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
4313 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
4314 loop_break
4315 end
4316 findregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
4317 if $kgm_registry_entry
4318 loop_break
4319 end
4320 end
4321 set $kgm_reg_depth = $kgm_reg_depth - 1
4322 end
4323 end
4324
4325 define findregdictvalue
4326 set $kgm_registry_value = 0
4327 set $kgm_reg_idx = 0
4328 while ($kgm_reg_idx < $arg0->count)
4329 set $kgm_obj = $arg0->dictionary + $kgm_reg_idx
4330 set $str = ((OSString *)$kgm_obj->key)->string
4331 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
4332
4333 if $kgm_strcmp_result == 0
4334 set $kgm_registry_value = $kgm_obj->value
4335 if $kgm_findregistry_verbose
4336 showobject $kgm_registry_value
4337 print $kgm_registry_value
4338 end
4339 loop_break
4340 end
4341 set $kgm_reg_idx = $kgm_reg_idx + 1
4342 end
4343 end
4344
4345 define setfindregistrystr
4346 set $kgm_reg_find_str0 = 0
4347 set $kgm_reg_find_str1 = 0
4348 set $kgm_reg_find_str2 = 0
4349 set $kgm_reg_find_str3 = 0
4350 set $kgm_reg_find_str4 = 0
4351 set $kgm_reg_find_str5 = 0
4352 set $kgm_reg_find_str6 = 0
4353 set $kgm_reg_find_str7 = 0
4354 set $kgm_reg_find_str8 = 0
4355
4356 if $argc > 0
4357 set $kgm_reg_find_str0 = $arg0
4358 end
4359 if $argc > 1
4360 set $kgm_reg_find_str1 = $arg1
4361 end
4362 if $argc > 2
4363 set $kgm_reg_find_str2 = $arg2
4364 end
4365 if $argc > 3
4366 set $kgm_reg_find_str3 = $arg3
4367 end
4368 if $argc > 4
4369 set $kgm_reg_find_str4 = $arg4
4370 end
4371 if $argc > 5
4372 set $kgm_reg_find_str5 = $arg5
4373 end
4374 if $argc > 6
4375 set $kgm_reg_find_str6 = $arg6
4376 end
4377 if $argc > 7
4378 set $kgm_reg_find_str7 = $arg7
4379 end
4380 if $argc > 8
4381 set $kgm_reg_find_str8 = $arg8
4382 end
4383 end
4384
4385 document setfindregistrystr
4386 Syntax: (gdb) setfindregistrystr [a] [b] [c] [d] [e] [f] [g] [h] [i]
4387 | Store an encoded string into up to 9 arguments for use by
4388 | findregistryprop or findregistryentry. The arguments are created
4389 | through calls to strcmp_arg_pack64
4390 end
4391
4392 define _findregistryprop
4393 set $reg = (IOService *) $arg0
4394 set $kgm_props = $reg->fPropertyTable
4395 set $kgm_findregistry_verbose = 0
4396
4397 findregdictvalue $kgm_props
4398 end
4399
4400 define findregistryprop
4401 set $reg = (IOService *) $arg0
4402 set $kgm_props = $reg->fPropertyTable
4403
4404 set $kgm_findregistry_verbose = 1
4405 findregdictvalue $kgm_props
4406 end
4407
4408 document findregistryprop
4409 Syntax: (gdb) findregistryprop <entry>
4410 | Given a registry entry, print out the contents for the property that matches
4411 | the encoded string specified via setfindregistrystr.
4412 |
4413 | For example, the following will print out the "intel-pic" property stored in
4414 | the AppleACPIPlatformExpert registry entry $pe_entry:
4415 | strcmp_arg_pack64 'i' 'n' 't' 'e' 'l' '-' 'p' 'i'
4416 | set $intel_pi = $kgm_strcmp_arg
4417 | strcmp_arg_pack64 'c' 0 0 0 0 0 0 0
4418 | set $c = $kgm_strcmp_arg
4419 | setfindregistrystr $intel_pi $c
4420 | findregistryprop $pe_entry
4421 end
4422
4423 define findregistryentryint
4424 if !$kgm_reg_plane
4425 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
4426 end
4427
4428 if !$kgm_reg_plane
4429 printf "Please load kgmacros after KDP attaching to the target.\n"
4430 else
4431 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
4432 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
4433 if $kgm_findregistry_verbose
4434 printf "Searching"
4435 end
4436 findregistryentryrecurse _ $arg0 0 0
4437 end
4438 end
4439
4440 define _findregistryentry
4441 set $kgm_findregistry_verbose = 0
4442 set $kgm_findregistry_continue = 0
4443 set $kgm_reg_depth = 0
4444
4445 findregistryentryint gRegistryRoot
4446 end
4447
4448 define findregistryentry
4449 set $kgm_findregistry_verbose = 1
4450 set $kgm_findregistry_continue = 0
4451 set $kgm_reg_depth = 0
4452
4453 findregistryentryint gRegistryRoot
4454 end
4455
4456 define findregistryentries
4457 set $kgm_findregistry_verbose = 1
4458 set $kgm_findregistry_continue = 1
4459 set $kgm_reg_depth = 0
4460
4461 findregistryentryint gRegistryRoot
4462 end
4463
4464 document findregistryentry
4465 Syntax: (gdb) findregistryentry
4466 | Search for a registry entry that matches the encoded string specified through
4467 | setfindregistrystr. You can alter the search depth through use of
4468 | $kgm_reg_depth_max.
4469 |
4470 | For example, the following will pull out the AppleACPIPlatformExpert registry
4471 | entry:
4472 | strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
4473 | set $AppleACP = $kgm_strcmp_arg
4474 | strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
4475 | set $IPlatfor = $kgm_strcmp_arg
4476 | strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
4477 | set $mExpert = $kgm_strcmp_arg
4478 | setfindregistrystr $AppleACP $IPlatfor $mExpert
4479 | findregistryentry
4480 end
4481
4482 document findregistryentries
4483 Syntax: (gdb) findregistryentries
4484 | Search for all registry entries that match the encoded string specified through
4485 | setfindregistrystr. You can alter the search depth through use of
4486 | $kgm_reg_depth_max. See findregistryentry for an example of how to encode a string.
4487 end
4488
4489
4490 define showregistryentryrecurse
4491 _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
4492
4493 indent $kgm_reg_depth $kgm$arg0_stack
4494 printf "+-o "
4495
4496 dictget $kgm_re->fRegistryTable $kgm_namekey
4497 if ($kgm_result == 0)
4498 dictget $kgm_re->fRegistryTable gIONameKey
4499 end
4500 if ($kgm_result == 0)
4501 dictget $kgm_re->fPropertyTable gIOClassKey
4502 end
4503
4504 if ($kgm_result != 0)
4505 printf "%s", ((OSString *)$kgm_result)->string
4506 else
4507 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
4508 printf "%s", ((IOService*)$kgm_re)->pwrMgt->Name
4509 else
4510 # printf ", guessclass "
4511 # guessclass $kgm_re
4512 printf "??"
4513 end
4514 end
4515
4516
4517 printf " <object "
4518 showptr $kgm_re
4519 printf ", id 0x%llx, ", $kgm_re->IORegistryEntry::reserved->fRegistryEntryID
4520 printf "vtable "
4521 set $kgm_vt = (unsigned long) *(void**) $kgm_re
4522 if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
4523 set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
4524 end
4525 output /a $kgm_vt
4526
4527 if ($kgm_vt != &_ZTV15IORegistryEntry)
4528 printf ", "
4529 set $kgm_state = $kgm_re->__state[0]
4530 # kIOServiceRegisteredState
4531 if (0 == ($kgm_state & 2))
4532 printf "!"
4533 end
4534 printf "registered, "
4535 # kIOServiceMatchedState
4536 if (0 == ($kgm_state & 4))
4537 printf "!"
4538 end
4539 printf "matched, "
4540 # kIOServiceInactiveState
4541 if ($kgm_state & 1)
4542 printf "in"
4543 end
4544 printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount)
4545 end
4546 printf ">\n"
4547
4548 if ($kgm_show_props)
4549 set $kgm_props = $kgm_re->fPropertyTable
4550 showregdictionary $kgm_props $kgm$arg0_stack
4551 end
4552
4553 # recurse
4554 if ($kgm$arg0_child_count != 0)
4555
4556 set $kgm_reg_depth = $kgm_reg_depth + 1
4557 set $kgm$arg0_child_idx = 0
4558
4559 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
4560 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
4561 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
4562 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
4563 loop_break
4564 end
4565 showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
4566 end
4567
4568 set $kgm_reg_depth = $kgm_reg_depth - 1
4569 end
4570 end
4571
4572 define showregistryentryint
4573 if !$kgm_reg_plane
4574 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
4575 end
4576
4577 if !$kgm_reg_plane
4578 printf "Please load kgmacros after KDP attaching to the target.\n"
4579 else
4580 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
4581 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
4582 showregistryentryrecurse _ $arg0 0 0
4583 end
4584 end
4585
4586 define showregistry
4587 set $kgm_reg_depth = 0
4588 set $kgm_show_props = 0
4589 showregistryentryint gRegistryRoot
4590 end
4591 document showregistry
4592 Syntax: (gdb) showregistry
4593 | Show info about all registry entries in the current plane. You can specify the maximum
4594 | display depth with $kgm_reg_depth_max.
4595 end
4596
4597 define showregistryprops
4598 set $kgm_reg_depth = 0
4599 set $kgm_show_props = 1
4600 showregistryentryint gRegistryRoot
4601 end
4602 document showregistryprops
4603 Syntax: (gdb) showregistryprops
4604 | Show info about all registry entries in the current plane, and their properties.
4605 | set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display
4606 | more verbose information
4607 end
4608
4609 define showregistryentry
4610 set $kgm_reg_depth = 0
4611 set $kgm_show_props = 1
4612 showregistryentryint $arg0
4613 end
4614 document showregistryentry
4615 Syntax: (gdb) showregistryentry <object address>
4616 | Show info about a registry entry; its properties and descendants in the current plane.
4617 end
4618
4619 define setregistryplane
4620 if ($arg0 != 0)
4621 set $kgm_reg_plane = (IORegistryPlane *) $arg0
4622 else
4623 showobjectint _ gIORegistryPlanes
4624 printf "\n"
4625 end
4626 end
4627 document setregistryplane
4628 Syntax: (gdb) setregistryplane <plane object address>
4629 | Set the plane to be used for the iokit registry macros. An argument of zero will
4630 | display known planes.
4631 end
4632
4633 define guessclass
4634 set $kgm_classidx = 0
4635 set $kgm_lookvt = *((void **) $arg0)
4636 set $kgm_bestvt = (void *) 0
4637 set $kgm_bestidx = 0
4638
4639 while $kgm_classidx < sAllClassesDict->count
4640 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value
4641
4642 set $kgm_vt = *((void **) $kgm_meta)
4643
4644 if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt))
4645 set $kgm_bestvt = $kgm_vt
4646 set $kgm_bestidx = $kgm_classidx
4647 end
4648 set $kgm_classidx = $kgm_classidx + 1
4649 end
4650 printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string
4651 end
4652
4653 define showallclasses
4654 set $kgm_classidx = 0
4655 while $kgm_classidx < sAllClassesDict->count
4656 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value
4657 showmetaclass $kgm_meta
4658 end
4659 end
4660
4661 document showallclasses
4662 Syntax: (gdb) showallclasses
4663 | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
4664 end
4665
4666 define showioalloc
4667 printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024
4668 printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024
4669 printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024
4670 printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024
4671 end
4672
4673 document showioalloc
4674 Syntax: (gdb) showioalloc
4675 | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
4676 end
4677
4678 define showosobjecttracking
4679 set $kgm_next = (OSObjectTracking *) gOSObjectTrackList.next
4680 while $kgm_next != &gOSObjectTrackList
4681 set $obj = (OSObject *) ($kgm_next+1)
4682 showobject $obj
4683 set $kgm_idx = 0
4684 while $kgm_idx < (sizeof($kgm_next->bt) / sizeof($kgm_next->bt[0]))
4685 if ((unsigned long) $kgm_next->bt[$kgm_idx] > (unsigned long) &last_kernel_symbol)
4686 showkmodaddr $kgm_next->bt[$kgm_idx]
4687 printf "\n"
4688 else
4689 if ((unsigned long) $kgm_next->bt[$kgm_idx] > 0)
4690 output /a $kgm_next->bt[$kgm_idx]
4691 printf "\n"
4692 end
4693 end
4694 set $kgm_idx = $kgm_idx + 1
4695 end
4696 printf "\n"
4697 set $kgm_next = (OSObjectTracking *) $kgm_next->link.next
4698 end
4699 end
4700
4701 document showosobjecttracking
4702 Syntax: (gdb) showosobjecttracking
4703 | Show the list of tracked OSObject allocations with backtraces.
4704 | Boot with the kOSTraceObjectAlloc (0x00400000) io debug flag set.
4705 | Set gOSObjectTrackThread to 1 or a thread_t to capture new OSObjects allocated by a thread or all threads.
4706 end
4707
4708 # $kgm_readphys_force_kdp and $kgm_readphys_force_physmap
4709 # can respectively cause physical memory access to use
4710 # a KDP manual packet or the physical memory mapping
4711 # even if the default behavior would be otherwise.
4712 define readphysint
4713 set $kgm_readphysint_result = 0xBAD10AD
4714
4715 if ($kgm_readphys_force_kdp != 0)
4716 set $kgm_readphys_use_kdp = 1
4717 else
4718 if ($kgm_readphys_force_physmap)
4719 set $kgm_readphys_use_kdp = 0
4720 else
4721 set $kgm_readphys_use_kdp = ( kdp->is_conn > 0 )
4722 end
4723 end
4724
4725 if ($kgm_readphys_use_kdp)
4726
4727 # set up the manual KDP packet
4728 set manual_pkt.input = 0
4729 set manual_pkt.len = sizeof(kdp_readphysmem64_req_t)
4730 set $kgm_pkt = (kdp_readphysmem64_req_t *)&manual_pkt.data
4731 set $kgm_pkt->hdr.request = KDP_READPHYSMEM64
4732 set $kgm_pkt->hdr.len = sizeof(kdp_readphysmem64_req_t)
4733 set $kgm_pkt->hdr.is_reply = 0
4734 set $kgm_pkt->hdr.seq = 0
4735 set $kgm_pkt->hdr.key = 0
4736 set $kgm_pkt->address = (uint64_t)$arg0
4737 set $kgm_pkt->nbytes = $arg1 >> 3
4738 set $kgm_pkt->lcpu = $arg2
4739 set manual_pkt.input = 1
4740 # dummy to make sure manual packet is executed
4741 set $kgm_dummy = &_mh_execute_header
4742 set $kgm_pkt = (kdp_readphysmem64_reply_t *)&manual_pkt.data
4743 if ($kgm_pkt->error == 0)
4744 if $arg1 == 8
4745 set $kgm_readphysint_result = *((uint8_t *)$kgm_pkt->data)
4746 end
4747 if $arg1 == 16
4748 set $kgm_readphysint_result = *((uint16_t *)$kgm_pkt->data)
4749 end
4750 if $arg1 == 32
4751 set $kgm_readphysint_result = *((uint32_t *)$kgm_pkt->data)
4752 end
4753 if $arg1 == 64
4754 set $kgm_readphysint_result = *((uint64_t *)$kgm_pkt->data)
4755 end
4756 end
4757
4758 else
4759 # No KDP. Attempt to use physical memory mapping
4760
4761 if ($kgm_mtype == $kgm_mtype_x86_64)
4762 set $kgm_readphys_paddr_in_kva = (unsigned long long)$arg0 + (((unsigned long long)-1 << 47) | ((unsigned long long)509 << 39))
4763 else
4764 if ($kgm_mtype == $kgm_mtype_arm)
4765 set $kgm_readphys_paddr_in_kva = (unsigned long long)$arg0 - gPhysBase + gVirtBase
4766 else
4767 printf "readphys not available for current architecture.\n"
4768 set $kgm_readphys_paddr_in_kva = 0
4769 end
4770 end
4771 if $kgm_readphys_paddr_in_kva
4772 if $arg1 == 8
4773 set $kgm_readphysint_result = *((uint8_t *)$kgm_readphys_paddr_in_kva)
4774 end
4775 if $arg1 == 16
4776 set $kgm_readphysint_result = *((uint16_t *)$kgm_readphys_paddr_in_kva)
4777 end
4778 if $arg1 == 32
4779 set $kgm_readphysint_result = *((uint32_t *)$kgm_readphys_paddr_in_kva)
4780 end
4781 if $arg1 == 64
4782 set $kgm_readphysint_result = *((uint64_t *)$kgm_readphys_paddr_in_kva)
4783 end
4784 end
4785 end
4786 end
4787
4788 define readphys8
4789 readphysint $arg0 8 $kgm_lcpu_self
4790 output /a $arg0
4791 printf ":\t0x%02hhx\n", $kgm_readphysint_result
4792 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
4793 end
4794
4795 define readphys16
4796 readphysint $arg0 16 $kgm_lcpu_self
4797 output /a $arg0
4798 printf ":\t0x%04hx\n", $kgm_readphysint_result
4799 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
4800 end
4801
4802 define readphys32
4803 readphysint $arg0 32 $kgm_lcpu_self
4804 output /a $arg0
4805 printf ":\t0x%08x\n", $kgm_readphysint_result
4806 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
4807 end
4808
4809 define readphys64
4810 readphysint $arg0 64 $kgm_lcpu_self
4811 output /a $arg0
4812 printf ":\t0x%016llx\n", $kgm_readphysint_result
4813 set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
4814 end
4815
4816 define readphys
4817 readphys32 $arg0
4818 end
4819
4820 document readphys8
4821 | See readphys64
4822 end
4823
4824 document readphys16
4825 | See readphys64
4826 end
4827
4828 document readphys32
4829 | See readphys64
4830 end
4831
4832 document readphys64
4833 | The argument is interpreted as a physical address, and the 64-bit word
4834 | addressed is displayed. Saves 64-bit result in $kgm_readphys_result.
4835 end
4836
4837 define writephysint
4838 # set up the manual KDP packet
4839 set manual_pkt.input = 0
4840 set manual_pkt.len = sizeof(kdp_writephysmem64_req_t)
4841 set $kgm_pkt = (kdp_writephysmem64_req_t *)&manual_pkt.data
4842 set $kgm_pkt->hdr.request = KDP_WRITEPHYSMEM64
4843 set $kgm_pkt->hdr.len = sizeof(kdp_writephysmem64_req_t)
4844 set $kgm_pkt->hdr.is_reply = 0
4845 set $kgm_pkt->hdr.seq = 0
4846 set $kgm_pkt->hdr.key = 0
4847 set $kgm_pkt->address = (uint64_t)$arg0
4848 set $kgm_pkt->nbytes = $arg1 >> 3
4849 set $kgm_pkt->lcpu = $arg3
4850 if $arg1 == 8
4851 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
4852 end
4853 if $arg1 == 16
4854 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
4855 end
4856 if $arg1 == 32
4857 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
4858 end
4859 if $arg1 == 64
4860 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg2
4861 end
4862 set manual_pkt.input = 1
4863 # dummy to make sure manual packet is executed
4864 set $kgm_dummy = &_mh_execute_header
4865 set $kgm_pkt = (kdp_writephysmem64_reply_t *)&manual_pkt.data
4866 set $kgm_writephysint_result = $kgm_pkt->error
4867 end
4868
4869 define writephys8
4870 writephysint $arg0 8 $arg1 $kgm_lcpu_self
4871 end
4872
4873 define writephys16
4874 writephysint $arg0 16 $arg1 $kgm_lcpu_self
4875 end
4876
4877 define writephys32
4878 writephysint $arg0 32 $arg1 $kgm_lcpu_self
4879 end
4880
4881 define writephys64
4882 writephysint $arg0 64 $arg1 $kgm_lcpu_self
4883 end
4884
4885 document writephys8
4886 | See writephys64
4887 end
4888
4889 document writephys16
4890 | See writephys64
4891 end
4892
4893 document writephys32
4894 | See writephys64
4895 end
4896
4897 document writephys64
4898 | The argument is interpreted as a physical address, and the second argument is
4899 | written to that address as a 64-bit word.
4900 end
4901
4902 define addkextsyms
4903 shell echo cd `pwd` > /tmp/gdb-cd
4904 cd $arg0
4905 source kcbmacros
4906 source /tmp/gdb-cd
4907 set $kgm_show_kmod_syms = 1
4908 end
4909
4910 document addkextsyms
4911 | Takes a directory of symbols for kexts generated with kextcache -y and loads them
4912 | into gdb.
4913 | (gdb) addkextsyms /path/to/symboldir
4914 end
4915
4916 define showprocfiles
4917 if ($argc == 1)
4918 _showprocheader
4919 _showprocfiles $arg0
4920 else
4921 printf "| Usage:\n|\n"
4922 help showprocfiles
4923 end
4924 end
4925 document showprocfiles
4926 Syntax: (gdb) showprocfiles <proc_t>
4927 | Given a proc_t pointer, display the list of open file descriptors for the
4928 | referenced process.
4929 end
4930
4931 define _showprocheader
4932 printf "fd fileglob "
4933 showptrhdrpad
4934 printf " fg flags fg type fg data "
4935 showptrhdrpad
4936 printf " info\n"
4937 printf "----- ----------"
4938 if $kgm_lp64
4939 printf "--------"
4940 end
4941 printf " ---------- -------- ----------"
4942 if $kgm_lp64
4943 printf "--------"
4944 end
4945 printf " -------------------\n"
4946 end
4947
4948 define _showprocfiles
4949 set $kgm_spf_filedesc = ((proc_t)$arg0)->p_fd
4950 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
4951 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
4952 set $kgm_spf_count = 0
4953 while ($kgm_spf_count <= $kgm_spf_last)
4954 if ($kgm_spf_ofiles[$kgm_spf_count] == 0)
4955 # DEBUG: For files that were open, but are now closed
4956 # printf "%-5d FILEPROC_NULL\n", $kgm_spf_count
4957 else
4958 # display fd #, fileglob address, fileglob flags
4959 set $kgm_spf_flags = $kgm_spf_ofiles[$kgm_spf_count].f_flags
4960 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
4961 printf "%-5d ", $kgm_spf_count
4962 showptr $kgm_spf_fg
4963 printf " 0x%08x ", $kgm_spf_flags
4964 # decode fileglob type
4965 set $kgm_spf_fgt = $kgm_spf_fg->fg_type
4966 if ($kgm_spf_fgt == 1)
4967 printf "VNODE "
4968 end
4969 if ($kgm_spf_fgt == 2)
4970 printf "SOCKET "
4971 end
4972 if ($kgm_spf_fgt == 3)
4973 printf "PSXSHM "
4974 end
4975 if ($kgm_spf_fgt == 4)
4976 printf "PSXSEM "
4977 end
4978 if ($kgm_spf_fgt == 5)
4979 printf "KQUEUE "
4980 end
4981 if ($kgm_spf_fgt == 6)
4982 printf "PIPE "
4983 end
4984 if ($kgm_spf_fgt == 7)
4985 printf "FSEVENTS"
4986 end
4987 if ($kgm_spf_fgt < 1 || $kgm_spf_fgt > 7)
4988 printf "?: %-5d", $kgm_spf_fgt
4989 end
4990
4991 # display fileglob data address and decode interesting fact(s)
4992 # about data, if we know any
4993 set $kgm_spf_fgd = $kgm_spf_fg->fg_data
4994 printf " "
4995 showptr $kgm_spf_fgd
4996 printf " "
4997 if ($kgm_spf_fgt == 1)
4998 set $kgm_spf_name = ((struct vnode *)$kgm_spf_fgd)->v_name
4999 if ($kgm_spf_name == 0)
5000 printf "(null)"
5001 else
5002 printf "%s", $kgm_spf_name
5003 end
5004 end
5005 printf "\n"
5006 end
5007 set $kgm_spf_count = $kgm_spf_count + 1
5008 end
5009 end
5010
5011 #
5012 # Show all the advisory file locks held by a process for each of the vnode
5013 # type files that it has open; do this by walking the per process open file
5014 # table and looking at any vnode type fileglob that has a non-NULL lock list
5015 # associated with it.
5016 #
5017 define showproclocks
5018 if ($argc == 1)
5019 _showproclocks $arg0
5020 else
5021 printf "| Usage:\n|\n"
5022 help showproclocks
5023 end
5024 end
5025 document showproclocks
5026 Syntax: (gdb) showproclocks <proc_t>
5027 | Given a proc_t pointer, display the list of advisory file locks held by the
5028 | referenced process.
5029 end
5030
5031 define _showproclocks
5032 set $kgm_spl_filedesc = ((proc_t)$arg0)->p_fd
5033 set $kgm_spl_last = $kgm_spl_filedesc->fd_lastfile
5034 set $kgm_spl_ofiles = $kgm_spl_filedesc->fd_ofiles
5035 set $kgm_spl_count = 0
5036 set $kgm_spl_seen = 0
5037 while ($kgm_spl_count <= $kgm_spl_last)
5038 if ($kgm_spl_ofiles[$kgm_spl_count] == 0)
5039 # DEBUG: For files that were open, but are now closed
5040 # printf "%-5d FILEPROC_NULL\n", $kgm_spl_count
5041 else
5042 set $kgm_spl_fg = $kgm_spl_ofiles[$kgm_spl_count].f_fglob
5043 # decode fileglob type
5044 set $kgm_spl_fgt = $kgm_spl_fg->fg_type
5045 if ($kgm_spl_fgt == 1)
5046 set $kgm_spl_fgd = $kgm_spl_fg->fg_data
5047 set $kgm_spl_name = ((struct vnode *)$kgm_spl_fgd)->v_name
5048 set $kgm_spl_vnode = ((vnode_t)$kgm_spl_fgd)
5049 set $kgm_spl_lockiter = $kgm_spl_vnode->v_lockf
5050 if ($kgm_spl_lockiter != 0)
5051 if ($kgm_spl_seen == 0)
5052 _showvnodelockheader
5053 end
5054 set $kgm_spl_seen = $kgm_spl_seen + 1
5055 printf "( fd %d, name ", $kgm_spl_count
5056 if ($kgm_spl_name == 0)
5057 printf "(null) )"
5058 else
5059 printf "%s )\n", $kgm_spl_name
5060 end
5061 _showvnodelocks $kgm_spl_fgd
5062 end
5063 end
5064 end
5065 set $kgm_spl_count = $kgm_spf_count + 1
5066 end
5067 printf "%d total locks for ", $kgm_spl_seen
5068 showptr $arg0
5069 printf "\n"
5070 end
5071
5072 define showprocinfo
5073 set $kgm_spi_proc = (proc_t)$arg0
5074 printf "Process "
5075 showptr $kgm_spi_proc
5076 printf "\n"
5077 printf " name %s\n", $kgm_spi_proc->p_comm
5078 printf " pid:%.8d", $kgm_spi_proc->p_pid
5079 printf " task:"
5080 showptr $kgm_spi_proc->task
5081 printf " p_stat:%.1d", $kgm_spi_proc->p_stat
5082 printf " parent pid:%.8d", $kgm_spi_proc->p_ppid
5083 printf "\n"
5084 # decode part of credential
5085 set $kgm_spi_cred = $kgm_spi_proc->p_ucred
5086 if ($kgm_spi_cred != 0)
5087 printf "Cred: euid %d ruid %d svuid %d\n", $kgm_spi_cred->cr_posix.cr_uid, $kgm_spi_cred->cr_posix.cr_ruid, $kgm_spi_cred->cr_posix.cr_svuid
5088 else
5089 printf "Cred: (null)\n"
5090 end
5091 # decode flags
5092 set $kgm_spi_flag = $kgm_spi_proc->p_flag
5093 printf "Flags: 0x%08x\n", $kgm_spi_flag
5094 if ($kgm_spi_flag & 0x00000001)
5095 printf " 0x00000001 - may hold advisory locks\n"
5096 end
5097 if ($kgm_spi_flag & 0x00000002)
5098 printf " 0x00000002 - has a controlling tty\n"
5099 end
5100 if ($kgm_spi_flag & 0x00000004)
5101 printf " 0x00000004 - process is 64 bit\n"
5102 else
5103 printf " !0x00000004 - process is 32 bit\n"
5104 end
5105 if ($kgm_spi_flag & 0x00000008)
5106 printf " 0x00000008 - no SIGCHLD on child stop\n"
5107 end
5108 if ($kgm_spi_flag & 0x00000010)
5109 printf " 0x00000010 - waiting for child exec/exit\n"
5110 end
5111 if ($kgm_spi_flag & 0x00000020)
5112 printf " 0x00000020 - has started profiling\n"
5113 end
5114 if ($kgm_spi_flag & 0x00000040)
5115 printf " 0x00000040 - in select; wakeup/waiting danger\n"
5116 end
5117 if ($kgm_spi_flag & 0x00000080)
5118 printf " 0x00000080 - was stopped and continued\n"
5119 end
5120 if ($kgm_spi_flag & 0x00000100)
5121 printf " 0x00000100 - has set privileges since exec\n"
5122 end
5123 if ($kgm_spi_flag & 0x00000200)
5124 printf " 0x00000200 - system process: no signals, stats, or swap\n"
5125 end
5126 if ($kgm_spi_flag & 0x00000400)
5127 printf " 0x00000400 - timing out during a sleep\n"
5128 end
5129 if ($kgm_spi_flag & 0x00000800)
5130 printf " 0x00000800 - debugged process being traced\n"
5131 end
5132 if ($kgm_spi_flag & 0x00001000)
5133 printf " 0x00001000 - debugging process has waited for child\n"
5134 end
5135 if ($kgm_spi_flag & 0x00002000)
5136 printf " 0x00002000 - exit in progress\n"
5137 end
5138 if ($kgm_spi_flag & 0x00004000)
5139 printf " 0x00004000 - process has called exec\n"
5140 end
5141 if ($kgm_spi_flag & 0x00008000)
5142 printf " 0x00008000 - owe process an addupc() XXX\n"
5143 end
5144 if ($kgm_spi_flag & 0x00010000)
5145 printf " 0x00010000 - affinity for Rosetta children\n"
5146 end
5147 if ($kgm_spi_flag & 0x00020000)
5148 printf " 0x00020000 - wants to run Rosetta\n"
5149 end
5150 if ($kgm_spi_flag & 0x00040000)
5151 printf " 0x00040000 - has wait() in progress\n"
5152 end
5153 if ($kgm_spi_flag & 0x00080000)
5154 printf " 0x00080000 - kdebug tracing on for this process\n"
5155 end
5156 if ($kgm_spi_flag & 0x00100000)
5157 printf " 0x00100000 - blocked due to SIGTTOU or SIGTTIN\n"
5158 end
5159 if ($kgm_spi_flag & 0x00200000)
5160 printf " 0x00200000 - has called reboot()\n"
5161 end
5162 if ($kgm_spi_flag & 0x00400000)
5163 printf " 0x00400000 - is TBE state\n"
5164 end
5165 if ($kgm_spi_flag & 0x00800000)
5166 printf " 0x00800000 - signal exceptions\n"
5167 end
5168 if ($kgm_spi_flag & 0x01000000)
5169 printf " 0x01000000 - has thread cwd\n"
5170 end
5171 if ($kgm_spi_flag & 0x02000000)
5172 printf " 0x02000000 - has vfork() children\n"
5173 end
5174 if ($kgm_spi_flag & 0x04000000)
5175 printf " 0x04000000 - not allowed to attach\n"
5176 end
5177 if ($kgm_spi_flag & 0x08000000)
5178 printf " 0x08000000 - vfork() in progress\n"
5179 end
5180 if ($kgm_spi_flag & 0x10000000)
5181 printf " 0x10000000 - no shared libraries\n"
5182 end
5183 if ($kgm_spi_flag & 0x20000000)
5184 printf " 0x20000000 - force quota for root\n"
5185 end
5186 if ($kgm_spi_flag & 0x40000000)
5187 printf " 0x40000000 - no zombies when children exit\n"
5188 end
5189 if ($kgm_spi_flag & 0x80000000)
5190 printf " 0x80000000 - don't hang on remote FS ops\n"
5191 end
5192 # decode state
5193 set $kgm_spi_state = $kgm_spi_proc->p_stat
5194 printf "State: "
5195 if ($kgm_spi_state == 1)
5196 printf "Idle\n"
5197 end
5198 if ($kgm_spi_state == 2)
5199 printf "Run\n"
5200 end
5201 if ($kgm_spi_state == 3)
5202 printf "Sleep\n"
5203 end
5204 if ($kgm_spi_state == 4)
5205 printf "Stop\n"
5206 end
5207 if ($kgm_spi_state == 5)
5208 printf "Zombie\n"
5209 end
5210 if ($kgm_spi_state == 6)
5211 printf "Reaping\n"
5212 end
5213 if ($kgm_spi_state < 1 || $kgm_spi_state > 6)
5214 printf "(Unknown)\n"
5215 end
5216 end
5217
5218 document showprocinfo
5219 Syntax: (gdb) showprocinfo <proc_t>
5220 | Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
5221 end
5222
5223 #
5224 # dump the zombprocs
5225 #
5226 define zombproc
5227 set $basep = (struct proc *)zombproc->lh_first
5228 set $pp = $basep
5229 while $pp
5230 showprocinfo $pp
5231 set $pp = $pp->p_list.le_next
5232 end
5233 end
5234
5235 document zombproc
5236 Syntax: (gdb) zombproc
5237 | Routine to print out all procs in the zombie list
5238 end
5239
5240 #
5241 # dump the zombstacks
5242 #
5243 define zombstacks
5244 set $basep = (struct proc *)zombproc->lh_first
5245 set $pp = $basep
5246 while $pp
5247 if $pp->p_stat != 5
5248 showtaskstacks $pp->task
5249 end
5250 set $pp = $pp->p_list.le_next
5251 end
5252 end
5253
5254 document zombstacks
5255 Syntax: (gdb) zombstacks
5256 | Routine to print out all stacks of tasks that are exiting
5257 end
5258
5259
5260 #
5261 # dump the allprocs
5262 #
5263 define allproc
5264 set $basep = (struct proc *)allproc->lh_first
5265 set $pp = $basep
5266 while $pp
5267 showprocinfo $pp
5268 set $pp = $pp->p_list.le_next
5269 end
5270 end
5271
5272 document allproc
5273 Syntax: (gdb) allproc
5274 | Routine to print out all process in the system
5275 | which are not in the zombie list
5276 end
5277 define showprocsiblingint
5278 set $kgm_sibling_ptr = (struct proc *)$arg0
5279 set $kgm_lx = $arg1
5280 while $kgm_lx
5281 printf "| "
5282 set $kgm_lx = $kgm_lx-3
5283 end
5284 printf "|--%d %s [ 0x%llx ]\n", $kgm_sibling_ptr->p_pid, $kgm_sibling_ptr->p_comm, $kgm_sibling_ptr
5285 end
5286 define showproctreeint
5287 #Initialize all the set variables used in this macro
5288 set $kgm_basep1 = 0
5289 set $kgm_sibling_ptr = 0
5290 set $kgm_lx = 0
5291 set $kgm_tmp_base = 0
5292 set $kgm_head_ptr = 0
5293 set $kgm_search_pid = 0
5294 set $kgm_rev = 0
5295 set $kgm_x = 0
5296
5297 set $kgm_basep1 = (struct proc *)allproc->lh_first
5298 if ($arg0 == 0)
5299 set $kgm_head_ptr = (struct proc *)initproc
5300 end
5301 if ($arg0 > 0)
5302 set $kgm_tmp_base = (struct proc *)allproc->lh_first
5303 set $kgm_search_pid = $arg0
5304 while $kgm_tmp_base
5305 if ( $kgm_tmp_base->p_pid == $kgm_search_pid)
5306 if ($kgm_tmp_base->p_childrencnt > 0)
5307 set $kgm_head_ptr = $kgm_tmp_base->p_children.lh_first
5308 else
5309 set $kgm_head_ptr = 0
5310 printf "No children present for PID=%d", $kgm_search_pid
5311 end
5312 loop_break
5313 end
5314 set $kgm_tmp_base = $kgm_tmp_base->p_list.le_next
5315 end
5316 end
5317 set $kgm_rev = 0
5318 set $kgm_x = 0
5319 if ($kgm_head_ptr)
5320 printf "PID PROCESS POINTER]\n"
5321 printf "=== ======= =======\n"
5322 printf "%d %s [ 0x%llx ]\n", $kgm_head_ptr->p_ppid, $kgm_head_ptr->p_pptr->p_comm, $kgm_head_ptr
5323 printf "|--%d %s [ 0x%llx ]\n", $kgm_head_ptr->p_pid, $kgm_head_ptr->p_comm, $kgm_head_ptr
5324 end
5325 while ($kgm_head_ptr)
5326 #Is childrencnt = 0? YES {=> no children}
5327 if ($kgm_head_ptr->p_childrencnt == 0)
5328 # Does it have sibling?
5329 if($kgm_head_ptr->p_sibling.le_next == 0)
5330 #No, it does not have sibling, so go back to its parent which will go to its sibling
5331 if($kgm_head_ptr == $kgm_head_ptr->p_pptr)
5332 loop_break
5333 end
5334 set $kgm_head_ptr = $kgm_head_ptr->p_pptr
5335 if ($kgm_head_ptr == $kgm_tmp_base)
5336 loop_break
5337 end
5338 if ($kgm_x > 3)
5339 set $kgm_x = $kgm_x - 3
5340 end
5341 set $kgm_rev = 1
5342 end
5343 if($kgm_head_ptr->p_sibling.le_next != 0)
5344 # Yes, it has sibling. So print sibling
5345 set $kgm_rev = 0
5346 showprocsiblingint $kgm_head_ptr->p_sibling.le_next $kgm_x
5347 set $kgm_head_ptr = $kgm_head_ptr->p_sibling.le_next
5348 end
5349 # childrencnt != 0 {=> it has children}
5350 else
5351 if ($kgm_rev == 1)
5352 if($kgm_head_ptr->p_sibling.le_next == 0)
5353 #No, it does not have sibling, so go back to its parent which will go to its sibling
5354 if($kgm_head_ptr == $kgm_head_ptr->p_pptr)
5355 loop_break
5356 end
5357 set $kgm_head_ptr = $kgm_head_ptr->p_pptr
5358 if ($kgm_head_ptr == $kgm_tmp_base)
5359 loop_break
5360 end
5361
5362 if ($kgm_x > 3)
5363 set $kgm_x = $kgm_x - 3
5364 end
5365 set $kgm_rev = 1
5366 end
5367 if($kgm_head_ptr->p_sibling.le_next != 0)
5368 set $kgm_rev = 0
5369 # Yes, it has sibling. So print sibling
5370 showprocsiblingint $kgm_head_ptr->p_sibling.le_next $kgm_x
5371 set $kgm_head_ptr = $kgm_head_ptr->p_sibling.le_next
5372 end
5373 else
5374 set $kgm_head_ptr = $kgm_head_ptr->p_children.lh_first
5375 set $kgm_x = $kgm_x + 3
5376 set $kgm_lx = $kgm_x
5377 while $kgm_lx
5378 printf "| "
5379 set $kgm_lx = $kgm_lx-3
5380 end
5381 printf "|--%d %s [ 0x%llx ] \n", $kgm_head_ptr->p_pid, $kgm_head_ptr->p_comm, $kgm_head_ptr
5382 end
5383 end
5384 end
5385 printf "\n"
5386 #Unset all the set variables used in this macro
5387 set $kgm_basep1 = 0
5388 set $kgm_sibling_ptr = 0
5389 set $kgm_lx = 0
5390 set $kgm_tmp_base = 0
5391 set $kgm_head_ptr = 0
5392 set $kgm_search_pid = 0
5393 set $kgm_rev = 0
5394 set $kgm_x = 0
5395 end
5396 define showproctree
5397 if ($argc > 0)
5398 showproctreeint $arg0
5399 else
5400 showproctreeint 0
5401 end
5402 end
5403 document showproctree
5404 Syntax: (gdb) showproctree <pid>
5405 | Routine to print the processes in the system in a hierarchical tree form. This routine does not print zombie processes.
5406 | If no argument is given, showproctree will print all the processes in the system.
5407 | If pid is specified, showproctree prints all the descendants of the indicated process
5408 end
5409
5410
5411 define print_vnode
5412 set $vp = (struct vnode *)$arg0
5413 printf " "
5414 printf " vp "
5415 showptr $vp
5416 printf " use %d", $vp->v_usecount
5417 printf " io %d", $vp->v_iocount
5418 printf " kuse %d", $vp->v_kusecount
5419 printf " type %d", $vp->v_type
5420 printf " flg 0x%.8x", $vp->v_flag
5421 printf " lflg 0x%.8x", $vp->v_lflag
5422 printf " par "
5423 showptr $vp->v_parent
5424 set $_name = (char *)$vp->v_name
5425 if ($_name != 0)
5426 printf " %s", $_name
5427 end
5428 if ($vp->v_type == VREG) && ($vp->v_un.vu_ubcinfo != 0)
5429 printf " mapped %d", ($vp->v_un.vu_ubcinfo.ui_flags & 0x08) ? 1 : 0
5430 end
5431 printf "\n"
5432 end
5433
5434 document print_vnode
5435 Syntax: (gdb) print_vnode <vnode>
5436 | Prints out the fields of a vnode struct
5437 end
5438
5439 define showprocvnodes
5440 set $pp = (struct proc *)$arg0
5441 set $fdp = (struct filedesc *)$pp->p_fd
5442 set $cvp = $fdp->fd_cdir
5443 set $rvp = $fdp->fd_rdir
5444 if $cvp
5445 printf "Current Working Directory \n"
5446 print_vnode $cvp
5447 printf "\n"
5448 end
5449 if $rvp
5450 printf "Current Root Directory \n"
5451 print_vnode $rvp
5452 printf "\n"
5453 end
5454 set $count = 0
5455 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
5456 set $fpo = (char)($fdp->fd_ofileflags[0])
5457 while $count < $fdp->fd_nfiles
5458 #printf"fpp %x ", *$fpp
5459 if *$fpp
5460 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
5461 if $fg && (($fg)->fg_type == 1)
5462 if $fdp->fd_ofileflags[$count] & 4
5463 printf "U: "
5464 else
5465 printf " "
5466 end
5467 printf "fd = %d ", $count
5468 print_vnode $fg->fg_data
5469 end
5470 end
5471 set $fpp = $fpp + 1
5472 set $count = $count + 1
5473 end
5474 end
5475
5476 document showprocvnodes
5477 Syntax: (gdb) showprocvnodes <proc_address>
5478 | Routine to print out all the open fds
5479 | which are vnodes in a process
5480 end
5481
5482 define showallprocvnodes
5483 set $basep = (struct proc *)allproc->lh_first
5484 set $pp = $basep
5485 while $pp
5486 printf "============================================ \n"
5487 showprocinfo $pp
5488 showprocvnodes $pp
5489 set $pp = $pp->p_list.le_next
5490 end
5491 end
5492
5493 document showallprocvnodes
5494 Syntax: (gdb) showallprocvnodes
5495 | Routine to print out all the open fds
5496 | which are vnodes
5497 end
5498
5499
5500 #
5501 # dump the childrent of a proc
5502 #
5503 define showinitchild
5504 set $basep = (struct proc *)initproc->p_children.lh_first
5505 set $pp = $basep
5506 while $pp
5507 showprocinfo $pp
5508 set $pp = $pp->p_sibling.le_next
5509 end
5510 end
5511
5512 document showinitchild
5513 Syntax: (gdb) showinitchild
5514 | Routine to print out all processes in the system
5515 | which are children of init process
5516 end
5517
5518
5519 define showmountallvnodes
5520 set $mp = (struct mount *)$arg0
5521 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
5522 set $vp = $basevp
5523 printf "____________________ Vnode list Queue ---------------\n"
5524 while $vp
5525 print_vnode $vp
5526 set $vp = $vp->v_mntvnodes->tqe_next
5527 end
5528 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
5529 set $vp = $basevp
5530 printf "____________________ Worker Queue ---------------\n"
5531 while $vp
5532 print_vnode $vp
5533 set $vp = $vp->v_mntvnodes->tqe_next
5534 end
5535 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
5536 set $vp = $basevp
5537 printf "____________________ New vnodes Queue ---------------\n"
5538 while $vp
5539 print_vnode $vp
5540 set $vp = $vp->v_mntvnodes->tqe_next
5541 end
5542 end
5543 document showmountallvnodes
5544 Syntax: showmountallvnodes <struct mount *>
5545 | Print the vnode inactive list
5546 end
5547
5548
5549 define showmountvnodes
5550 set $mp = (struct mount *)$arg0
5551 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
5552 set $vp = $basevp
5553 printf "____________________ Vnode list Queue ---------------\n"
5554 while $vp
5555 print_vnode $vp
5556 set $vp = $vp->v_mntvnodes->tqe_next
5557 end
5558 end
5559 document showmountvnodes
5560 Syntax: showmountvnodes <struct mount *>
5561 | Print the vnode list
5562 end
5563
5564
5565
5566 define showworkqvnodes
5567 set $mp = (struct mount *)$arg0
5568 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
5569 set $vp = $basevp
5570 printf "____________________ Worker Queue ---------------\n"
5571 while $vp
5572 print_vnode $vp
5573 set $vp = $vp->v_mntvnodes->tqe_next
5574 end
5575 end
5576 document showworkqvnodes
5577 Syntax: showworkqvnodes <struct mount *>
5578 | Print the vnode worker list
5579 end
5580
5581
5582 define shownewvnodes
5583 set $mp = (struct mount *)$arg0
5584 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
5585 set $vp = $basevp
5586 printf "____________________ New vnodes Queue ---------------\n"
5587 while $vp
5588 print_vnode $vp
5589 set $vp = $vp->v_mntvnodes->tqe_next
5590 end
5591 end
5592
5593 document shownewvnodes
5594 Syntax: shownewvnodes <struct mount *>
5595 | Print the new vnode list
5596 end
5597
5598
5599 #
5600 # print mount point info
5601 define print_mount
5602 set $mp = (struct mount *)$arg0
5603 printf " "
5604 printf " mp "
5605 showptr $mp
5606 printf " flag %x", $mp->mnt_flag
5607 printf " kern_flag %x", $mp->mnt_kern_flag
5608 printf " lflag %x", $mp->mnt_lflag
5609 printf " type: %s", $mp->mnt_vfsstat.f_fstypename
5610 printf " mnton: %s", $mp->mnt_vfsstat.f_mntonname
5611 printf " mntfrom: %s", $mp->mnt_vfsstat.f_mntfromname
5612 printf "\n"
5613 end
5614
5615 define showallmounts
5616 set $mp=(struct mount *)mountlist.tqh_first
5617 while $mp
5618 print_mount $mp
5619 set $mp = $mp->mnt_list.tqe_next
5620 end
5621 end
5622
5623 document showallmounts
5624 Syntax: showallmounts
5625 | Print all mount points
5626 end
5627
5628 define pcprint
5629 if (((unsigned long) $arg0 < (unsigned long) &_mh_execute_header || \
5630 (unsigned long) $arg0 >= (unsigned long) &last_kernel_symbol ))
5631 showkmodaddr $arg0
5632 else
5633 output /a $arg0
5634 end
5635 end
5636
5637 define mbuf_walkpkt
5638 set $mp = (struct mbuf *)$arg0
5639 set $cnt = 1
5640 set $tot = 0
5641 while $mp
5642 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
5643 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
5644 if mclaudit != 0
5645 mbuf_buf2mca $mp
5646 printf ", "
5647 end
5648 set $tot = $tot + $mp->m_hdr.mh_len
5649 printf "total %d]\n", $tot
5650 set $mp = $mp->m_hdr.mh_nextpkt
5651 set $cnt = $cnt + 1
5652 end
5653 end
5654
5655 document mbuf_walkpkt
5656 Syntax: (gdb) mbuf_walkpkt <addr>
5657 | Given an mbuf address, walk its m_nextpkt pointer
5658 end
5659
5660 define mbuf_walk
5661 set $mp = (struct mbuf *)$arg0
5662 set $cnt = 1
5663 set $tot = 0
5664 while $mp
5665 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
5666 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
5667 if mclaudit != 0
5668 mbuf_buf2mca $mp
5669 printf ", "
5670 end
5671 set $tot = $tot + $mp->m_hdr.mh_len
5672 printf "total %d]\n", $tot
5673 set $mp = $mp->m_hdr.mh_next
5674 set $cnt = $cnt + 1
5675 end
5676 end
5677
5678 document mbuf_walk
5679 Syntax: (gdb) mbuf_walk <addr>
5680 | Given an mbuf address, walk its m_next pointer
5681 end
5682
5683 define mbuf_buf2slab
5684 set $addr = $arg0
5685 set $gix = ((char *)$addr - (char *)mbutl) >> 20
5686 set $ix = ((char *)$addr - (char *)slabstbl[$gix].slg_slab[0].sl_base) >> 12
5687 set $slab = &slabstbl[$gix].slg_slab[$ix]
5688 if $kgm_lp64
5689 printf "0x%-16llx", $slab
5690 else
5691 printf "0x%-8x", $slab
5692 end
5693 end
5694
5695 document mbuf_buf2slab
5696 | Given an mbuf object, find its corresponding slab address.
5697 end
5698
5699 define mbuf_buf2mca
5700 set $addr = $arg0
5701 set $ix = ((char *)$addr - (char *)mbutl) >> 12
5702 set $clbase = ((union mbigcluster *)mbutl) + $ix
5703 set $mclidx = (((char *)$addr - (char *)$clbase) >> 8)
5704 set $mca = mclaudit[$ix].cl_audit[$mclidx]
5705 if $kgm_lp64
5706 printf "mca: 0x%-16llx", $mca
5707 else
5708 printf "mca: 0x%-8x", $mca
5709 end
5710 end
5711
5712 document mbuf_buf2mca
5713 Syntax: (gdb) mbuf_buf2mca <addr>
5714 | Given an mbuf object, find its buffer audit structure address.
5715 | This requires mbuf buffer auditing to be turned on, by setting
5716 | the appropriate flags to the "mbuf_debug" boot-args parameter.
5717 end
5718
5719 define mbuf_showmca
5720 set language c
5721 set $mca = (mcache_audit_t *)$arg0
5722 set $cp = (mcache_t *)$mca->mca_cache
5723 printf "object type:\t\t"
5724 mbuf_mca_ctype $mca 1
5725 printf "\ncontrolling mcache:\t%p (%s)\n", $mca->mca_cache, $cp->mc_name
5726 if $mca->mca_uflags & $MB_SCVALID
5727 set $ix = ((char *)$mca->mca_addr - (char *)mbutl) >> 12
5728 set $clbase = ((union mbigcluster *)mbutl) + $ix
5729 set $mclidx = (((char *)$mca->mca_addr - (char *)$clbase) >> 8)
5730 printf "mbuf obj:\t\t%p\n", $mca->mca_addr
5731 printf "mbuf index:\t\t%d (out of 16) in cluster base %p\n", \
5732 $mclidx + 1, $clbase
5733 if $mca->mca_uptr != 0
5734 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
5735 printf "paired cluster obj:\t%p (mca %p)\n", \
5736 $peer_mca->mca_addr, $peer_mca
5737 end
5738 printf "saved contents:\t\t%p (%d bytes)\n", \
5739 $mca->mca_contents, $mca->mca_contents_size
5740 else
5741 printf "cluster obj:\t\t%p\n", $mca->mca_addr
5742 if $mca->mca_uptr != 0
5743 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
5744 printf "paired mbuf obj:\t%p (mca %p)\n", \
5745 $peer_mca->mca_addr, $peer_mca
5746 end
5747 end
5748 printf "recent transaction for this buffer (thread %p):\n", \
5749 $mca->mca_thread
5750 set $cnt = 0
5751 while $cnt < $mca->mca_depth
5752 set $kgm_pc = $mca->mca_stack[$cnt]
5753 printf "%4d: ", $cnt + 1
5754 pcprint $kgm_pc
5755 printf "\n"
5756 set $cnt = $cnt + 1
5757 end
5758 if $mca->mca_pdepth > 0
5759 printf "previous transaction for this buffer (thread %p):\n", \
5760 $mca->mca_pthread
5761 end
5762 set $cnt = 0
5763 while $cnt < $mca->mca_pdepth
5764 set $kgm_pc = $mca->mca_pstack[$cnt]
5765 printf "%4d: ", $cnt + 1
5766 pcprint $kgm_pc
5767 printf "\n"
5768 set $cnt = $cnt + 1
5769 end
5770 set language auto
5771 end
5772
5773 document mbuf_showmca
5774 Syntax: (gdb) mbuf_showmca <addr>
5775 | Given an mbuf/cluster buffer audit structure address, print the audit
5776 | records including the stack trace of the last buffer transaction.
5777 end
5778
5779 define mbuf_topleak
5780 set language c
5781 set $topcnt = 0
5782 if $arg0 < 5
5783 set $maxcnt = $arg0
5784 else
5785 set $maxcnt = 5
5786 end
5787 while $topcnt < $maxcnt
5788 mbuf_traceleak mleak_top_trace[$topcnt]
5789 set $topcnt = $topcnt + 1
5790 end
5791 set language auto
5792 end
5793
5794 document mbuf_topleak
5795 Syntax: (gdb) mbuf_topleak <num>
5796 | Prints information about the top <num> suspected mbuf leakers
5797 | where <num> is a value <= 5
5798 end
5799
5800 define mbuf_traceleak
5801 set language c
5802 set $trace = (struct mtrace *) $arg0
5803 if $trace->allocs != 0
5804 printf "%p:%d outstanding allocs\n", $trace, $trace->allocs
5805 printf "backtrace saved %d deep:\n", $trace->depth
5806 if $trace->depth != 0
5807 set $cnt = 0
5808 while $cnt < $trace->depth
5809 printf "%4d: ", $cnt + 1
5810 pcprint $trace->addr[$cnt]
5811 printf "\n"
5812 set $cnt = $cnt + 1
5813 end
5814 end
5815 end
5816 set language auto
5817 end
5818
5819 document mbuf_traceleak
5820 Syntax: (gdb) mbuf_traceleak <addr>
5821 | Given an mbuf leak trace (mtrace) structure address, print out the
5822 | stored information with that trace
5823 end
5824
5825 set $MCF_NOCPUCACHE = 0x10
5826
5827 define mcache_stat
5828 set $head = (mcache_t *)mcache_head
5829 set $mc = $head
5830
5831 if $kgm_lp64
5832 printf "cache cache cache buf buf backing (# of retries) bufs\n"
5833 printf "name state addr size align zone wait nowait failed incache\n"
5834 printf "------------------------- -------- ------------------ ------ ----- ------------------ -------------------------- --------\n"
5835 else
5836 printf "cache cache cache buf buf backing (# of retries) bufs\n"
5837 printf "name state addr size align zone wait nowait failed incache\n"
5838 printf "------------------------- -------- ---------- ------ ----- ---------- -------------------------- --------\n"
5839 end
5840 while $mc != 0
5841 set $bktsize = $mc->mc_cpu.cc_bktsize
5842 printf "%-25s ", $mc->mc_name
5843 if ($mc->mc_flags & $MCF_NOCPUCACHE)
5844 printf "disabled"
5845 else
5846 if $mc->mc_purge_cnt > 0
5847 printf " purging"
5848 else
5849 if $bktsize == 0
5850 printf " offline"
5851 else
5852 printf " online"
5853 end
5854 end
5855 end
5856 printf " %p %6d %5d ",$mc, \
5857 $mc->mc_bufsize, $mc->mc_align
5858 if $mc->mc_slab_zone != 0
5859 printf "%p", $mc->mc_slab_zone
5860 else
5861 if $kgm_lp64
5862 printf " custom"
5863 else
5864 printf " custom"
5865 end
5866 end
5867 set $tot = 0
5868 set $tot += $mc->mc_full.bl_total * $bktsize
5869 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
5870 set $n = 0
5871 while $n < ncpu
5872 if $ccp->cc_objs > 0
5873 set $tot += $ccp->cc_objs
5874 end
5875 if $ccp->cc_pobjs > 0
5876 set $tot += $ccp->cc_pobjs
5877 end
5878 set $n += 1
5879 set $ccp += 1
5880 end
5881 printf " %8d %8d %8d %8d", $mc->mc_wretry_cnt, \
5882 $mc->mc_nwretry_cnt, $mc->mc_nwfail_cnt, $tot
5883 printf "\n"
5884 set $mc = (mcache_t *)$mc->mc_list.le_next
5885 end
5886 end
5887
5888 document mcache_stat
5889 Syntax: (gdb) mcache_stat
5890 | Print all mcaches in the system.
5891 end
5892
5893 define mcache_showzone
5894 set $mc = (mcache_t *)$arg0
5895 if $mc->mc_slab_zone != 0
5896 printf "%p", $mc->mc_slab_zone
5897 else
5898 printf " custom"
5899 end
5900
5901 document mcache_showzone
5902 Syntax: (gdb) mcache_showzone <mcache_addr>
5903 | Print the type of backend (custom or zone) of a mcache.
5904 end
5905
5906 define mcache_walkobj
5907 set $p = (mcache_obj_t *)$arg0
5908 set $cnt = 1
5909 set $tot = 0
5910 while $p
5911 printf "%4d: %p\n", $cnt, $p,
5912 set $p = $p->obj_next
5913 set $cnt = $cnt + 1
5914 end
5915 end
5916
5917 document mcache_walkobj
5918 Syntax: (gdb) mcache_walkobj <addr>
5919 | Given a mcache object address, walk its obj_next pointer
5920 end
5921
5922 define mcache_showcache
5923 set $cp = (mcache_t *)$arg0
5924 set $ccp = (mcache_cpu_t *)$cp->mc_cpu
5925 set $bktsize = $cp->mc_cpu.cc_bktsize
5926 set $cnt = 0
5927 set $tot = 0
5928 printf "Showing cache '%s':\n\n", $cp->mc_name
5929 printf " CPU cc_objs cc_pobjs total\n"
5930 printf "---- -------- -------- --------\n"
5931 while $cnt < ncpu
5932 set $objs = $ccp->cc_objs
5933 if $objs <= 0
5934 set $objs = 0
5935 end
5936 set $pobjs = $ccp->cc_pobjs
5937 if $pobjs <= 0
5938 set $pobjs = 0
5939 end
5940 set $tot_cpu = $objs + $pobjs
5941 set $tot += $tot_cpu
5942 printf "%4d %8d %8d %8d\n", $cnt, $objs, $pobjs, $tot_cpu
5943 set $ccp += 1
5944 set $cnt += 1
5945 end
5946 printf " ========\n"
5947 printf " %8d\n", $tot
5948 printf "\n"
5949 set $tot += $cp->mc_full.bl_total * $bktsize
5950 printf "Total # of full buckets (%d objs/bkt):\t%-8d\n", \
5951 $bktsize, $cp->mc_full.bl_total
5952 printf "Total # of objects cached:\t\t%-8d\n", $tot
5953 end
5954
5955 document mcache_showcache
5956 | Display the number of objects in the cache
5957 end
5958
5959 set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
5960
5961 define mbuf_slabstbl
5962 set $x = 0
5963
5964 if $kgm_lp64
5965 printf "slot slabg slabs range\n"
5966 printf "---- ------------------ -------------------------------------------\n"
5967 else
5968 printf "slot slabg slabs range\n"
5969 printf "---- ---------- ---------------------------\n"
5970 end
5971 while $x < maxslabgrp
5972 set $slg = slabstbl[$x]
5973 printf "%3d: ", $x
5974 if $slg == 0
5975 printf "-\n"
5976 else
5977 if $kgm_lp64
5978 printf "0x%-16llx [ 0x%-16llx - 0x%-16llx ]\n", $slg, &$slg->slg_slab[0], \
5979 &$slg->slg_slab[$NSLABSPMB-1]
5980 else
5981 printf "0x%-8x [ 0x%-8x - 0x%-8x ]\n", $slg, &$slg->slg_slab[0], \
5982 &$slg->slg_slab[$NSLABSPMB-1]
5983 end
5984 end
5985 set $x += 1
5986 end
5987 end
5988
5989 document mbuf_slabstbl
5990 | Display the mbuf slabs table
5991 end
5992
5993 set $SLF_MAPPED=0x0001
5994 set $SLF_PARTIAL=0x0002
5995 set $SLF_DETACHED=0x0004
5996
5997 define mbuf_slabs
5998 set $slg = (mcl_slabg_t *)$arg0
5999 set $x = 0
6000
6001 if $kgm_lp64
6002 printf "slot slab next obj mca C R N size flags\n"
6003 printf "---- ------------------ ------------------ ------------------ ------------------ -- -- -- ------ -----\n"
6004 else
6005 printf "slot slab next obj mca C R N size flags\n"
6006 printf "---- ---------- ---------- ---------- ---------- -- -- -- ------ -----\n"
6007 end
6008 while $x < $NSLABSPMB
6009 set $sl = &$slg->slg_slab[$x]
6010 set $mca = 0
6011 set $obj = $sl->sl_base
6012
6013 if mclaudit != 0
6014 set $ix = ((char *)$obj - (char *)mbutl) >> 12
6015 set $clbase = ((union mbigcluster *)mbutl) + $ix
6016 set $mclidx = (((char *)$obj - (char *)$clbase) >> 8)
6017 set $mca = mclaudit[$ix].cl_audit[$mclidx]
6018 end
6019
6020 if $kgm_lp64
6021 printf "%3d: 0x%-16llx 0x%-16llx 0x%-16llx 0x%-16llx %2d %2d %2d %6d 0x%04x ", \
6022 $x + 1, $sl, $sl->sl_next, $obj, $mca, $sl->sl_class, \
6023 $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
6024 $sl->sl_flags
6025 else
6026 printf "%3d: 0x%-8x 0x%-8x 0x%-8x 0x%-8x %2d %2d %2d %6d 0x%04x ", \
6027 $x + 1, $sl, $sl->sl_next, $obj, $mca, $sl->sl_class, \
6028 $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
6029 $sl->sl_flags
6030 end
6031 if $sl->sl_flags != 0
6032 printf "<"
6033 if $sl->sl_flags & $SLF_MAPPED
6034 printf "mapped"
6035 end
6036 if $sl->sl_flags & $SLF_PARTIAL
6037 printf ",partial"
6038 end
6039 if $sl->sl_flags & $SLF_DETACHED
6040 printf ",detached"
6041 end
6042 printf ">"
6043 end
6044 printf "\n"
6045
6046 if $sl->sl_chunks > 1
6047 set $z = 1
6048 set $c = $sl->sl_len / $sl->sl_chunks
6049
6050 while $z < $sl->sl_chunks
6051 set $obj = $sl->sl_base + ($c * $z)
6052 set $mca = 0
6053
6054 if mclaudit != 0
6055 set $ix = ((char *)$obj - (char *)mbutl) >> 12
6056 set $clbase = ((union mbigcluster *)mbutl) + $ix
6057 set $mclidx = (((char *)$obj - (char *)$clbase) >> 8)
6058 set $mca = mclaudit[$ix].cl_audit[$mclidx]
6059 end
6060
6061 if $kgm_lp64
6062 printf " 0x%-16llx 0x%-16llx\n", $obj, $mca
6063 else
6064 printf " 0x%-8x 0x%-8x\n", $obj, $mca
6065 end
6066 set $z += 1
6067 end
6068 end
6069
6070 set $x += 1
6071 end
6072 end
6073
6074 document mbuf_slabs
6075 | Display all mbuf slabs in the group
6076 end
6077
6078 define mbuf_stat
6079 set $x = 0
6080
6081 printf "class total cached uncached inuse failed waiter notified purge\n"
6082 printf "name objs objs objs / slabs objs alloc count count count count\n"
6083 printf "---------------- -------- -------- ------------------- -------- ---------------- -------- -------- --------\n"
6084 while $x < (sizeof(mbuf_table) / sizeof(mbuf_table[0]))
6085 set $mbt = mbuf_table[$x]
6086 set $mcs = (mb_class_stat_t *)mbuf_table[$x].mtbl_stats
6087 set $tot = 0
6088 set $mc = $mbt->mtbl_cache
6089 set $bktsize = $mc->mc_cpu.cc_bktsize
6090 set $tot += $mc->mc_full.bl_total * $bktsize
6091 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
6092 set $n = 0
6093 while $n < ncpu
6094 if $ccp->cc_objs > 0
6095 set $tot += $ccp->cc_objs
6096 end
6097 if $ccp->cc_pobjs > 0
6098 set $tot += $ccp->cc_pobjs
6099 end
6100 set $n += 1
6101 set $ccp += 1
6102 end
6103
6104 printf "%-16s %8d %8d %8d / %-8d %8d %16llu %8d %8llu %8llu", \
6105 $mcs->mbcl_cname, $mcs->mbcl_total, $tot, \
6106 $mcs->mbcl_infree, $mcs->mbcl_slab_cnt, \
6107 ($mcs->mbcl_total - $tot - $mcs->mbcl_infree), \
6108 $mcs->mbcl_fail_cnt, $mc->mc_waiter_cnt, \
6109 $mcs->mbcl_notified, $mcs->mbcl_purge_cnt
6110 printf "\n"
6111 set $x += 1
6112 end
6113 end
6114
6115 document mbuf_stat
6116 | Print extended mbuf allocator statistics.
6117 end
6118
6119 set $MB_INUSE = 0x1
6120 set $MB_COMP_INUSE = 0x2
6121 set $MB_SCVALID = 0x4
6122
6123 set $MCLBYTES = 2048
6124 set $MSIZE = 256
6125 set $NBPG = 4096
6126 set $M16KCLBYTES = 16384
6127
6128 define mbuf_mca_ctype
6129 set $mca = (mcache_audit_t *)$arg0
6130 set $vopt = $arg1
6131 set $cp = $mca->mca_cache
6132 set $class = (unsigned int)$cp->mc_private
6133 set $csize = mbuf_table[$class].mtbl_stats->mbcl_size
6134 set $done = 0
6135 if $csize == $MSIZE
6136 if $vopt
6137 printf "M (mbuf) "
6138 else
6139 printf "M "
6140 end
6141 set $done = 1
6142 end
6143 if !$done && $csize == $MCLBYTES
6144 if $vopt
6145 printf "CL (2K cluster) "
6146 else
6147 printf "CL "
6148 end
6149 set $done = 1
6150 end
6151 if !$done && $csize == $NBPG
6152 if $vopt
6153 printf "BCL (4K cluster) "
6154 else
6155 printf "BCL "
6156 end
6157 set $done = 1
6158 end
6159 if !$done && $csize == $M16KCLBYTES
6160 if $vopt
6161 printf "JCL (16K cluster) "
6162 else
6163 printf "JCL "
6164 end
6165 set $done = 1
6166 end
6167 if !$done && $csize == ($MSIZE+$MCLBYTES)
6168 if $mca->mca_uflags & $MB_SCVALID
6169 if $mca->mca_uptr
6170 printf "M+CL "
6171 if $vopt
6172 printf "(paired mbuf, 2K cluster)"
6173 end
6174 else
6175 printf "M-CL "
6176 if $vopt
6177 printf "(unpaired mbuf, 2K cluster) "
6178 end
6179 end
6180 else
6181 if $mca->mca_uptr
6182 printf "CL+M "
6183 if $vopt
6184 printf "(paired 2K cluster, mbuf) "
6185 end
6186 else
6187 printf "CL-M "
6188 if $vopt
6189 printf "(paired 2K cluster, mbuf) "
6190 end
6191 end
6192 end
6193 set $done = 1
6194 end
6195 if !$done && $csize == ($MSIZE+$NBPG)
6196 if $mca->mca_uflags & $MB_SCVALID
6197 if $mca->mca_uptr
6198 printf "M+BCL "
6199 if $vopt
6200 printf "(paired mbuf, 4K cluster) "
6201 end
6202 else
6203 printf "M-BCL "
6204 if $vopt
6205 printf "(unpaired mbuf, 4K cluster) "
6206 end
6207 end
6208 else
6209 if $mca->mca_uptr
6210 printf "BCL+M "
6211 if $vopt
6212 printf "(paired 4K cluster, mbuf) "
6213 end
6214 else
6215 printf "BCL-M "
6216 if $vopt
6217 printf "(unpaired 4K cluster, mbuf) "
6218 end
6219 end
6220 end
6221 set $done = 1
6222 end
6223 if !$done && $csize == ($MSIZE+$M16KCLBYTES)
6224 if $mca->mca_uflags & $MB_SCVALID
6225 if $mca->mca_uptr
6226 printf "M+JCL "
6227 if $vopt
6228 printf "(paired mbuf, 16K cluster) "
6229 end
6230 else
6231 printf "M-JCL "
6232 if $vopt
6233 printf "(unpaired mbuf, 16K cluster) "
6234 end
6235 end
6236 else
6237 if $mca->mca_uptr
6238 printf "JCL+M "
6239 if $vopt
6240 printf "(paired 16K cluster, mbuf) "
6241 end
6242 else
6243 printf "JCL-M "
6244 if $vopt
6245 printf "(unpaired 16K cluster, mbuf) "
6246 end
6247 end
6248 end
6249 set $done = 1
6250 end
6251 if !$done
6252 printf "unknown: %s ", $cp->mc_name
6253 end
6254 end
6255
6256 document mbuf_mca_ctype
6257 | This is a helper macro for mbuf_show{active,inactive,all} that prints
6258 | out the mbuf object type represented by a given mcache audit structure.
6259 end
6260
6261 define mbuf_showactive
6262 if $argc == 0
6263 mbuf_walkallslabs 1 0
6264 else
6265 mbuf_walkallslabs 1 0 $arg0
6266 end
6267 end
6268
6269 document mbuf_showactive
6270 Syntax: (gdb) mbuf_showactive
6271 | Walk the mbuf objects pool and print only the active ones; this
6272 | requires mbuf debugging to be turned on, by setting the appropriate flags
6273 | to the "mbuf_debug" boot-args parameter. Active objects are those that
6274 | are outstanding (have not returned to the mbuf slab layer) and in use
6275 | by the client (have not been freed).
6276 end
6277
6278 define mbuf_showinactive
6279 mbuf_walkallslabs 0 1
6280 end
6281
6282 document mbuf_showinactive
6283 Syntax: (gdb) mbuf_showinactive
6284 | Walk the mbuf objects pool and print only the inactive ones; this
6285 | requires mbuf debugging to be turned on, by setting the appropriate flags
6286 | to the "mbuf_debug" boot-args parameter. Inactive objects are those that
6287 | are outstanding (have not returned to the mbuf slab layer) but have been
6288 | freed by the client, i.e. they still reside in the mcache layer ready to
6289 | be used for subsequent allocation requests.
6290 end
6291
6292 define mbuf_showall
6293 mbuf_walkallslabs 1 1
6294 end
6295
6296 document mbuf_showall
6297 Syntax: (gdb) mbuf_showall
6298 | Walk the mbuf objects pool and print them all; this requires
6299 | mbuf debugging to be turned on, by setting the appropriate flags to the
6300 | "mbuf_debug" boot-args parameter.
6301 end
6302
6303 define mbuf_mcaobjs
6304 end
6305
6306 define mbuf_walkallslabs
6307 set $show_a = $arg0
6308 set $show_f = $arg1
6309 if $argc == 3
6310 set $show_tr = $arg2
6311 else
6312 set $show_tr = 0
6313 end
6314 set $x = 0
6315 set $total = 0
6316 set $total_a = 0
6317 set $total_f = 0
6318
6319 printf "("
6320 if $show_a && !$show_f
6321 printf "Searching only for active "
6322 end
6323 if !$show_a && $show_f
6324 printf "Searching only for inactive "
6325 end
6326 if $show_a && $show_f
6327 printf "Displaying all "
6328 end
6329 printf "objects; this may take a while ...)\n\n"
6330
6331 if $kgm_lp64
6332 printf " slab mca obj allocation\n"
6333 printf "slot idx address address address type state\n"
6334 printf "---- ---- ------------------ ------------------ ------------------ ----- -----------\n"
6335 else
6336 printf " slab mca obj allocation\n"
6337 printf "slot idx address address address type state\n"
6338 printf "---- ---- ---------- ---------- ---------- ----- -----------\n"
6339 end
6340
6341 while $x < slabgrp
6342 set $slg = slabstbl[$x]
6343 set $y = 0
6344 set $stop = 0
6345 while $y < $NSLABSPMB && $stop == 0
6346 set $sl = &$slg->slg_slab[$y]
6347 set $base = (char *)$sl->sl_base
6348 set $ix = ($base - (char *)mbutl) >> 12
6349 set $clbase = ((union mbigcluster *)mbutl) + $ix
6350 set $mclidx = ($base - (char *)$clbase) >> 8
6351 set $mca = mclaudit[$ix].cl_audit[$mclidx]
6352 set $first = 1
6353
6354 while $mca != 0 && $mca->mca_addr != 0
6355 set $printmca = 0
6356 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
6357 set $total_a = $total_a + 1
6358 set $printmca = $show_a
6359 else
6360 set $total_f = $total_f + 1
6361 set $printmca = $show_f
6362 end
6363
6364 if $printmca != 0
6365 if $first == 1
6366 if $kgm_lp64
6367 printf "%4d %4d 0x%-16llx ", $x, $y, $sl
6368 else
6369 printf "%4d %4d 0x%-8x ", $x, $y, $sl
6370 end
6371 else
6372 if $kgm_lp64
6373 printf " "
6374 else
6375 printf " "
6376 end
6377 end
6378
6379 if $kgm_lp64
6380 printf "0x%-16llx 0x%-16llx ", $mca, $mca->mca_addr
6381 else
6382 printf "0x%-8x 0x%-8x ", $mca, $mca->mca_addr
6383 end
6384
6385 mbuf_mca_ctype $mca 0
6386 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
6387 printf "active "
6388 else
6389 printf " freed "
6390 end
6391 if $first == 1
6392 set $first = 0
6393 end
6394 printf "\n"
6395 set $total = $total + 1
6396
6397 if $show_tr != 0
6398 printf "recent transaction for this buffer (thread %p):\n", \
6399 $mca->mca_thread
6400 set $cnt = 0
6401 while $cnt < $mca->mca_depth
6402 set $kgm_pc = $mca->mca_stack[$cnt]
6403 printf "%4d: ", $cnt + 1
6404 pcprint $kgm_pc
6405 printf "\n"
6406 set $cnt = $cnt + 1
6407 end
6408 end
6409 end
6410
6411 set $mca = $mca->mca_next
6412 end
6413 set $y += 1
6414 if $slg->slg_slab[$y].sl_base == 0
6415 set $stop = 1
6416 end
6417 end
6418 set $x += 1
6419 end
6420 if $total && $show_a && $show_f
6421 printf "\ntotal objects:\t%d\n", $total
6422 printf "active/unfreed:\t%d\n", $total_a
6423 printf "freed/in_cache:\t%d\n", $total_f
6424 end
6425 end
6426
6427 document mbuf_walkallslabs
6428 | Walk the mbuf objects pool; this requires mbuf debugging to be
6429 | turned on, by setting the appropriate flags to the "mbuf_debug" boot-args
6430 | parameter. This is a backend routine for mbuf_show{active,inactive,all}.
6431 end
6432
6433 define mbuf_countchain
6434 set $mp = (struct mbuf *)$arg0
6435
6436 set $pkt = 0
6437 set $nxt = 0
6438
6439 while $mp != 0
6440 set $pkt = $pkt + 1
6441
6442 set $mn = (struct mbuf *)$mp->m_hdr.mh_next
6443 while $mn != 0
6444 set $nxt = $nxt + 1
6445
6446 set $mn = (struct mbuf *)$mn->m_hdr.mh_next
6447 end
6448
6449 set $mp = $mp->m_hdr.mh_nextpkt
6450
6451 if (($pkt + $nxt) % 50) == 0
6452 printf "... %d\n", $pkt + $nxt
6453 end
6454 end
6455
6456 printf "\ntotal: %d (via m_next: %d)\n", $pkt + $nxt, $nxt
6457 end
6458
6459 document mbuf_countchain
6460 Syntax: mbuf_countchain <addr>
6461 | Count the total number of mbufs chained from the given the address of an mbuf.
6462 | The routine follows both the m_next pointers and m_nextpkt pointers.
6463 end
6464
6465 set $RTF_UP = 0x1
6466 set $RTF_GATEWAY = 0x2
6467 set $RTF_HOST = 0x4
6468 set $RTF_REJECT = 0x8
6469 set $RTF_DYNAMIC = 0x10
6470 set $RTF_MODIFIED = 0x20
6471 set $RTF_DONE = 0x40
6472 set $RTF_DELCLONE = 0x80
6473 set $RTF_CLONING = 0x100
6474 set $RTF_XRESOLVE = 0x200
6475 set $RTF_LLINFO = 0x400
6476 set $RTF_STATIC = 0x800
6477 set $RTF_BLACKHOLE = 0x1000
6478 set $RTF_PROTO2 = 0x4000
6479 set $RTF_PROTO1 = 0x8000
6480 set $RTF_PRCLONING = 0x10000
6481 set $RTF_WASCLONED = 0x20000
6482 set $RTF_PROTO3 = 0x40000
6483 set $RTF_PINNED = 0x100000
6484 set $RTF_LOCAL = 0x200000
6485 set $RTF_BROADCAST = 0x400000
6486 set $RTF_MULTICAST = 0x800000
6487 set $RTF_IFSCOPE = 0x1000000
6488 set $RTF_CONDEMNED = 0x2000000
6489
6490 set $AF_INET = 2
6491 set $AF_INET6 = 30
6492 set $AF_LINK = 18
6493
6494 define rtentry_prdetails
6495 set $rt = (struct rtentry *)$arg0
6496 set $is_v6 = 0
6497
6498 set $dst = (struct sockaddr *)$rt->rt_nodes->rn_u.rn_leaf.rn_Key
6499 if $dst->sa_family == $AF_INET
6500 showsockaddr_in $dst
6501 printf " "
6502 else
6503 if $dst->sa_family == $AF_INET6
6504 showsockaddr_in6 $dst
6505 printf " "
6506 set $is_v6 = 1
6507 else
6508 if $dst->sa_family == $AF_LINK
6509 showsockaddr_dl $dst
6510 printf " "
6511 else
6512 showsockaddr_unspec $dst
6513 end
6514 end
6515 end
6516
6517 set $dst = (struct sockaddr *)$rt->rt_gateway
6518 if $dst->sa_family == $AF_INET
6519 showsockaddr_in $dst
6520 printf " "
6521 else
6522 if $dst->sa_family == $AF_INET6
6523 set $is_v6 = 1
6524 showsockaddr_in6 $dst
6525 printf " "
6526 else
6527 if $dst->sa_family == $AF_LINK
6528 showsockaddr_dl $dst
6529 if $is_v6
6530 printf " "
6531 else
6532 printf " "
6533 end
6534 else
6535 showsockaddr_unspec $dst
6536 end
6537 end
6538 end
6539
6540 if $rt->rt_flags & $RTF_WASCLONED
6541 if $kgm_lp64
6542 printf "%18p ", $rt->rt_parent
6543 else
6544 printf "%10p ", $rt->rt_parent
6545 end
6546 else
6547 if $kgm_lp64
6548 printf " "
6549 else
6550 printf " "
6551 end
6552 end
6553
6554 printf "%6u %8u ", $rt->rt_refcnt, $rt->rt_rmx.rmx_pksent
6555
6556 if $rt->rt_flags & $RTF_UP
6557 printf "U"
6558 end
6559 if $rt->rt_flags & $RTF_GATEWAY
6560 printf "G"
6561 end
6562 if $rt->rt_flags & $RTF_HOST
6563 printf "H"
6564 end
6565 if $rt->rt_flags & $RTF_REJECT
6566 printf "R"
6567 end
6568 if $rt->rt_flags & $RTF_DYNAMIC
6569 printf "D"
6570 end
6571 if $rt->rt_flags & $RTF_MODIFIED
6572 printf "M"
6573 end
6574 if $rt->rt_flags & $RTF_CLONING
6575 printf "C"
6576 end
6577 if $rt->rt_flags & $RTF_PRCLONING
6578 printf "c"
6579 end
6580 if $rt->rt_flags & $RTF_LLINFO
6581 printf "L"
6582 end
6583 if $rt->rt_flags & $RTF_STATIC
6584 printf "S"
6585 end
6586 if $rt->rt_flags & $RTF_PROTO1
6587 printf "1"
6588 end
6589 if $rt->rt_flags & $RTF_PROTO2
6590 printf "2"
6591 end
6592 if $rt->rt_flags & $RTF_PROTO3
6593 printf "3"
6594 end
6595 if $rt->rt_flags & $RTF_WASCLONED
6596 printf "W"
6597 end
6598 if $rt->rt_flags & $RTF_BROADCAST
6599 printf "b"
6600 end
6601 if $rt->rt_flags & $RTF_MULTICAST
6602 printf "m"
6603 end
6604 if $rt->rt_flags & $RTF_XRESOLVE
6605 printf "X"
6606 end
6607 if $rt->rt_flags & $RTF_BLACKHOLE
6608 printf "B"
6609 end
6610 if $rt->rt_flags & $RTF_IFSCOPE
6611 printf "I"
6612 end
6613
6614 printf "/%s%d", $rt->rt_ifp->if_name, $rt->rt_ifp->if_unit
6615 end
6616
6617 set $RNF_ROOT = 2
6618
6619 define _rttable_dump
6620 set $rnh = $arg0
6621 set $rn = (struct radix_node *)$rnh->rnh_treetop
6622 set $rnh_cnt = $rnh->rnh_cnt
6623
6624 while $rn->rn_bit >= 0
6625 set $rn = $rn->rn_u.rn_node.rn_L
6626 end
6627
6628 while 1
6629 set $base = (struct radix_node *)$rn
6630 while ($rn->rn_parent->rn_u.rn_node.rn_R == $rn) && ($rn->rn_flags & $RNF_ROOT) == 0
6631 set $rn = $rn->rn_parent
6632 end
6633 set $rn = $rn->rn_parent->rn_u.rn_node.rn_R
6634 while $rn->rn_bit >= 0
6635 set $rn = $rn->rn_u.rn_node.rn_L
6636 end
6637 set $next = $rn
6638 while $base != 0
6639 set $rn = $base
6640 set $base = $rn->rn_u.rn_leaf.rn_Dupedkey
6641 if ($rn->rn_flags & $RNF_ROOT) == 0
6642
6643 set $rt = (struct rtentry *)$rn
6644
6645 if $kgm_lp64
6646 printf "%18p ", $rt
6647 else
6648 printf "%10p ", $rt
6649 end
6650 rtentry_prdetails $rt
6651 printf "\n"
6652
6653 end
6654 end
6655 set $rn = $next
6656 if ($rn->rn_flags & $RNF_ROOT) != 0
6657 loop_break
6658 end
6659 end
6660 end
6661
6662
6663 define show_rt_inet
6664 if $kgm_lp64
6665 printf " rtentry dst gw parent Refs Use flags/if\n"
6666 printf " ----------------- --------------- ----------------- ------------------ ------ -------- -----------\n"
6667 else
6668 printf " rtentry dst gw parent Refs Use flags/if\n"
6669 printf " --------- --------------- ----------------- ---------- ------ -------- -----------\n"
6670 end
6671 _rttable_dump rt_tables[2]
6672 end
6673
6674 document show_rt_inet
6675 Syntax: (gdb) show_rt_inet
6676 | Show the entries of the IPv4 routing table.
6677 end
6678
6679 define show_rt_inet6
6680 if $kgm_lp64
6681 printf " rtentry dst gw parent Refs Use flags/if\n"
6682 printf " ----------------- --------------------------------------- --------------------------------------- ------------------ ------ -------- -----------\n"
6683 else
6684 printf " rtentry dst gw parent Refs Use flags/if\n"
6685 printf " --------- --------------------------------------- --------------------------------------- ---------- ------ -------- -----------\n"
6686 end
6687 _rttable_dump rt_tables[30]
6688 end
6689
6690 document show_rt_inet6
6691 Syntax: (gdb) show_rt_inet6
6692 | Show the entries of the IPv6 routing table.
6693 end
6694
6695 define rtentry_trash
6696 set $rtd = (struct rtentry_dbg *)rttrash_head.tqh_first
6697 set $cnt = 0
6698 while $rtd != 0
6699 if $cnt == 0
6700 if $kgm_lp64
6701 printf " rtentry ref hold rele dst gw parent flags/if\n"
6702 printf " ----------------- --- ------ ------ --------------- ----- ------------------ -----------\n"
6703 else
6704 printf " rtentry ref hold rele dst gw parent flags/if\n"
6705 printf " --------- --- ------ ------ --------------- ----- ---------- -----------\n"
6706 end
6707 end
6708 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $rtd, \
6709 $rtd->rtd_refhold_cnt - $rtd->rtd_refrele_cnt, \
6710 $rtd->rtd_refhold_cnt, $rtd->rtd_refrele_cnt
6711 rtentry_prdetails $rtd
6712 printf "\n"
6713 set $rtd = $rtd->rtd_trash_link.tqe_next
6714 set $cnt = $cnt + 1
6715 end
6716 end
6717
6718 document rtentry_trash
6719 Syntax: (gdb) rtentry_trash
6720 | Walk the list of trash route entries; this requires route entry
6721 | debugging to be turned on, by setting the appropriate flags to the
6722 | "rte_debug" boot-args parameter.
6723 end
6724
6725 set $CTRACE_STACK_SIZE = ctrace_stack_size
6726 set $CTRACE_HIST_SIZE = ctrace_hist_size
6727
6728 define rtentry_showdbg
6729 set $rtd = (struct rtentry_dbg *)$arg0
6730 set $cnt = 0
6731
6732 printf "Total holds:\t%d\n", $rtd->rtd_refhold_cnt
6733 printf "Total releases:\t%d\n", $rtd->rtd_refrele_cnt
6734
6735 set $ix = 0
6736 while $ix < $CTRACE_STACK_SIZE
6737 set $kgm_pc = $rtd->rtd_alloc.pc[$ix]
6738 if $kgm_pc != 0
6739 if $ix == 0
6740 printf "\nAlloc (thread %p):\n", \
6741 $rtd->rtd_alloc.th
6742 end
6743 printf "%4d: ", $ix + 1
6744 pcprint $kgm_pc
6745 printf "\n"
6746 end
6747 set $ix = $ix + 1
6748 end
6749 set $ix = 0
6750 while $ix < $CTRACE_STACK_SIZE
6751 set $kgm_pc = $rtd->rtd_free.pc[$ix]
6752 if $kgm_pc != 0
6753 if $ix == 0
6754 printf "\nFree: (thread %p)\n", \
6755 $rtd->rtd_free.th
6756 end
6757 printf "%4d: ", $ix + 1
6758 pcprint $kgm_pc
6759 printf "\n"
6760 end
6761 set $ix = $ix + 1
6762 end
6763 while $cnt < $CTRACE_HIST_SIZE
6764 set $ix = 0
6765 while $ix < $CTRACE_STACK_SIZE
6766 set $kgm_pc = $rtd->rtd_refhold[$cnt].pc[$ix]
6767 if $kgm_pc != 0
6768 if $ix == 0
6769 printf "\nHold [%d] (thread %p):\n", \
6770 $cnt, $rtd->rtd_refhold[$cnt].th
6771 end
6772 printf "%4d: ", $ix + 1
6773 pcprint $kgm_pc
6774 printf "\n"
6775 end
6776 set $ix = $ix + 1
6777 end
6778 set $cnt = $cnt + 1
6779 end
6780 set $cnt = 0
6781 while $cnt < $CTRACE_HIST_SIZE
6782 set $ix = 0
6783 while $ix < $CTRACE_STACK_SIZE
6784 set $kgm_pc = $rtd->rtd_refrele[$cnt].pc[$ix]
6785 if $kgm_pc != 0
6786 if $ix == 0
6787 printf "\nRelease [%d] (thread %p):\n",\
6788 $cnt, $rtd->rtd_refrele[$cnt].th
6789 end
6790 printf "%4d: ", $ix + 1
6791 pcprint $kgm_pc
6792 printf "\n"
6793 end
6794 set $ix = $ix + 1
6795 end
6796 set $cnt = $cnt + 1
6797 end
6798
6799 printf "\nTotal locks:\t%d\n", $rtd->rtd_lock_cnt
6800 printf "Total unlocks:\t%d\n", $rtd->rtd_unlock_cnt
6801
6802 set $cnt = 0
6803 while $cnt < $CTRACE_HIST_SIZE
6804 set $ix = 0
6805 while $ix < $CTRACE_STACK_SIZE
6806 set $kgm_pc = $rtd->rtd_lock[$cnt].pc[$ix]
6807 if $kgm_pc != 0
6808 if $ix == 0
6809 printf "\nLock [%d] (thread %p):\n",\
6810 $cnt, $rtd->rtd_lock[$cnt].th
6811 end
6812 printf "%4d: ", $ix + 1
6813 pcprint $kgm_pc
6814 printf "\n"
6815 end
6816 set $ix = $ix + 1
6817 end
6818 set $cnt = $cnt + 1
6819 end
6820 set $cnt = 0
6821 while $cnt < $CTRACE_HIST_SIZE
6822 set $ix = 0
6823 while $ix < $CTRACE_STACK_SIZE
6824 set $kgm_pc = $rtd->rtd_unlock[$cnt].pc[$ix]
6825 if $kgm_pc != 0
6826 if $ix == 0
6827 printf "\nUnlock [%d] (thread %p):\n",\
6828 $cnt, $rtd->rtd_unlock[$cnt].th
6829 end
6830 printf "%4d: ", $ix + 1
6831 pcprint $kgm_pc
6832 printf "\n"
6833 end
6834 set $ix = $ix + 1
6835 end
6836 set $cnt = $cnt + 1
6837 end
6838 end
6839
6840 document rtentry_showdbg
6841 Syntax: (gdb) rtentry_showdbg <addr>
6842 | Given a route entry structure address, print the debug information
6843 | related to it. This requires route entry debugging to be turned
6844 | on, by setting the appropriate flags to the "rte_debug" boot-args
6845 | parameter.
6846 end
6847
6848 set $INIFA_TRACE_HIST_SIZE = inifa_trace_hist_size
6849
6850 define inifa_showdbg
6851 set $inifa = (struct in_ifaddr_dbg *)$arg0
6852 set $cnt = 0
6853
6854 printf "Total holds:\t%d\n", $inifa->inifa_refhold_cnt
6855 printf "Total releases:\t%d\n", $inifa->inifa_refrele_cnt
6856
6857 set $ix = 0
6858 while $ix < $CTRACE_STACK_SIZE
6859 set $kgm_pc = $inifa->inifa_alloc.pc[$ix]
6860 if $kgm_pc != 0
6861 if $ix == 0
6862 printf "\nAlloc (thread %p):\n", \
6863 $inifa->inifa_alloc.th
6864 end
6865 printf "%4d: ", $ix + 1
6866 pcprint $kgm_pc
6867 printf "\n"
6868 end
6869 set $ix = $ix + 1
6870 end
6871 set $ix = 0
6872 while $ix < $CTRACE_STACK_SIZE
6873 set $kgm_pc = $inifa->inifa_free.pc[$ix]
6874 if $kgm_pc != 0
6875 if $ix == 0
6876 printf "\nFree: (thread %p)\n", \
6877 $inifa->inifa_free.th
6878 end
6879 printf "%4d: ", $ix + 1
6880 pcprint $kgm_pc
6881 printf "\n"
6882 end
6883 set $ix = $ix + 1
6884 end
6885 while $cnt < $INIFA_TRACE_HIST_SIZE
6886 set $ix = 0
6887 while $ix < $CTRACE_STACK_SIZE
6888 set $kgm_pc = $inifa->inifa_refhold[$cnt].pc[$ix]
6889 if $kgm_pc != 0
6890 if $ix == 0
6891 printf "\nHold [%d] (thread %p):\n", \
6892 $cnt, $inifa->inifa_refhold[$cnt].th
6893 end
6894 printf "%4d: ", $ix + 1
6895 pcprint $kgm_pc
6896 printf "\n"
6897 end
6898 set $ix = $ix + 1
6899 end
6900 set $cnt = $cnt + 1
6901 end
6902 set $cnt = 0
6903 while $cnt < $INIFA_TRACE_HIST_SIZE
6904 set $ix = 0
6905 while $ix < $CTRACE_STACK_SIZE
6906 set $kgm_pc = $inifa->inifa_refrele[$cnt].pc[$ix]
6907 if $kgm_pc != 0
6908 if $ix == 0
6909 printf "\nRelease [%d] (thread %p):\n",\
6910 $cnt, $inifa->inifa_refrele[$cnt].th
6911 end
6912 printf "%4d: ", $ix + 1
6913 pcprint $kgm_pc
6914 printf "\n"
6915 end
6916 set $ix = $ix + 1
6917 end
6918 set $cnt = $cnt + 1
6919 end
6920 end
6921
6922 document inifa_showdbg
6923 Syntax: (gdb) inifa_showdbg <addr>
6924 | Given an IPv4 interface structure address, print the debug information
6925 | related to it. This requires interface address debugging to be turned
6926 | on, by setting the appropriate flags to the "ifa_debug" boot-args
6927 | parameter.
6928 end
6929
6930 set $IN6IFA_TRACE_HIST_SIZE = in6ifa_trace_hist_size
6931
6932 define in6ifa_showdbg
6933 set $in6ifa = (struct in6_ifaddr_dbg *)$arg0
6934 set $cnt = 0
6935
6936 printf "Total holds:\t%d\n", $in6ifa->in6ifa_refhold_cnt
6937 printf "Total releases:\t%d\n", $in6ifa->in6ifa_refrele_cnt
6938
6939 set $ix = 0
6940 while $ix < $CTRACE_STACK_SIZE
6941 set $kgm_pc = $in6ifa->in6ifa_alloc.pc[$ix]
6942 if $kgm_pc != 0
6943 if $ix == 0
6944 printf "\nAlloc (thread %p):\n", \
6945 $in6ifa->in6ifa_alloc.th
6946 end
6947 printf "%4d: ", $ix + 1
6948 pcprint $kgm_pc
6949 printf "\n"
6950 end
6951 set $ix = $ix + 1
6952 end
6953 set $ix = 0
6954 while $ix < $CTRACE_STACK_SIZE
6955 set $kgm_pc = $in6ifa->in6ifa_free.pc[$ix]
6956 if $kgm_pc != 0
6957 if $ix == 0
6958 printf "\nFree: (thread %p)\n", \
6959 $in6ifa->in6ifa_free.th
6960 end
6961 printf "%4d: ", $ix + 1
6962 pcprint $kgm_pc
6963 printf "\n"
6964 end
6965 set $ix = $ix + 1
6966 end
6967 while $cnt < $IN6IFA_TRACE_HIST_SIZE
6968 set $ix = 0
6969 while $ix < $CTRACE_STACK_SIZE
6970 set $kgm_pc = $in6ifa->in6ifa_refhold[$cnt].pc[$ix]
6971 if $kgm_pc != 0
6972 if $ix == 0
6973 printf "\nHold [%d] (thread %p):\n", \
6974 $cnt, $in6ifa->in6ifa_refhold[$cnt].th
6975 end
6976 printf "%4d: ", $ix + 1
6977 pcprint $kgm_pc
6978 printf "\n"
6979 end
6980 set $ix = $ix + 1
6981 end
6982 set $cnt = $cnt + 1
6983 end
6984 set $cnt = 0
6985 while $cnt < $IN6IFA_TRACE_HIST_SIZE
6986 set $ix = 0
6987 while $ix < $CTRACE_STACK_SIZE
6988 set $kgm_pc = $in6ifa->in6ifa_refrele[$cnt].pc[$ix]
6989 if $kgm_pc != 0
6990 if $ix == 0
6991 printf "\nRelease [%d] (thread %p):\n",\
6992 $cnt, $in6ifa->in6ifa_refrele[$cnt].th
6993 end
6994 printf "%4d: ", $ix + 1
6995 pcprint $kgm_pc
6996 printf "\n"
6997 end
6998 set $ix = $ix + 1
6999 end
7000 set $cnt = $cnt + 1
7001 end
7002 end
7003
7004 document in6ifa_showdbg
7005 Syntax: (gdb) in6ifa_showdbg <addr>
7006 | Given an IPv6 interface structure address, print the debug information
7007 | related to it. This requires interface address debugging to be turned
7008 | on, by setting the appropriate flags to the "ifa_debug" boot-args
7009 | parameter.
7010 end
7011
7012 set $IFMA_TRACE_HIST_SIZE = ifma_trace_hist_size
7013
7014 define ifma_showdbg
7015 set $ifma = (struct ifmultiaddr_dbg *)$arg0
7016 set $cnt = 0
7017
7018 printf "Total holds:\t%d\n", $ifma->ifma_refhold_cnt
7019 printf "Total releases:\t%d\n", $ifma->ifma_refrele_cnt
7020
7021 while $cnt < $IFMA_TRACE_HIST_SIZE
7022 set $ix = 0
7023 while $ix < $CTRACE_STACK_SIZE
7024 set $kgm_pc = $ifma->ifma_refhold[$cnt].pc[$ix]
7025 if $kgm_pc != 0
7026 if $ix == 0
7027 printf "\nHold [%d] (thread %p):\n", \
7028 $cnt, $ifma->ifma_refhold[$cnt].th
7029 end
7030 printf "%4d: ", $ix + 1
7031 pcprint $kgm_pc
7032 printf "\n"
7033 end
7034 set $ix = $ix + 1
7035 end
7036 set $cnt = $cnt + 1
7037 end
7038 set $cnt = 0
7039 while $cnt < $IFMA_TRACE_HIST_SIZE
7040 set $ix = 0
7041 while $ix < $CTRACE_STACK_SIZE
7042 set $kgm_pc = $ifma->ifma_refrele[$cnt].pc[$ix]
7043 if $kgm_pc != 0
7044 if $ix == 0
7045 printf "\nRelease [%d] (thread %p):\n",\
7046 $cnt, $ifma->ifma_refrele[$cnt].th
7047 end
7048 printf "%4d: ", $ix + 1
7049 pcprint $kgm_pc
7050 printf "\n"
7051 end
7052 set $ix = $ix + 1
7053 end
7054 set $cnt = $cnt + 1
7055 end
7056 end
7057
7058 document ifma_showdbg
7059 Syntax: (gdb) ifma_showdbg <addr>
7060 | Given a link multicast structure address, print the debug information
7061 | related to it. This requires interface address debugging to be turned
7062 | on, by setting the appropriate flags to the "ifa_debug" boot-args
7063 | parameter.
7064 end
7065
7066 set $INM_TRACE_HIST_SIZE = inm_trace_hist_size
7067
7068 define inm_showdbg
7069 set $inm = (struct in_multi_dbg *)$arg0
7070 set $cnt = 0
7071
7072 printf "Total holds:\t%d\n", $inm->inm_refhold_cnt
7073 printf "Total releases:\t%d\n", $inm->inm_refrele_cnt
7074
7075 while $cnt < $INM_TRACE_HIST_SIZE
7076 set $ix = 0
7077 while $ix < $CTRACE_STACK_SIZE
7078 set $kgm_pc = $inm->inm_refhold[$cnt].pc[$ix]
7079 if $kgm_pc != 0
7080 if $ix == 0
7081 printf "\nHold [%d] (thread %p):\n", \
7082 $cnt, $inm->inm_refhold[$cnt].th
7083 end
7084 printf "%4d: ", $ix + 1
7085 pcprint $kgm_pc
7086 printf "\n"
7087 end
7088 set $ix = $ix + 1
7089 end
7090 set $cnt = $cnt + 1
7091 end
7092 set $cnt = 0
7093 while $cnt < $INM_TRACE_HIST_SIZE
7094 set $ix = 0
7095 while $ix < $CTRACE_STACK_SIZE
7096 set $kgm_pc = $inm->inm_refrele[$cnt].pc[$ix]
7097 if $kgm_pc != 0
7098 if $ix == 0
7099 printf "\nRelease [%d] (thread %p):\n",\
7100 $cnt, $inm->inm_refrele[$cnt].th
7101 end
7102 printf "%4d: ", $ix + 1
7103 pcprint $kgm_pc
7104 printf "\n"
7105 end
7106 set $ix = $ix + 1
7107 end
7108 set $cnt = $cnt + 1
7109 end
7110 end
7111
7112 document inm_showdbg
7113 Syntax: (gdb) inm_showdbg <addr>
7114 | Given an IPv4 multicast structure address, print the debug information
7115 | related to it. This requires interface address debugging to be turned
7116 | on, by setting the appropriate flags to the "ifa_debug" boot-args
7117 | parameter.
7118 end
7119
7120 set $IF_REF_TRACE_HIST_SIZE = if_ref_trace_hist_size
7121
7122 define ifpref_showdbg
7123 set $dl_if = (struct dlil_ifnet_dbg *)$arg0
7124 set $cnt = 0
7125
7126 printf "Total references:\t%d\n", $dl_if->dldbg_if_refhold_cnt
7127 printf "Total releases:\t\t%d\n", $dl_if->dldbg_if_refrele_cnt
7128
7129 while $cnt < $IF_REF_TRACE_HIST_SIZE
7130 set $ix = 0
7131 while $ix < $CTRACE_STACK_SIZE
7132 set $kgm_pc = $dl_if->dldbg_if_refhold[$cnt].pc[$ix]
7133 if $kgm_pc != 0
7134 if $ix == 0
7135 printf "\nHold [%d] (thread %p):\n", \
7136 $cnt, \
7137 $dl_if->dldbg_if_refhold[$cnt].th
7138 end
7139 printf "%4d: ", $ix + 1
7140 pcprint $kgm_pc
7141 printf "\n"
7142 end
7143 set $ix = $ix + 1
7144 end
7145 set $cnt = $cnt + 1
7146 end
7147 set $cnt = 0
7148 while $cnt < $IF_REF_TRACE_HIST_SIZE
7149 set $ix = 0
7150 while $ix < $CTRACE_STACK_SIZE
7151 set $kgm_pc = $dl_if->dldbg_if_refrele[$cnt].pc[$ix]
7152 if $kgm_pc != 0
7153 if $ix == 0
7154 printf "\nRelease [%d] (thread %p):\n",\
7155 $cnt, \
7156 $dl_if->dldbg_if_refrele[$cnt].th
7157 end
7158 printf "%4d: ", $ix + 1
7159 pcprint $kgm_pc
7160 printf "\n"
7161 end
7162 set $ix = $ix + 1
7163 end
7164 set $cnt = $cnt + 1
7165 end
7166 end
7167
7168 document ifpref_showdbg
7169 Syntax: (gdb) ifpref_showdbg <addr>
7170 | Given an ifnet structure address, print the debug information
7171 | related to its refcnt. This requires ifnet debugging to be turned
7172 | on, by setting the appropriate flags to the "ifnet_debug" boot-args
7173 | parameter.
7174 end
7175
7176 define in6ifa_trash
7177 set $ifa = (struct in6_ifaddr_dbg *)in6ifa_trash_head.tqh_first
7178 set $cnt = 0
7179 while $ifa != 0
7180 if $cnt == 0
7181 if $kgm_lp64
7182 printf " in6_ifa ref hold rele\n"
7183 printf " ----------------- --- ------ ------\n"
7184 else
7185 printf " in6_ifa ref hold rele\n"
7186 printf " --------- --- ------ ------\n"
7187 end
7188 end
7189 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifa, \
7190 $ifa->in6ifa_refhold_cnt - $ifa->in6ifa_refrele_cnt, \
7191 $ifa->in6ifa_refhold_cnt, $ifa->in6ifa_refrele_cnt
7192 showsockaddr_in6 $ifa->in6ifa.ia_ifa.ifa_addr
7193 printf "\n"
7194 set $ifa = $ifa->in6ifa_trash_link.tqe_next
7195 set $cnt = $cnt + 1
7196 end
7197 end
7198
7199 set $NDPR_TRACE_HIST_SIZE = ndpr_trace_hist_size
7200
7201 define ndpr_showdbg
7202 set $ndpr = (struct nd_prefix_dbg *)$arg0
7203 set $cnt = 0
7204
7205 printf "Total references:\t%d\n", $ndpr->ndpr_refhold_cnt
7206 printf "Total releases:\t\t%d\n", $ndpr->ndpr_refrele_cnt
7207
7208 while $cnt < $NDPR_TRACE_HIST_SIZE
7209 set $ix = 0
7210 while $ix < $CTRACE_STACK_SIZE
7211 set $kgm_pc = $ndpr->ndpr_refhold[$cnt].pc[$ix]
7212 if $kgm_pc != 0
7213 if $ix == 0
7214 printf "\nHold [%d] (thread %p):\n", \
7215 $cnt, \
7216 $ndpr->ndpr_refhold[$cnt].th
7217 end
7218 printf "%4d: ", $ix + 1
7219 pcprint $kgm_pc
7220 printf "\n"
7221 end
7222 set $ix = $ix + 1
7223 end
7224 set $cnt = $cnt + 1
7225 end
7226 set $cnt = 0
7227 while $cnt < $NDPR_TRACE_HIST_SIZE
7228 set $ix = 0
7229 while $ix < $CTRACE_STACK_SIZE
7230 set $kgm_pc = $ndpr->ndpr_refrele[$cnt].pc[$ix]
7231 if $kgm_pc != 0
7232 if $ix == 0
7233 printf "\nRelease [%d] (thread %p):\n",\
7234 $cnt, \
7235 $ndpr->ndpr_refrele[$cnt].th
7236 end
7237 printf "%4d: ", $ix + 1
7238 pcprint $kgm_pc
7239 printf "\n"
7240 end
7241 set $ix = $ix + 1
7242 end
7243 set $cnt = $cnt + 1
7244 end
7245 end
7246
7247 document ndpr_showdbg
7248 Syntax: (gdb) ndpr_showdbg <addr>
7249 | Given a nd_prefix structure address, print the debug information
7250 | related to its refcnt. This requires the interface address debugging
7251 | to be turned on, by setting the appropriate flags to the "ifa_debug"
7252 | boot-args parameter.
7253 end
7254
7255 set $NDDR_TRACE_HIST_SIZE = nddr_trace_hist_size
7256
7257 define nddr_showdbg
7258 set $nddr = (struct nd_defrouter_dbg *)$arg0
7259 set $cnt = 0
7260
7261 printf "Total references:\t%d\n", $nddr->nddr_refhold_cnt
7262 printf "Total releases:\t\t%d\n", $nddr->nddr_refrele_cnt
7263
7264 while $cnt < $NDDR_TRACE_HIST_SIZE
7265 set $ix = 0
7266 while $ix < $CTRACE_STACK_SIZE
7267 set $kgm_pc = $nddr->nddr_refhold[$cnt].pc[$ix]
7268 if $kgm_pc != 0
7269 if $ix == 0
7270 printf "\nHold [%d] (thread %p):\n", \
7271 $cnt, \
7272 $nddr->nddr_refhold[$cnt].th
7273 end
7274 printf "%4d: ", $ix + 1
7275 pcprint $kgm_pc
7276 printf "\n"
7277 end
7278 set $ix = $ix + 1
7279 end
7280 set $cnt = $cnt + 1
7281 end
7282 set $cnt = 0
7283 while $cnt < $NDDR_TRACE_HIST_SIZE
7284 set $ix = 0
7285 while $ix < $CTRACE_STACK_SIZE
7286 set $kgm_pc = $nddr->nddr_refrele[$cnt].pc[$ix]
7287 if $kgm_pc != 0
7288 if $ix == 0
7289 printf "\nRelease [%d] (thread %p):\n",\
7290 $cnt, \
7291 $nddr->nddr_refrele[$cnt].th
7292 end
7293 printf "%4d: ", $ix + 1
7294 pcprint $kgm_pc
7295 printf "\n"
7296 end
7297 set $ix = $ix + 1
7298 end
7299 set $cnt = $cnt + 1
7300 end
7301 end
7302
7303 document nddr_showdbg
7304 Syntax: (gdb) nddr_showdbg <addr>
7305 | Given a nd_defrouter structure address, print the debug information
7306 | related to its refcnt. This requires the interface address debugging
7307 | to be turned on, by setting the appropriate flags to the "ifa_debug"
7308 | boot-args parameter.
7309 end
7310 set $IMO_TRACE_HIST_SIZE = imo_trace_hist_size
7311
7312 define imo_showdbg
7313 set $imo = (struct ip_moptions_dbg *)$arg0
7314 set $cnt = 0
7315
7316 printf "Total references:\t%d\n", $imo->imo_refhold_cnt
7317 printf "Total releases:\t\t%d\n", $imo->imo_refrele_cnt
7318
7319 while $cnt < $IMO_TRACE_HIST_SIZE
7320 set $ix = 0
7321 while $ix < $CTRACE_STACK_SIZE
7322 set $kgm_pc = $imo->imo_refhold[$cnt].pc[$ix]
7323 if $kgm_pc != 0
7324 if $ix == 0
7325 printf "\nHold [%d] (thread %p):\n", \
7326 $cnt, \
7327 $imo->imo_refhold[$cnt].th
7328 end
7329 printf "%4d: ", $ix + 1
7330 pcprint $kgm_pc
7331 printf "\n"
7332 end
7333 set $ix = $ix + 1
7334 end
7335 set $cnt = $cnt + 1
7336 end
7337 set $cnt = 0
7338 while $cnt < $IMO_TRACE_HIST_SIZE
7339 set $ix = 0
7340 while $ix < $CTRACE_STACK_SIZE
7341 set $kgm_pc = $imo->imo_refrele[$cnt].pc[$ix]
7342 if $kgm_pc != 0
7343 if $ix == 0
7344 printf "\nRelease [%d] (thread %p):\n",\
7345 $cnt, \
7346 $imo->imo_refrele[$cnt].th
7347 end
7348 printf "%4d: ", $ix + 1
7349 pcprint $kgm_pc
7350 printf "\n"
7351 end
7352 set $ix = $ix + 1
7353 end
7354 set $cnt = $cnt + 1
7355 end
7356 end
7357
7358 document imo_showdbg
7359 Syntax: (gdb) imo_showdbg <addr>
7360 | Given a ip_moptions structure address, print the debug information
7361 | related to its refcnt. This requires the interface address debugging
7362 | to be turned on, by setting the appropriate flags to the "ifa_debug"
7363 | boot-args parameter.
7364 end
7365
7366 set $IM6O_TRACE_HIST_SIZE = im6o_trace_hist_size
7367
7368 define im6o_showdbg
7369 set $im6o = (struct ip6_moptions_dbg *)$arg0
7370 set $cnt = 0
7371
7372 printf "Total references:\t%d\n", $im6o->im6o_refhold_cnt
7373 printf "Total releases:\t\t%d\n", $im6o->im6o_refrele_cnt
7374
7375 while $cnt < $IM6O_TRACE_HIST_SIZE
7376 set $ix = 0
7377 while $ix < $CTRACE_STACK_SIZE
7378 set $kgm_pc = $im6o->im6o_refhold[$cnt].pc[$ix]
7379 if $kgm_pc != 0
7380 if $ix == 0
7381 printf "\nHold [%d] (thread %p):\n", \
7382 $cnt, \
7383 $im6o->im6o_refhold[$cnt].th
7384 end
7385 printf "%4d: ", $ix + 1
7386 pcprint $kgm_pc
7387 printf "\n"
7388 end
7389 set $ix = $ix + 1
7390 end
7391 set $cnt = $cnt + 1
7392 end
7393 set $cnt = 0
7394 while $cnt < $IM6O_TRACE_HIST_SIZE
7395 set $ix = 0
7396 while $ix < $CTRACE_STACK_SIZE
7397 set $kgm_pc = $im6o->im6o_refrele[$cnt].pc[$ix]
7398 if $kgm_pc != 0
7399 if $ix == 0
7400 printf "\nRelease [%d] (thread %p):\n",\
7401 $cnt, \
7402 $im6o->im6o_refrele[$cnt].th
7403 end
7404 printf "%4d: ", $ix + 1
7405 pcprint $kgm_pc
7406 printf "\n"
7407 end
7408 set $ix = $ix + 1
7409 end
7410 set $cnt = $cnt + 1
7411 end
7412 end
7413
7414 document im6o_showdbg
7415 Syntax: (gdb) im6o_showdbg <addr>
7416 | Given a ip6_moptions structure address, print the debug information
7417 | related to its refcnt. This requires the interface address debugging
7418 | to be turned on, by setting the appropriate flags to the "ifa_debug"
7419 | boot-args parameter.
7420 end
7421
7422 document in6ifa_trash
7423 Syntax: (gdb) in6ifa_trash
7424 | Walk the list of trash in6_ifaddr entries; this requires interface
7425 | address debugging to be turned on, by setting the appropriate flags
7426 | to the "ifa_debug" boot-args parameter.
7427 end
7428
7429 define inifa_trash
7430 set $ifa = (struct in_ifaddr_dbg *)inifa_trash_head.tqh_first
7431 set $cnt = 0
7432 while $ifa != 0
7433 if $cnt == 0
7434 if $kgm_lp64
7435 printf " in_ifa ref hold rele\n"
7436 printf " ----------------- --- ------ ------\n"
7437 else
7438 printf " in_ifa ref hold rele\n"
7439 printf " --------- --- ------ ------\n"
7440 end
7441 end
7442 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifa, \
7443 $ifa->inifa_refhold_cnt - $ifa->inifa_refrele_cnt, \
7444 $ifa->inifa_refhold_cnt, $ifa->inifa_refrele_cnt
7445 showsockaddr_in $ifa->inifa.ia_ifa.ifa_addr
7446 printf "\n"
7447 set $ifa = $ifa->inifa_trash_link.tqe_next
7448 set $cnt = $cnt + 1
7449 end
7450 end
7451
7452 document inifa_trash
7453 Syntax: (gdb) inifa_trash
7454 | Walk the list of trash in_ifaddr entries; this requires interface
7455 | address debugging to be turned on, by setting the appropriate flags
7456 | to the "ifa_debug" boot-args parameter.
7457 end
7458
7459 define ifma_trash
7460 set $ifma = (struct ifmultiaddr_dbg *)ifma_trash_head.tqh_first
7461 set $cnt = 0
7462 while $ifma != 0
7463 if $cnt == 0
7464 if $kgm_lp64
7465 printf " ifma ref hold rele\n"
7466 printf " ----------------- --- ------ ------\n"
7467 else
7468 printf " ifma ref hold rele\n"
7469 printf " --------- --- ------ ------\n"
7470 end
7471 end
7472 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifma, \
7473 $ifma->ifma_refhold_cnt - $ifma->ifma_refrele_cnt, \
7474 $ifma->ifma_refhold_cnt, $ifma->ifma_refrele_cnt
7475 showsockaddr $ifma->ifma.ifma_addr
7476 printf " @ %s%d", $ifma->ifma.ifma_ifp->if_name, \
7477 $ifma->ifma.ifma_ifp->if_unit
7478 printf "\n"
7479 set $ifma = $ifma->ifma_trash_link.tqe_next
7480 set $cnt = $cnt + 1
7481 end
7482 end
7483
7484 document ifma_trash
7485 Syntax: (gdb) ifma_trash
7486 | Walk the list of trash ifmultiaddr entries; this requires interface
7487 | address debugging to be turned on, by setting the appropriate flags
7488 | to the "ifa_debug" boot-args parameter.
7489 end
7490
7491 define inm_trash
7492 set $inm = (struct in_multi_dbg *)inm_trash_head.tqh_first
7493 set $cnt = 0
7494 while $inm != 0
7495 if $cnt == 0
7496 if $kgm_lp64
7497 printf " inm ref hold rele\n"
7498 printf " ----------------- --- ------ ------\n"
7499 else
7500 printf " inm ref hold rele\n"
7501 printf " --------- --- ------ ------\n"
7502 end
7503 end
7504 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $inm, \
7505 $inm->inm_refhold_cnt - $inm->inm_refrele_cnt, \
7506 $inm->inm_refhold_cnt, $inm->inm_refrele_cnt
7507 show_in_addr &($inm->inm.inm_addr)
7508 printf "\n"
7509 set $inm = $inm->inm_trash_link.tqe_next
7510 set $cnt = $cnt + 1
7511 end
7512 end
7513
7514 document inm_trash
7515 Syntax: (gdb) inm_trash
7516 | Walk the list of trash in_multi entries; this requires interface
7517 | address debugging to be turned on, by setting the appropriate flags
7518 | to the "ifa_debug" boot-args parameter.
7519 end
7520
7521 define in6m_trash
7522 set $in6m = (struct in6_multi_dbg *)in6m_trash_head.tqh_first
7523 set $cnt = 0
7524 while $in6m != 0
7525 if $cnt == 0
7526 if $kgm_lp64
7527 printf " in6m ref hold rele\n"
7528 printf " ----------------- --- ------ ------\n"
7529 else
7530 printf " in6m ref hold rele\n"
7531 printf " --------- --- ------ ------\n"
7532 end
7533 end
7534 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $in6m, \
7535 $in6m->in6m_refhold_cnt - $in6m->in6m_refrele_cnt, \
7536 $in6m->in6m_refhold_cnt, $in6m->in6m_refrele_cnt
7537 show_in_addr &($in6m->in6m.in6m_addr)
7538 printf "\n"
7539 set $in6m = $in6m->in6m_trash_link.tqe_next
7540 set $cnt = $cnt + 1
7541 end
7542 end
7543
7544 document in6m_trash
7545 Syntax: (gdb) in6m_trash
7546 | Walk the list of trash in6_multi entries; this requires interface
7547 | address debugging to be turned on, by setting the appropriate flags
7548 | to the "ifa_debug" boot-args parameter.
7549 end
7550
7551 #
7552 # print all OSMalloc stats
7553
7554 define ostag_print
7555 set $kgm_tagp = (OSMallocTag)$arg0
7556 printf "0x%08x: ", $kgm_tagp
7557 printf "%8d ",$kgm_tagp->OSMT_refcnt
7558 printf "%8x ",$kgm_tagp->OSMT_state
7559 printf "%8x ",$kgm_tagp->OSMT_attr
7560 printf "%s ",$kgm_tagp->OSMT_name
7561 printf "\n"
7562 end
7563
7564
7565 define showosmalloc
7566 printf "TAG COUNT STATE ATTR NAME\n"
7567 set $kgm_tagheadp = (struct _OSMallocTag_ *)&OSMalloc_tag_list
7568 set $kgm_tagptr = (struct _OSMallocTag_ * )($kgm_tagheadp->OSMT_link.next)
7569 while $kgm_tagptr != $kgm_tagheadp
7570 ostag_print $kgm_tagptr
7571 set $kgm_tagptr = (struct _OSMallocTag_ *)$kgm_tagptr->OSMT_link.next
7572 end
7573 printf "\n"
7574 end
7575 document showosmalloc
7576 Syntax: (gdb) showosmalloc
7577 | Print the outstanding allocation count by OSMallocTags.
7578 end
7579
7580
7581 define systemlog
7582 if msgbufp->msg_bufc[msgbufp->msg_bufx] == 0 \
7583 && msgbufp->msg_bufc[0] != 0
7584 # The buffer hasn't wrapped, so take the easy (and fast!) path
7585 printf "%s", msgbufp->msg_bufc
7586 else
7587 set $kgm_msgbuf = *msgbufp
7588 set $kgm_syslog_bufsize = $kgm_msgbuf.msg_size
7589 set $kgm_syslog_bufend = $kgm_msgbuf.msg_bufx
7590 if $kgm_syslog_bufend >= $kgm_syslog_bufsize
7591 set $kgm_syslog_bufend = 0
7592 end
7593
7594 # print older messages from msg_bufx to end of buffer
7595 set $kgm_i = $kgm_syslog_bufend
7596 while $kgm_i < $kgm_syslog_bufsize
7597 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
7598 if $kgm_syslog_char == 0
7599 # break out of loop
7600 set $kgm_i = $kgm_syslog_bufsize
7601 else
7602 printf "%c", $kgm_syslog_char
7603 end
7604 set $kgm_i = $kgm_i + 1
7605 end
7606
7607 # print newer messages from start of buffer to msg_bufx
7608 set $kgm_i = 0
7609 while $kgm_i < $kgm_syslog_bufend
7610 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
7611 if $kgm_syslog_char != 0
7612 printf "%c", $kgm_syslog_char
7613 end
7614 set $kgm_i = $kgm_i + 1
7615 end
7616 end
7617 printf "\n"
7618 end
7619 document systemlog
7620 | Syntax: systemlog
7621 | Display the kernel's printf ring buffer
7622 end
7623
7624
7625 define hexdump
7626 set $kgm_addr = (unsigned char *)$arg0
7627 set $kgm_len = $arg1
7628 while $kgm_len > 0
7629 showptr $kgm_addr
7630 printf ": "
7631 set $kgm_i = 0
7632 while $kgm_i < 16
7633 printf "%02x ", *($kgm_addr+$kgm_i)
7634 set $kgm_i += 1
7635 end
7636 printf " |"
7637 set $kgm_i = 0
7638 while $kgm_i < 16
7639 set $kgm_temp = *($kgm_addr+$kgm_i)
7640 if $kgm_temp < 32 || $kgm_temp >= 127
7641 printf "."
7642 else
7643 printf "%c", $kgm_temp
7644 end
7645 set $kgm_i += 1
7646 end
7647 printf "|\n"
7648 set $kgm_addr += 16
7649 set $kgm_len -= 16
7650 end
7651 end
7652 document hexdump
7653 | Show the contents of memory as a hex/ASCII dump
7654 | The following is the syntax:
7655 | (gdb) hexdump <address> <length>
7656 end
7657
7658
7659 define printcolonhex
7660 if ($argc == 2)
7661 set $addr = $arg0
7662 set $count = $arg1
7663 set $li = 0
7664 while ($li < $count)
7665 if ($li == 0)
7666 printf "%02x", (u_char)$addr[$li]
7667 end
7668 if ($li != 0)
7669 printf ":%02x", (u_char)$addr[$li]
7670 end
7671 set $li = $li + 1
7672 end
7673 end
7674 end
7675
7676 define showsockaddr_dl
7677 set $sdl = (struct sockaddr_dl *)$arg0
7678 if ($sdl == 0)
7679 printf "(null) "
7680 else
7681 if $sdl->sdl_nlen == 0 && $sdl->sdl_alen == 0 && $sdl->sdl_slen == 0
7682 printf "link#%3d ", $sdl->sdl_index
7683 else
7684 set $addr = $sdl->sdl_data + $sdl->sdl_nlen
7685 set $count = $sdl->sdl_alen
7686 printcolonhex $addr $count
7687 end
7688 end
7689 end
7690
7691 define showsockaddr_unspec
7692 set $sockaddr = (struct sockaddr *)$arg0
7693 set $addr = $sockaddr->sa_data
7694 set $count = $sockaddr->sa_len - 2
7695 printcolonhex $addr $count
7696 end
7697
7698 define showsockaddr_at
7699 set $sockaddr = (struct sockaddr *)$arg0
7700 set $addr = $sockaddr->sa_data
7701 set $count = $sockaddr->sa_len - 2
7702 printcolonhex $addr $count
7703 end
7704
7705 define show_in_addr
7706 set $ia = (unsigned char *)$arg0
7707 printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
7708 end
7709
7710 define showsockaddr_in
7711 set $sin = (struct sockaddr_in *)$arg0
7712 set $sa_bytes = (unsigned char *)&($sin->sin_addr)
7713 show_in_addr $sa_bytes
7714 end
7715
7716 define show_in6_addr
7717 set $ia = (unsigned char *)$arg0
7718 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
7719 $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
7720 end
7721
7722 define showsockaddr_in6
7723 set $sin6 = (struct sockaddr_in6 *)$arg0
7724 set $sa_bytes = $sin6->sin6_addr.__u6_addr.__u6_addr8
7725 show_in6_addr $sa_bytes
7726 end
7727
7728 define showsockaddr_un
7729 set $sun = (struct sockaddr_un *)$arg0
7730 if $sun == 0
7731 printf "(null)"
7732 else
7733 if $sun->sun_path[0] == 0
7734 printf "\"\""
7735 else
7736 printf "%s", $sun->sun_path
7737 end
7738 end
7739 end
7740
7741 define showifmultiaddrs
7742 set $ifp = (struct ifnet *)$arg0
7743 set $if_multi = (struct ifmultiaddr *)$ifp->if_multiaddrs->lh_first
7744 set $mymulti = $if_multi
7745 set $myi = 0
7746 while ($mymulti != 0)
7747 printf "%2d. %p ", $myi, $mymulti
7748 set $sa_family = $mymulti->ifma_addr.sa_family
7749 if ($sa_family == 2)
7750 if ($mymulti->ifma_ll != 0)
7751 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
7752 printf " "
7753 end
7754 showsockaddr_in $mymulti->ifma_addr
7755 end
7756 if ($sa_family == 30)
7757 if ($mymulti->ifma_ll != 0)
7758 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
7759 printf " "
7760 end
7761 showsockaddr_in6 $mymulti->ifma_addr
7762 end
7763 if ($sa_family == 18)
7764 showsockaddr_dl $mymulti->ifma_addr
7765 end
7766 if ($sa_family == 0)
7767 showsockaddr_unspec $mymulti->ifma_addr 6
7768 end
7769 printf " [%d]", $mymulti->ifma_refcount
7770 printf "\n"
7771 set $mymulti = $mymulti->ifma_link.le_next
7772 set $myi = $myi + 1
7773 end
7774 end
7775
7776 document showifmultiaddrs
7777 Syntax showifmultiaddrs <ifp>
7778 | show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
7779 end
7780
7781 define showinmultiaddrs
7782 set $in_multi = (struct in_multi *)(in_multihead->lh_first)
7783 set $mymulti = $in_multi
7784 set $myi = 0
7785 while ($mymulti != 0)
7786 set $ifp = (struct ifnet *)$mymulti->inm_ifp
7787 printf "%2d. %p ", $myi, $mymulti
7788 show_in_addr &($mymulti->inm_addr)
7789 printf " (ifp %p [%s%d] ifma %p) ", $ifp, $ifp->if_name, \
7790 $ifp->if_unit, $mymulti->inm_ifma
7791 printf "\n"
7792 set $mymulti = $mymulti->inm_link.le_next
7793 set $myi = $myi + 1
7794 end
7795 end
7796
7797 document showinmultiaddrs
7798 Syntax showinmultiaddrs
7799 | show the contents of IPv4 multicast address records
7800 end
7801
7802 define showin6multiaddrs
7803 set $in6_multi = (struct in6_multi *)(in6_multihead->lh_first)
7804 set $mymulti = $in6_multi
7805 set $myi = 0
7806 while ($mymulti != 0)
7807 set $ifp = (struct ifnet *)$mymulti->in6m_ifp
7808 printf "%2d. %p ", $myi, $mymulti
7809 show_in6_addr &($mymulti->in6m_addr)
7810 printf " (ifp %p [%s%d] ifma %p) ", $ifp, $ifp->if_name, \
7811 $ifp->if_unit, $mymulti->in6m_ifma
7812 printf "\n"
7813 set $mymulti = $mymulti->in6m_entry.le_next
7814 set $myi = $myi + 1
7815 end
7816 end
7817
7818 document showin6multiaddrs
7819 Syntax showin6multiaddrs
7820 | show the contents of IPv6 multicast address records
7821 end
7822
7823 define showsockaddr
7824 set $mysock = (struct sockaddr *)$arg0
7825 set $showsockaddr_handled = 0
7826 if ($mysock == 0)
7827 printf "(null)"
7828 else
7829 if ($mysock->sa_family == 0)
7830 printf "UNSPC"
7831 showsockaddr_unspec $mysock
7832 set $showsockaddr_handled = 1
7833 end
7834 if ($mysock->sa_family == 1)
7835 printf "UNIX "
7836 showsockaddr_un $mysock
7837 set $showsockaddr_handled = 1
7838 end
7839 if ($mysock->sa_family == 2)
7840 printf "INET "
7841 showsockaddr_in $mysock
7842 set $showsockaddr_handled = 1
7843 end
7844 if ($mysock->sa_family == 30)
7845 printf "INET6 "
7846 showsockaddr_in6 $mysock
7847 set $showsockaddr_handled = 1
7848 end
7849 if ($mysock->sa_family == 18)
7850 printf "LINK "
7851 showsockaddr_dl $mysock
7852 set $showsockaddr_handled = 1
7853 end
7854 if ($mysock->sa_family == 16)
7855 printf "ATLK "
7856 showsockaddr_at $mysock
7857 set $showsockaddr_handled = 1
7858 end
7859 if ($showsockaddr_handled == 0)
7860 printf "FAM %d ", $mysock->sa_family
7861 set $addr = $mysock->sa_data
7862 set $count = $mysock->sa_len
7863 printcolonhex $addr $count
7864 end
7865 end
7866 end
7867
7868 define showifflags
7869 set $flags = (u_short)$arg0
7870 set $first = 1
7871 printf "<"
7872 if ($flags & 0x1)
7873 printf "UP"
7874 set $first = 0
7875 end
7876 if ($flags & 0x2)
7877 if ($first == 1)
7878 set $first = 0
7879 else
7880 printf ","
7881 end
7882 printf "BROADCAST"
7883 end
7884 if ($flags & 0x4)
7885 printf "DEBUG"
7886 end
7887 if ($flags & 0x8)
7888 if ($first == 1)
7889 set $first = 0
7890 else
7891 printf ","
7892 end
7893 printf "LOOPBACK"
7894 end
7895 if ($flags & 0x10)
7896 if ($first == 1)
7897 set $first = 0
7898 else
7899 printf ","
7900 end
7901 printf "POINTTOPOINT"
7902 end
7903 ## if ($flags & 0x20)
7904 ## if ($first == 1)
7905 # set $first = 0
7906 ## else
7907 # printf ","
7908 # end
7909 # printf "NOTRAILERS"
7910 # end
7911 if ($flags & 0x40)
7912 if ($first == 1)
7913 set $first = 0
7914 else
7915 printf ","
7916 end
7917 printf "RUNNING"
7918 end
7919 if ($flags & 0x80)
7920 if ($first == 1)
7921 set $first = 0
7922 else
7923 printf ","
7924 end
7925 printf "NOARP"
7926 end
7927 if ($flags & 0x100)
7928 if ($first == 1)
7929 set $first = 0
7930 else
7931 printf ","
7932 end
7933 printf "PROMISC"
7934 end
7935 if ($flags & 0x200)
7936 if ($first == 1)
7937 set $first = 0
7938 else
7939 printf ","
7940 end
7941 printf "ALLMULTI"
7942 end
7943 if ($flags & 0x400)
7944 if ($first == 1)
7945 set $first = 0
7946 else
7947 printf ","
7948 end
7949 printf "OACTIVE"
7950 end
7951 if ($flags & 0x800)
7952 if ($first == 1)
7953 set $first = 0
7954 else
7955 printf ","
7956 end
7957 printf "SIMPLEX"
7958 end
7959 if ($flags & 0x1000)
7960 if ($first == 1)
7961 set $first = 0
7962 else
7963 printf ","
7964 end
7965 printf "LINK0"
7966 end
7967 if ($flags & 0x2000)
7968 if ($first == 1)
7969 set $first = 0
7970 else
7971 printf ","
7972 end
7973 printf "LINK1"
7974 end
7975 if ($flags & 0x4000)
7976 if ($first == 1)
7977 set $first = 0
7978 else
7979 printf ","
7980 end
7981 printf "LINK2-ALTPHYS"
7982 end
7983 if ($flags & 0x8000)
7984 if ($first == 1)
7985 set $first = 0
7986 else
7987 printf ","
7988 end
7989 printf "MULTICAST"
7990 end
7991 printf ">"
7992 end
7993
7994 define showifaddrs
7995 set $ifp = (struct ifnet *)$arg0
7996 set $myifaddr = (struct ifaddr *)$ifp->if_addrhead->tqh_first
7997 set $myi = 0
7998 while ($myifaddr != 0)
7999 printf "\t%d. %p ", $myi, $myifaddr
8000 showsockaddr $myifaddr->ifa_addr
8001 printf " [%d]\n", $myifaddr->ifa_refcnt
8002 set $myifaddr = $myifaddr->ifa_link->tqe_next
8003 set $myi = $myi + 1
8004 end
8005 end
8006
8007 document showifaddrs
8008 Syntax: showifaddrs <ifp>
8009 | show the (struct ifnet).if_addrhead list of addresses for the given ifp
8010 end
8011
8012 define ifconfig
8013 set $ifconfig_all = 0
8014 if ($argc == 1)
8015 set $ifconfig_all = 1
8016 end
8017 set $ifp = (struct ifnet *)(ifnet_head->tqh_first)
8018 while ($ifp != 0)
8019 printf "%s%d: flags=%hx", $ifp->if_name, $ifp->if_unit, (u_short)$ifp->if_flags
8020 showifflags $ifp->if_flags
8021 printf " index %d", $ifp->if_index
8022 printf " mtu %d\n", $ifp->if_data.ifi_mtu
8023 printf "\t(struct ifnet *)"
8024 showptr $ifp
8025 printf "\n"
8026 if ($ifconfig_all == 1)
8027 showifaddrs $ifp
8028 end
8029 set $ifp = $ifp->if_link->tqe_next
8030 end
8031 end
8032 document ifconfig
8033 Syntax: (gdb) ifconfig
8034 | display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
8035 end
8036
8037 set $DLIF_INUSE = 0x1
8038 set $DLIF_REUSE = 0x2
8039
8040 define showifnets
8041 set $all = 0
8042 if ($argc == 1)
8043 set $all = 1
8044 end
8045 set $dlifp = (struct dlil_ifnet *)(dlil_ifnet_head->tqh_first)
8046 while ($dlifp != 0)
8047 set $ifp = (struct ifnet *)$dlifp
8048 if ($dlifp->dl_if_flags & $DLIF_REUSE)
8049 printf "*"
8050 end
8051 if ($dlifp->dl_if_flags & $DLIF_INUSE)
8052 printf "%s%d: ", $ifp->if_name, $ifp->if_unit
8053 else
8054 printf "[%s%d]: ", $ifp->if_name, $ifp->if_unit
8055 end
8056 printf "flags=%hx", (u_short)$ifp->if_flags
8057 showifflags $ifp->if_flags
8058 printf " index %d", $ifp->if_index
8059 printf " mtu %d\n", $ifp->if_data.ifi_mtu
8060 printf "\t(struct ifnet *)"
8061 showptr $ifp
8062 printf "\n"
8063 if ($all == 1)
8064 showifaddrs $ifp
8065 end
8066 set $dlifp = $dlifp->dl_if_link->tqe_next
8067 end
8068 end
8069
8070 document showifnets
8071 Syntax: (gdb) showifnets
8072 | Display ifconfig-like output for all attached and detached interfaces
8073 end
8074
8075 define _show_unix_domain_socket
8076 set $so = (struct socket *)$arg0
8077 set $pcb = (struct unpcb *)$so->so_pcb
8078 if $pcb == 0
8079 printf "unpcb: (null) "
8080 else
8081 printf "unpcb: %p ", $pcb
8082 printf "unp_vnode: %p ", $pcb->unp_vnode
8083 printf "unp_conn: %p ", $pcb->unp_conn
8084 printf "unp_addr: "
8085 showsockaddr_un $pcb->unp_addr
8086 end
8087 end
8088
8089 define _show_in_port
8090 set $str = (unsigned char *)$arg0
8091 set $port = *(unsigned short *)$arg0
8092
8093 if (((($port & 0xff00) >> 8) == $str[0])) && ((($port & 0x00ff) == $str[1]))
8094 #printf "big endian "
8095 printf ":%d ", $port
8096 else
8097 #printf "little endian "
8098 printf ":%d ", (($port & 0xff00) >> 8) | (($port & 0x00ff) << 8)
8099 end
8100 end
8101
8102 define _show_in_addr_4in6
8103 set $ia = (unsigned char *)$arg0
8104 if $ia
8105 printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
8106 end
8107 end
8108
8109 define _show_in6_addr
8110 set $ia = (unsigned char *)$arg0
8111 if $ia
8112 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
8113 $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], \
8114 $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
8115 end
8116 end
8117
8118 define _showtcpstate
8119 set $tp = (struct tcpcb *)$arg0
8120 if $tp
8121 if $tp->t_state == 0
8122 printf "CLOSED "
8123 end
8124 if $tp->t_state == 1
8125 printf "LISTEN "
8126 end
8127 if $tp->t_state == 2
8128 printf "SYN_SENT "
8129 end
8130 if $tp->t_state == 3
8131 printf "SYN_RCVD "
8132 end
8133 if $tp->t_state == 4
8134 printf "ESTABLISHED "
8135 end
8136 if $tp->t_state == 5
8137 printf "CLOSE_WAIT "
8138 end
8139 if $tp->t_state == 6
8140 printf "FIN_WAIT_1 "
8141 end
8142 if $tp->t_state == 7
8143 printf "CLOSING "
8144 end
8145 if $tp->t_state == 8
8146 printf "LAST_ACK "
8147 end
8148 if $tp->t_state == 9
8149 printf "FIN_WAIT_2 "
8150 end
8151 if $tp->t_state == 10
8152 printf "TIME_WAIT "
8153 end
8154 end
8155 end
8156
8157 define _showsockprotocol
8158 set $so = (struct socket *)$arg0
8159 set $inpcb = (struct inpcb *)$so->so_pcb
8160
8161 if $so->so_proto->pr_protocol == 6
8162 printf "TCP "
8163 _showtcpstate $inpcb->inp_ppcb
8164 end
8165 if $so->so_proto->pr_protocol == 17
8166 printf "UDP "
8167 end
8168 if $so->so_proto->pr_protocol == 1
8169 printf "ICMP "
8170 end
8171 if $so->so_proto->pr_protocol == 254
8172 printf "DIVERT "
8173 end
8174 if $so->so_proto->pr_protocol == 255
8175 printf "RAW "
8176 end
8177 end
8178
8179 define _show_ipv4_socket
8180 set $so = (struct socket *)$arg0
8181 set $inpcb = (struct inpcb *)$so->so_pcb
8182 if $inpcb == 0
8183 printf "inpcb: (null) "
8184 else
8185 printf "inpcb: %p ", $inpcb
8186
8187 _showsockprotocol $so
8188
8189 _show_in_addr_4in6 &$inpcb->inp_dependladdr.inp46_local
8190 _show_in_port &$inpcb->inp_lport
8191 printf "-> "
8192 _show_in_addr_4in6 &$inpcb->inp_dependfaddr.inp46_foreign
8193 _show_in_port &$inpcb->inp_fport
8194 end
8195 end
8196
8197 define _show_ipv6_socket
8198 set $so = (struct socket *)$arg0
8199 set $pcb = (struct inpcb *)$so->so_pcb
8200 if $pcb == 0
8201 printf "inpcb: (null) "
8202 else
8203 printf "inpcb: %p ", $pcb
8204
8205 _showsockprotocol $so
8206
8207 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
8208 _show_in_port &$pcb->inp_lport
8209 printf "-> "
8210 _show_in6_addr &$pcb->inp_dependfaddr.inp6_foreign
8211 _show_in_port &$pcb->inp_fport
8212 end
8213 end
8214
8215
8216 define showsocket
8217 set $so = (struct socket *)$arg0
8218 if $so == 0
8219 printf "so: (null) "
8220 else
8221 printf "so: %p ", $so
8222 if $so && $so->so_proto && $so->so_proto->pr_domain
8223 set $domain = (struct domain *) $so->so_proto->pr_domain
8224
8225 printf "%s ", $domain->dom_name
8226 if $domain->dom_family == 1
8227 _show_unix_domain_socket $so
8228 end
8229 if $domain->dom_family == 2
8230 _show_ipv4_socket $so
8231 end
8232 if $domain->dom_family == 30
8233 _show_ipv6_socket $so
8234 end
8235 end
8236 end
8237 printf "\n"
8238 end
8239 document showsocket
8240 Syntax: (gdb) showsocket <socket_address>
8241 | Routine to print out a socket
8242 end
8243
8244 define showprocsockets
8245 set $pp = (struct proc *)$arg0
8246 set $fdp = (struct filedesc *)$pp->p_fd
8247
8248 set $count = 0
8249 set $fpp = (struct fileproc **)($fdp->fd_ofiles)
8250 set $fpo = (char)($fdp->fd_ofileflags[0])
8251 while $count < $fdp->fd_nfiles
8252 if *$fpp
8253 set $fg =(struct fileglob *)((**$fpp)->f_fglob)
8254 if $fg && (($fg)->fg_type == 2)
8255 if $fdp->fd_ofileflags[$count] & 4
8256 printf "U: "
8257 else
8258 printf " "
8259 end
8260 printf "fd = %d ", $count
8261 if $fg->fg_data
8262 showsocket $fg->fg_data
8263 else
8264 printf "\n"
8265 end
8266 end
8267 end
8268 set $fpp = $fpp + 1
8269 set $count = $count + 1
8270 end
8271 end
8272 document showprocsockets
8273 Syntax: (gdb) showprocsockets <proc_address>
8274 | Routine to print out all the open fds
8275 | which are sockets in a process
8276 end
8277
8278 define showallprocsockets
8279 set $basep = (struct proc *)allproc->lh_first
8280 set $pp = $basep
8281 while $pp
8282 printf "============================================ \n"
8283 showproc $pp
8284 showprocsockets $pp
8285 set $pp = $pp->p_list.le_next
8286 end
8287 end
8288 document showallprocsockets
8289 Syntax: (gdb) showallprocsockets
8290 | Routine to print out all the open fds
8291 | which are sockets
8292 end
8293
8294 define _print_ntohs
8295 set $port = (unsigned short)$arg0
8296 set $port = (unsigned short)((($arg0 & 0xff00) >> 8) & 0xff)
8297 set $port |= (unsigned short)(($arg0 & 0xff) << 8)
8298 printf "%5d", $port
8299 end
8300
8301 set $INPCB_STATE_INUSE=0x1
8302 set $INPCB_STATE_CACHED=0x2
8303 set $INPCB_STATE_DEAD=0x3
8304
8305 set $INP_RECVOPTS=0x01
8306 set $INP_RECVRETOPTS=0x02
8307 set $INP_RECVDSTADDR=0x04
8308 set $INP_HDRINCL=0x08
8309 set $INP_HIGHPORT=0x10
8310 set $INP_LOWPORT=0x20
8311 set $INP_ANONPORT=0x40
8312 set $INP_RECVIF=0x80
8313 set $INP_MTUDISC=0x100
8314 set $INP_STRIPHDR=0x200
8315 set $INP_FAITH=0x400
8316 set $INP_INADDR_ANY=0x800
8317 set $INP_RECVTTL=0x1000
8318 set $INP_UDP_NOCKSUM=0x2000
8319 set $IN6P_IPV6_V6ONLY=0x008000
8320 set $IN6P_PKTINFO=0x010000
8321 set $IN6P_HOPLIMIT=0x020000
8322 set $IN6P_HOPOPTS=0x040000
8323 set $IN6P_DSTOPTS=0x080000
8324 set $IN6P_RTHDR=0x100000
8325 set $IN6P_RTHDRDSTOPTS=0x200000
8326 set $IN6P_AUTOFLOWLABEL=0x800000
8327 set $IN6P_BINDV6ONLY=0x10000000
8328
8329 set $INP_IPV4=0x1
8330 set $INP_IPV6=0x2
8331
8332 set $IPPROTO_TCP=6
8333 set $IPPROTO_UDP=17
8334
8335 define _dump_inpcb
8336 set $pcb = (struct inpcb *)$arg0
8337 if $kgm_lp64
8338 printf "%18p", $pcb
8339 else
8340 printf "%10p ", $pcb
8341 end
8342 if $arg1 == $IPPROTO_TCP
8343 printf "tcp"
8344 else
8345 if $arg1 == $IPPROTO_UDP
8346 printf "udp"
8347 else
8348 printf "%2d.", $arg1
8349 end
8350 end
8351 if ($pcb->inp_vflag & $INP_IPV4)
8352 printf "4 "
8353 end
8354 if ($pcb->inp_vflag & $INP_IPV6)
8355 printf "6 "
8356 end
8357
8358 if ($pcb->inp_vflag & $INP_IPV4)
8359 printf " "
8360 _show_in_addr &$pcb->inp_dependladdr.inp46_local.ia46_addr4
8361 else
8362 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
8363 end
8364 printf " "
8365 _print_ntohs $pcb->inp_lport
8366 printf " "
8367 if ($pcb->inp_vflag & $INP_IPV4)
8368 printf " "
8369 _show_in_addr &($pcb->inp_dependfaddr.inp46_foreign.ia46_addr4)
8370 else
8371 _show_in6_addr &($pcb->inp_dependfaddr.inp6_foreign)
8372 end
8373 printf " "
8374 _print_ntohs $pcb->inp_fport
8375 printf " "
8376
8377 if $arg1 == $IPPROTO_TCP
8378 _showtcpstate $pcb->inp_ppcb
8379 end
8380
8381 # printf "phd "
8382 # set $phd = $pcb->inp_phd
8383 # while $phd != 0
8384 # printf " "
8385 # _print_ntohs $phd->phd_port
8386 # set $phd = $phd->phd_hash.le_next
8387 # end
8388 # printf ", "
8389 if ($pcb->inp_flags & $INP_RECVOPTS)
8390 printf "recvopts "
8391 end
8392 if ($pcb->inp_flags & $INP_RECVRETOPTS)
8393 printf "recvretopts "
8394 end
8395 if ($pcb->inp_flags & $INP_RECVDSTADDR)
8396 printf "recvdstaddr "
8397 end
8398 if ($pcb->inp_flags & $INP_HDRINCL)
8399 printf "hdrincl "
8400 end
8401 if ($pcb->inp_flags & $INP_HIGHPORT)
8402 printf "highport "
8403 end
8404 if ($pcb->inp_flags & $INP_LOWPORT)
8405 printf "lowport "
8406 end
8407 if ($pcb->inp_flags & $INP_ANONPORT)
8408 printf "anonport "
8409 end
8410 if ($pcb->inp_flags & $INP_RECVIF)
8411 printf "recvif "
8412 end
8413 if ($pcb->inp_flags & $INP_MTUDISC)
8414 printf "mtudisc "
8415 end
8416 if ($pcb->inp_flags & $INP_STRIPHDR)
8417 printf "striphdr "
8418 end
8419 if ($pcb->inp_flags & $INP_FAITH)
8420 printf "faith "
8421 end
8422 if ($pcb->inp_flags & $INP_INADDR_ANY)
8423 printf "inaddr_any "
8424 end
8425 if ($pcb->inp_flags & $INP_RECVTTL)
8426 printf "recvttl "
8427 end
8428 if ($pcb->inp_flags & $INP_UDP_NOCKSUM)
8429 printf "nocksum "
8430 end
8431 if ($pcb->inp_flags & $IN6P_IPV6_V6ONLY)
8432 printf "v6only "
8433 end
8434 if ($pcb->inp_flags & $IN6P_PKTINFO)
8435 printf "pktinfo "
8436 end
8437 if ($pcb->inp_flags & $IN6P_HOPLIMIT)
8438 printf "hoplimit "
8439 end
8440 if ($pcb->inp_flags & $IN6P_HOPOPTS)
8441 printf "hopopts "
8442 end
8443 if ($pcb->inp_flags & $IN6P_DSTOPTS)
8444 printf "dstopts "
8445 end
8446 if ($pcb->inp_flags & $IN6P_RTHDR)
8447 printf "rthdr "
8448 end
8449 if ($pcb->inp_flags & $IN6P_RTHDRDSTOPTS)
8450 printf "rthdrdstopts "
8451 end
8452 if ($pcb->inp_flags & $IN6P_AUTOFLOWLABEL)
8453 printf "autoflowlabel "
8454 end
8455 if ($pcb->inp_flags & $IN6P_BINDV6ONLY)
8456 printf "bindv6only "
8457 end
8458 set $so = (struct socket *)$pcb->inp_socket
8459 if $so != 0
8460 printf "[so=%p s=%ld r=%ld usecnt=%ld] ", $so, $so->so_snd.sb_cc, \
8461 $so->so_rcv.sb_cc, $so->so_usecount
8462 end
8463 if ($pcb->inp_state == 0 || $pcb->inp_state == $INPCB_STATE_INUSE)
8464 printf "inuse, "
8465 else
8466 if ($pcb->inp_state == $INPCB_STATE_CACHED)
8467 printf "cached, "
8468 else
8469 if ($pcb->inp_state == $INPCB_STATE_DEAD)
8470 printf "dead, "
8471 else
8472 printf "unknown (%d), ", $pcb->inp_state
8473 end
8474 end
8475 end
8476 end
8477
8478 define _dump_inpcbport
8479 set $ppcb = (struct inpcbport *)$arg0
8480 printf "%p: lport ", $ppcb
8481 _print_ntohs $ppcb->phd_port
8482 end
8483
8484 set $UDBHASHSIZE=16
8485
8486 define _dump_pcbinfo
8487 set $snd_cc = 0
8488 set $snd_buf = (unsigned int)0
8489 set $rcv_cc = 0
8490 set $rcv_buf = (unsigned int)0
8491 set $pcbseen = 0
8492 set $pcbi = (struct inpcbinfo *)$arg0
8493 printf "lastport %d lastlow %d lasthi %d\n", \
8494 $pcbi->lastport, $pcbi->lastlow, $pcbi->lasthi
8495 printf "active pcb count is %d\n", $pcbi->ipi_count
8496 set $hashsize = $pcbi->hashmask + 1
8497 printf "hash size is %d\n", $hashsize
8498 printf "hash base %p has the following inpcb(s):\n", $pcbi->hashbase
8499 if $kgm_lp64
8500 printf "pcb prot source address port destination address port\n"
8501 printf "------------------ ---- --------------------------------------- ----- --------------------------------------- -----\n"
8502 else
8503 printf "pcb prot source address port destination address port\n"
8504 printf "---------- ---- --------------------------------------- ----- --------------------------------------- -----\n"
8505 end
8506 set $i = 0
8507 set $hashbase = $pcbi->hashbase
8508 set $head = *(uintptr_t *)$hashbase
8509 while $i < $hashsize
8510 if $head != 0
8511 set $pcb0 = (struct inpcb *)$head
8512 while $pcb0 != 0
8513 set $pcbseen += 1
8514 _dump_inpcb $pcb0 $arg1
8515 set $so = (struct socket *)$pcb->inp_socket
8516 if $so != 0
8517 set $snd_cc += $so->so_snd.sb_cc
8518 set $mp = $so->so_snd.sb_mb
8519 while $mp
8520 set $snd_buf += 256
8521 if ($mp->m_hdr.mh_flags & 0x01)
8522 set $snd_buf += $mp->M_dat.MH.MH_dat.MH_ext.ext_size
8523 end
8524 set $mp = $mp->m_hdr.mh_next
8525 end
8526 set $rcv_cc += $so->so_rcv.sb_cc
8527 set $mp = $so->so_rcv.sb_mb
8528 while $mp
8529 set $rcv_buf += 256
8530 if ($mp->m_hdr.mh_flags & 0x01)
8531 set $rcv_buf += $mp->M_dat.MH.MH_dat.MH_ext.ext_size
8532 end
8533 set $mp = $mp->m_hdr.mh_next
8534 end
8535 end
8536 set $pcb0 = $pcb0->inp_hash.le_next
8537 printf "\n"
8538 end
8539 end
8540 set $i += 1
8541 set $hashbase += 1
8542 set $head = *(uintptr_t *)$hashbase
8543 end
8544 printf "total seen %ld snd_cc %ld rcv_cc %ld\n", $pcbseen, $snd_cc, $rcv_cc
8545 printf "total snd_buf %u rcv_buf %u \n", (unsigned int)$snd_buf, (unsigned int)$rcv_buf
8546 printf "port hash base is %p\n", $pcbi->porthashbase
8547 set $i = 0
8548 set $hashbase = $pcbi->porthashbase
8549 set $head = *(uintptr_t *)$hashbase
8550 while $i < $hashsize
8551 if $head != 0
8552 set $pcb0 = (struct inpcbport *)$head
8553 while $pcb0 != 0
8554 printf "\t"
8555 _dump_inpcbport $pcb0
8556 printf "\n"
8557 set $pcb0 = $pcb0->phd_hash.le_next
8558 end
8559 end
8560 set $i += 1
8561 set $hashbase += 1
8562 set $head = *(uintptr_t *)$hashbase
8563 end
8564 end
8565
8566 set $N_TIME_WAIT_SLOTS=128
8567
8568 define show_tcp_timewaitslots
8569 set $slot = -1
8570 set $all = 0
8571 if $argc == 1
8572 if (int)$arg0 == -1
8573 set $all = 1
8574 else
8575 set $slot = (int)$arg0
8576 end
8577 end
8578 printf "time wait slot size %d cur_tw_slot %ld\n", $N_TIME_WAIT_SLOTS, cur_tw_slot
8579 set $i = 0
8580 while $i < $N_TIME_WAIT_SLOTS
8581 set $perslot = 0
8582 set $head = (uintptr_t *)time_wait_slots[$i]
8583 if $i == $slot || $slot == -1
8584 if $head != 0
8585 set $pcb0 = (struct inpcb *)$head
8586 while $pcb0 != 0
8587 set $perslot += 1
8588 set $pcb0 = $pcb0->inp_list.le_next
8589 end
8590 end
8591 printf " slot %ld count %ld\n", $i, $perslot
8592 end
8593 if $all || $i == $slot
8594 if $head != 0
8595 set $pcb0 = (struct inpcb *)$head
8596 while $pcb0 != 0
8597 printf "\t"
8598 _dump_inpcb $pcb0 $IPPROTO_TCP
8599 printf "\n"
8600 set $pcb0 = $pcb0->inp_list.le_next
8601 end
8602 end
8603 end
8604 set $i += 1
8605 end
8606 end
8607 document show_tcp_timewaitslots
8608 Syntax: (gdb) show_tcp_timewaitslots
8609 | Print the list of TCP protocol control block in the TIMEWAIT state
8610 | Pass -1 to see the list of PCB for each slot
8611 | Pass a slot number to see information for that slot with the list of PCB
8612 end
8613
8614 define show_tcp_pcbinfo
8615 _dump_pcbinfo &tcbinfo $IPPROTO_TCP
8616 end
8617 document show_tcp_pcbinfo
8618 Syntax: (gdb) show_tcp_pcbinfo
8619 | Print the list of TCP protocol control block information
8620 end
8621
8622
8623 define show_udp_pcbinfo
8624 _dump_pcbinfo &udbinfo $IPPROTO_UDP
8625 end
8626 document show_udp_pcbinfo
8627 Syntax: (gdb) show_udp_pcbinfo
8628 | Print the list of UDP protocol control block information
8629 end
8630
8631 define showbpfdtab
8632 set $myi = 0
8633 while ($myi < bpf_dtab_size)
8634 if (bpf_dtab[$myi] != 0)
8635 printf "Address 0x%x, bd_next 0x%x\n", bpf_dtab[$myi], bpf_dtab[$myi]->bd_next
8636 print *bpf_dtab[$myi]
8637 end
8638 set $myi = $myi + 1
8639 end
8640 end
8641
8642 define printvnodepathint_recur
8643 if $arg0 != 0
8644 if ($arg0->v_flag & 0x000001) && ($arg0->v_mount != 0)
8645 if $arg0->v_mount->mnt_vnodecovered != 0
8646 printvnodepathint_recur $arg0->v_mount->mnt_vnodecovered $arg0->v_mount->mnt_vnodecovered->v_name
8647 end
8648 else
8649 printvnodepathint_recur $arg0->v_parent $arg0->v_parent->v_name
8650 printf "/%s", $arg1
8651 end
8652 end
8653 end
8654
8655 define showvnodepath
8656 set $vp = (struct vnode *)$arg0
8657 if $vp != 0
8658 if ($vp->v_flag & 0x000001) && ($vp->v_mount != 0) && ($vp->v_mount->mnt_flag & 0x00004000)
8659 printf "/"
8660 else
8661 printvnodepathint_recur $vp $vp->v_name
8662 end
8663 end
8664 printf "\n"
8665 end
8666
8667 document showvnodepath
8668 Syntax: (gdb) showvnodepath <vnode>
8669 | Prints the path for a vnode
8670 end
8671
8672 define showallvols
8673 printf "volume "
8674 showptrhdrpad
8675 printf " mnt_data "
8676 showptrhdrpad
8677 printf " mnt_devvp "
8678 showptrhdrpad
8679 printf " typename mountpoint\n"
8680 set $kgm_vol = (mount_t) mountlist.tqh_first
8681 while $kgm_vol
8682 showptr $kgm_vol
8683 printf " "
8684 showptr $kgm_vol->mnt_data
8685 printf " "
8686 showptr $kgm_vol->mnt_devvp
8687 printf " "
8688 if ($kgm_vol->mnt_vtable->vfc_name[0] == 'h') && \
8689 ($kgm_vol->mnt_vtable->vfc_name[1] == 'f') && \
8690 ($kgm_vol->mnt_vtable->vfc_name[2] == 's') && \
8691 ($kgm_vol->mnt_vtable->vfc_name[3] == '\0')
8692 set $kgm_hfsmount = \
8693 (struct hfsmount *) $kgm_vol->mnt_data
8694 if $kgm_hfsmount->hfs_freezing_proc != 0
8695 printf "FROZEN hfs "
8696 else
8697 printf "hfs "
8698 end
8699 else
8700 printf "%-10s ", $kgm_vol->mnt_vtable->vfc_name
8701 end
8702 printf "%s\n", $kgm_vol->mnt_vfsstat.f_mntonname
8703
8704 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
8705 end
8706 end
8707
8708 document showallvols
8709 Syntax: (gdb) showallvols
8710 | Display a summary of mounted volumes
8711 end
8712
8713 define showvnodeheader
8714 printf "vnode "
8715 showptrhdrpad
8716 printf " usecount iocount v_data "
8717 showptrhdrpad
8718 printf " vtype parent "
8719 showptrhdrpad
8720 printf " name\n"
8721 end
8722
8723 define showvnodeint
8724 set $kgm_vnode = (vnode_t) $arg0
8725 showptr $kgm_vnode
8726 printf " %8d ", $kgm_vnode->v_usecount
8727 printf "%7d ", $kgm_vnode->v_iocount
8728 # print information about clean/dirty blocks?
8729 showptr $kgm_vnode->v_data
8730 printf " "
8731 # print the vtype, using the enum tag
8732 set $kgm_vtype = $kgm_vnode->v_type
8733 if $kgm_vtype == VNON
8734 printf "VNON "
8735 end
8736 if $kgm_vtype == VREG
8737 printf "VREG "
8738 end
8739 if $kgm_vtype == VDIR
8740 printf "VDIR "
8741 end
8742 if $kgm_vtype == VBLK
8743 printf "VBLK "
8744 end
8745 if $kgm_vtype == VCHR
8746 printf "VCHR "
8747 end
8748 if $kgm_vtype == VLNK
8749 printf "VLNK "
8750 end
8751 if $kgm_vtype == VSOCK
8752 printf "VSOCK "
8753 end
8754 if $kgm_vtype == VFIFO
8755 printf "VFIFO "
8756 end
8757 if $kgm_vtype == VBAD
8758 printf "VBAD "
8759 end
8760 if ($kgm_vtype < VNON) || ($kgm_vtype > VBAD)
8761 printf "%5d ", $kgm_vtype
8762 end
8763
8764 showptr $kgm_vnode->v_parent
8765 printf " "
8766 if ($kgm_vnode->v_name != 0)
8767 printf "%s\n", $kgm_vnode->v_name
8768 else
8769 # If this is HFS vnode, get name from the cnode
8770 if ($kgm_vnode->v_tag == 16)
8771 set $kgm_cnode = (struct cnode *)$kgm_vnode->v_data
8772 printf "hfs: %s\n", (char *)$kgm_cnode->c_desc->cd_nameptr
8773 else
8774 printf "\n"
8775 end
8776 end
8777 end
8778
8779 define showvnode
8780 showvnodeheader
8781 showvnodeint $arg0
8782 end
8783
8784 document showvnode
8785 Syntax: (gdb) showvnode <vnode>
8786 | Display info about one vnode
8787 end
8788
8789 define showvolvnodes
8790 showvnodeheader
8791 set $kgm_vol = (mount_t) $arg0
8792 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
8793 while $kgm_vnode
8794 showvnodeint $kgm_vnode
8795 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
8796 end
8797 end
8798
8799 document showvolvnodes
8800 Syntax: (gdb) showvolvnodes <mouont_t>
8801 | Display info about all vnodes of a given mount_t
8802 end
8803
8804 define showvolbusyvnodes
8805 showvnodeheader
8806 set $kgm_vol = (mount_t) $arg0
8807 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
8808 while $kgm_vnode
8809 if $kgm_vnode->v_iocount != 0
8810 showvnodeint $kgm_vnode
8811 end
8812 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
8813 end
8814 end
8815
8816 document showvolbusyvnodes
8817 Syntax: (gdb) showvolbusyvnodes <mount_t>
8818 | Display info about busy (iocount!=0) vnodes of a given mount_t
8819 end
8820
8821 define showallbusyvnodes
8822 showvnodeheader
8823 set $kgm_vol = (mount_t) mountlist.tqh_first
8824 while $kgm_vol
8825 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
8826 while $kgm_vnode
8827 if $kgm_vnode->v_iocount != 0
8828 showvnodeint $kgm_vnode
8829 end
8830 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
8831 end
8832 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
8833 end
8834 end
8835
8836 document showallbusyvnodes
8837 Syntax: (gdb) showallbusyvnodes <vnode>
8838 | Display info about all busy (iocount!=0) vnodes
8839 end
8840
8841 define showallvnodes
8842 showvnodeheader
8843 set $kgm_vol = (mount_t) mountlist.tqh_first
8844 while $kgm_vol
8845 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
8846 while $kgm_vnode
8847 showvnodeint $kgm_vnode
8848 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
8849 end
8850 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
8851 end
8852 end
8853
8854 document showallvnodes
8855 Syntax: (gdb) showallvnodes
8856 | Display info about all vnodes
8857 end
8858
8859 define _showvnodelockheader
8860 printf "* type W held by lock type start end\n"
8861 printf "- ----- - ------------- --------- ------------------ ------------------\n"
8862 end
8863
8864 define _showvnodelock
8865 set $kgm_svl_lock = ((struct lockf *)$arg0)
8866
8867 # decode flags
8868 set $kgm_svl_flags = $kgm_svl_lock->lf_flags
8869 set $kgm_svl_type = $kgm_svl_lock->lf_type
8870 if ($kgm_svl_flags & 0x20)
8871 printf "flock"
8872 end
8873 if ($kgm_svl_flags & 0x40)
8874 printf "posix"
8875 end
8876 if ($kgm_svl_flags & 0x80)
8877 printf "prov "
8878 end
8879 if ($kgm_svl_flags & 0x10)
8880 printf " W "
8881 else
8882 printf " . "
8883 end
8884
8885 # POSIX file vs. advisory range locks
8886 if ($kgm_svl_flags & 0x40)
8887 set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id
8888 printf "PID %8d ", $kgm_svl_proc->p_pid
8889 else
8890 printf "ID 0x%08x ", $kgm_svl_lock->lf_id
8891 end
8892
8893 # lock type
8894 if ($kgm_svl_type == 1)
8895 printf "shared "
8896 else
8897 if ($kgm_svl_type == 3)
8898 printf "exclusive "
8899 else
8900 if ($kgm_svl_type == 2)
8901 printf "unlock "
8902 else
8903 printf "unknown "
8904 end
8905 end
8906 end
8907
8908 # start and stop
8909 printf "0x%016x..", $kgm_svl_lock->lf_start
8910 printf "0x%016x ", $kgm_svl_lock->lf_end
8911 printf "\n"
8912 end
8913 # Body of showvnodelocks, not including header
8914 define _showvnodelocks
8915 set $kgm_svl_vnode = ((vnode_t)$arg0)
8916 set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf
8917 while ($kgm_svl_lockiter != 0)
8918 # locks that are held
8919 printf "H "
8920 _showvnodelock $kgm_svl_lockiter
8921
8922 # and any locks blocked by them
8923 set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first
8924 while ($kgm_svl_blocker != 0)
8925 printf "> "
8926 _showvnodelock $kgm_svl_blocker
8927 set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next
8928 end
8929
8930 # and on to the next one...
8931 set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next
8932 end
8933 end
8934
8935
8936 define showvnodelocks
8937 if ($argc == 1)
8938 _showvnodelockheader
8939 _showvnodelocks $arg0
8940 else
8941 printf "| Usage:\n|\n"
8942 help showvnodelocks
8943 end
8944 end
8945
8946 document showvnodelocks
8947 Syntax: (gdb) showvnodelocks <vnode_t>
8948 | Given a vnodet pointer, display the list of advisory record locks for the
8949 | referenced pvnodes
8950 end
8951
8952 define showbootargs
8953 printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
8954 end
8955
8956 document showbootargs
8957 Syntax: showbootargs
8958 | Display boot arguments passed to the target kernel
8959 end
8960
8961 define showbootermemorymap
8962 if ($kgm_mtype == $kgm_mtype_i386)
8963 set $kgm_voffset = 0
8964 else
8965 if ($kgm_mtype == $kgm_mtype_x86_64)
8966 set $kgm_voffset = 0xFFFFFF8000000000ULL
8967 else
8968 echo showbootermemorymap not supported on this architecture
8969 end
8970 end
8971
8972 set $kgm_boot_args = kernelBootArgs
8973 set $kgm_msize = kernelBootArgs->MemoryMapDescriptorSize
8974 set $kgm_mcount = kernelBootArgs->MemoryMapSize / $kgm_msize
8975 set $kgm_i = 0
8976
8977 printf "Type Physical Start Number of Pages Virtual Start Attributes\n"
8978 while $kgm_i < $kgm_mcount
8979 set $kgm_mptr = (EfiMemoryRange *)((unsigned long)kernelBootArgs->MemoryMap + $kgm_voffset + $kgm_i * $kgm_msize)
8980 # p/x *$kgm_mptr
8981 if $kgm_mptr->Type == 0
8982 printf "Reserved "
8983 end
8984 if $kgm_mptr->Type == 1
8985 printf "LoaderCode"
8986 end
8987 if $kgm_mptr->Type == 2
8988 printf "LoaderData"
8989 end
8990 if $kgm_mptr->Type == 3
8991 printf "BS_code "
8992 end
8993 if $kgm_mptr->Type == 4
8994 printf "BS_data "
8995 end
8996 if $kgm_mptr->Type == 5
8997 printf "RT_code "
8998 end
8999 if $kgm_mptr->Type == 6
9000 printf "RT_data "
9001 end
9002 if $kgm_mptr->Type == 7
9003 printf "Convention"
9004 end
9005 if $kgm_mptr->Type == 8
9006 printf "Unusable "
9007 end
9008 if $kgm_mptr->Type == 9
9009 printf "ACPI_recl "
9010 end
9011 if $kgm_mptr->Type == 10
9012 printf "ACPI_NVS "
9013 end
9014 if $kgm_mptr->Type == 11
9015 printf "MemMapIO "
9016 end
9017 if $kgm_mptr->Type == 12
9018 printf "MemPortIO "
9019 end
9020 if $kgm_mptr->Type == 13
9021 printf "PAL_code "
9022 end
9023 if $kgm_mptr->Type > 13
9024 printf "UNKNOWN "
9025 end
9026
9027 printf " %016llx %016llx", $kgm_mptr->PhysicalStart, $kgm_mptr->NumberOfPages
9028 if $kgm_mptr->VirtualStart != 0
9029 printf " %016llx", $kgm_mptr->VirtualStart
9030 else
9031 printf " "
9032 end
9033 printf " %016llx\n", $kgm_mptr->Attribute
9034 set $kgm_i = $kgm_i + 1
9035 end
9036 end
9037
9038 document showbootermemorymap
9039 Syntax: (gdb) showbootermemorymap
9040 | Prints out the phys memory map from kernelBootArgs
9041 end
9042
9043
9044 define showstacksaftertask
9045 set $kgm_head_taskp = &tasks
9046 set $kgm_taskp = (struct task *)$arg0
9047 set $kgm_taskp = (struct task *)$kgm_taskp->tasks.next
9048 while $kgm_taskp != $kgm_head_taskp
9049 showtaskheader
9050 showtaskint $kgm_taskp
9051 set $kgm_head_actp = &($kgm_taskp->threads)
9052 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
9053 while $kgm_actp != $kgm_head_actp
9054 showactheader
9055 if ($decode_wait_events > 0)
9056 showactint $kgm_actp 1
9057 else
9058 showactint $kgm_actp 2
9059 end
9060 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
9061 end
9062 printf "\n"
9063 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9064 end
9065 end
9066 document showstacksaftertask
9067 Syntax: (gdb) showstacksaftertask <task>
9068 | Routine to print out all stacks (as in showallstacks) starting after a given task
9069 | Useful if that gdb refuses to print a certain task's stack.
9070 end
9071
9072 define showpmworkqueueint
9073 set $kgm_pm_workqueue = (IOPMWorkQueue *)$arg0
9074 set $kgm_pm_wq = &($kgm_pm_workqueue->fWorkQueue)
9075 set $kgm_pm_wqe = (IOServicePM *)$kgm_pm_wq->next
9076 while ((queue_entry_t) $kgm_pm_wqe != (queue_entry_t) $kgm_pm_wq)
9077 printf "service "
9078 showptrhdrpad
9079 printf " ps ms wr name\n"
9080 showptr $kgm_pm_wqe->Owner
9081 printf " "
9082 printf "%02d ", $kgm_pm_wqe->CurrentPowerState
9083 printf "%02d ", $kgm_pm_wqe->MachineState
9084 printf "%02d ", $kgm_pm_wqe->WaitReason
9085 printf "%s\n", $kgm_pm_wqe->Name
9086 printf "request "
9087 showptrhdrpad
9088 printf " type next "
9089 showptrhdrpad
9090 printf " root "
9091 showptrhdrpad
9092 printf " work_wait free_wait\n"
9093 set $kgm_pm_rq = &($kgm_pm_wqe->RequestHead)
9094 set $kgm_pm_rqe = (IOPMRequest *)$kgm_pm_rq->next
9095 while ((queue_entry_t) $kgm_pm_rqe != (queue_entry_t) $kgm_pm_rq)
9096 showptr $kgm_pm_rqe
9097 printf " 0x%02x ", $kgm_pm_rqe->fType
9098 showptr $kgm_pm_rqe->fRequestNext
9099 printf " "
9100 showptr $kgm_pm_rqe->fRequestRoot
9101 printf " 0x%08x 0x%08x\n", $kgm_pm_rqe->fWorkWaitCount, $kgm_pm_rqe->fFreeWaitCount
9102 showptrhdrpad
9103 printf " args "
9104 showptr $kgm_pm_rqe->fArg0
9105 printf " "
9106 showptr $kgm_pm_rqe->fArg1
9107 printf " "
9108 showptr $kgm_pm_rqe->fArg2
9109 printf "\n"
9110 set $kgm_pm_rqe = (IOPMRequest *)$kgm_pm_rqe->fCommandChain.next
9111 end
9112 printf "\n"
9113 set $kgm_pm_wqe = (IOServicePM *)$kgm_pm_wqe->WorkChain.next
9114 end
9115 end
9116
9117 define showpmworkqueue
9118 printf "IOPMWorkQueue "
9119 showptr gIOPMWorkQueue
9120 printf " length "
9121 printf "%u", gIOPMWorkQueue->fQueueLength
9122 printf "\n"
9123 if (gIOPMWorkQueue->fQueueLength > 0)
9124 showpmworkqueueint gIOPMWorkQueue
9125 end
9126 end
9127
9128 document showpmworkqueue
9129 Syntax: (gdb) showpmworkqueue
9130 | Display the IOPMWorkQueue object
9131 end
9132
9133 define showioservicepm
9134 set $kgm_iopmpriv = (IOServicePM *)$arg0
9135 printf "{ "
9136 printf "MachineState = %d (", $kgm_iopmpriv->MachineState
9137 if ( $kgm_iopmpriv->MachineState == 0 )
9138 printf "kIOPM_Finished"
9139 else
9140 if ( $kgm_iopmpriv->MachineState == 1 )
9141 printf "kIOPM_OurChangeTellClientsPowerDown"
9142 else
9143 if ( $kgm_iopmpriv->MachineState == 2 )
9144 printf "kIOPM_OurChangeTellPriorityClientsPowerDown"
9145 else
9146 if ( $kgm_iopmpriv->MachineState == 3 )
9147 printf "kIOPM_OurChangeNotifyInterestedDriversWillChange"
9148 else
9149 if ( $kgm_iopmpriv->MachineState == 4 )
9150 printf "kIOPM_OurChangeSetPowerState"
9151 else
9152 if ( $kgm_iopmpriv->MachineState == 5 )
9153 printf "kIOPM_OurChangeWaitForPowerSettle"
9154 else
9155 if ( $kgm_iopmpriv->MachineState == 6 )
9156 printf "kIOPM_OurChangeNotifyInterestedDriversDidChange"
9157 else
9158 if ( $kgm_iopmpriv->MachineState == 7 )
9159 printf "kIOPM_OurChangeTellCapabilityDidChange"
9160 else
9161 if ( $kgm_iopmpriv->MachineState == 8 )
9162 printf "kIOPM_OurChangeFinish"
9163 else
9164 if ( $kgm_iopmpriv->MachineState == 9 )
9165 printf "Unused_MachineState_9"
9166 else
9167 if ( $kgm_iopmpriv->MachineState == 10 )
9168 printf "kIOPM_ParentChangeTellPriorityClientsPowerDown"
9169 else
9170 if ( $kgm_iopmpriv->MachineState == 11 )
9171 printf "kIOPM_ParentChangeNotifyInterestedDriversWillChange"
9172 else
9173 if ( $kgm_iopmpriv->MachineState == 12 )
9174 printf "kIOPM_ParentChangeSetPowerState"
9175 else
9176 if ( $kgm_iopmpriv->MachineState == 13 )
9177 printf "kIOPM_ParentChangeWaitForPowerSettle"
9178 else
9179 if ( $kgm_iopmpriv->MachineState == 14)
9180 printf "kIOPM_ParentChangeNotifyInterestedDriversDidChange"
9181 else
9182 if ( $kgm_iopmpriv->MachineState == 15)
9183 printf "kIOPM_ParentChangeTellCapabilityDidChange"
9184 else
9185 if ( $kgm_iopmpriv->MachineState == 16)
9186 printf "kIOPM_ParentChangeAcknowledgePowerChange"
9187 else
9188 if ( $kgm_iopmpriv->MachineState == 17)
9189 printf "kIOPM_NotifyChildrenStart"
9190 else
9191 if ( $kgm_iopmpriv->MachineState == 18)
9192 printf "kIOPM_NotifyChildrenOrdered"
9193 else
9194 if ( $kgm_iopmpriv->MachineState == 19)
9195 printf "kIOPM_NotifyChildrenDelayed"
9196 else
9197 if ( $kgm_iopmpriv->MachineState == 20)
9198 printf "kIOPM_SyncTellClientsPowerDown"
9199 else
9200 if ( $kgm_iopmpriv->MachineState == 21)
9201 printf "kIOPM_SyncTellPriorityClientsPowerDown"
9202 else
9203 if ( $kgm_iopmpriv->MachineState == 22)
9204 printf "kIOPM_SyncNotifyWillChange"
9205 else
9206 if ( $kgm_iopmpriv->MachineState == 23)
9207 printf "kIOPM_SyncNotifyDidChange"
9208 else
9209 if ( $kgm_iopmpriv->MachineState == 24)
9210 printf "kIOPM_SyncTellCapabilityDidChange"
9211 else
9212 if ( $kgm_iopmpriv->MachineState == 25)
9213 printf "kIOPM_SyncFinish"
9214 else
9215 if ( $kgm_iopmpriv->MachineState == 26)
9216 printf "kIOPM_TellCapabilityChangeDone"
9217 else
9218 if ( $kgm_iopmpriv->MachineState == 27)
9219 printf "kIOPM_DriverThreadCallDone"
9220 else
9221 printf "Unknown_MachineState"
9222 end
9223 end
9224 end
9225 end
9226 end
9227 end
9228 end
9229 end
9230 end
9231 end
9232 end
9233 end
9234 end
9235 end
9236 end
9237 end
9238 end
9239 end
9240 end
9241 end
9242 end
9243 end
9244 end
9245 end
9246 end
9247 end
9248 end
9249 end
9250 printf "), "
9251
9252 if ( $kgm_iopmpriv->MachineState != 20 )
9253 printf "DriverTimer = %d, ",(unsigned int)$kgm_iopmpriv->DriverTimer
9254 printf "SettleTime = %d, ",(unsigned int)$kgm_iopmpriv->SettleTimeUS
9255 printf "HeadNoteFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteChangeFlags
9256 printf "HeadNotePendingAcks = %x, ",(unsigned int)$kgm_iopmpriv->HeadNotePendingAcks
9257 end
9258
9259 if ( $kgm_iopmpriv->DeviceOverrideEnabled != 0 )
9260 printf"DeviceOverrides, "
9261 end
9262
9263 printf "DeviceDesire = %d, ",(unsigned int)$kgm_iopmpriv->DeviceDesire
9264 printf "DesiredPowerState = %d, ",(unsigned int)$kgm_iopmpriv->DesiredPowerState
9265 printf "PreviousRequest = %d }\n",(unsigned int)$kgm_iopmpriv->PreviousRequestPowerFlags
9266 end
9267
9268 document showioservicepm
9269 Syntax: (gdb) showioservicepm <IOServicePM pointer>
9270 | Routine to dump the IOServicePM object
9271 end
9272
9273 define showregistryentryrecursepmstate
9274 set $kgm_re = (IOService *)$arg1
9275 set $kgm$arg0_stack = (unsigned long long) $arg2
9276
9277 if ($arg3)
9278 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
9279 else
9280 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
9281 end
9282
9283 dictget $kgm_re->fRegistryTable $kgm_childkey
9284 set $kgm$arg0_child_array = (OSArray *) $kgm_result
9285
9286 if ($kgm$arg0_child_array)
9287 set $kgm$arg0_child_count = $kgm$arg0_child_array->count
9288 else
9289 set $kgm$arg0_child_count = 0
9290 end
9291
9292 if ($kgm$arg0_child_count)
9293 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
9294 else
9295 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
9296 end
9297
9298 indent $kgm_reg_depth $kgm$arg0_stack
9299 printf "+-o "
9300
9301 dictget $kgm_re->fRegistryTable $kgm_namekey
9302 if ($kgm_result == 0)
9303 dictget $kgm_re->fRegistryTable gIONameKey
9304 end
9305 if ($kgm_result == 0)
9306 dictget $kgm_re->fPropertyTable gIOClassKey
9307 end
9308
9309 if ($kgm_result != 0)
9310 printf "%s <%p>", ((OSString *)$kgm_result)->string, $kgm_re
9311 else
9312 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name)
9313 printf "%s <", ((IOService*)$kgm_re)->pwrMgt->Name
9314 showptr $kgm_re
9315 printf ">"
9316 else
9317 printf "?? <"
9318 showptr $kgm_re
9319 printf ">"
9320 end
9321 end
9322
9323 if (((IOService*)$kgm_re)->pwrMgt )
9324 printf " Current Power State: %ld ", ((IOService*)$kgm_re)->pwrMgt->CurrentPowerState
9325 #printf " Mach State %ld", ((IOService*)$kgm_re)->pwrMgt->MachineState
9326 showioservicepm ((IOService*)$kgm_re)->pwrMgt
9327 end
9328 printf "\n"
9329
9330
9331 # recurse
9332 if ($kgm$arg0_child_count != 0)
9333
9334 set $kgm_reg_depth = $kgm_reg_depth + 1
9335 set $kgm$arg0_child_idx = 0
9336
9337 while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
9338 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
9339 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
9340 if $kgm_reg_depth >= $kgm_reg_depth_max + 1
9341 loop_break
9342 end
9343 showregistryentryrecursepmstate _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
9344 end
9345
9346 set $kgm_reg_depth = $kgm_reg_depth - 1
9347 end
9348 end
9349
9350 define showregistryentryintpmstate
9351 if !$kgm_reg_plane
9352 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
9353 end
9354
9355 if !$kgm_reg_plane
9356 printf "Please load kgmacros after KDP attaching to the target.\n"
9357 else
9358 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane->nameKey
9359 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane->keys[1]
9360 showregistryentryrecursepmstate _ $arg0 0 0
9361 end
9362 end
9363
9364 define showregistrypmstate
9365 # setregistryplane gIOPowerPlane
9366 set $kgm_reg_depth = 0
9367 set $kgm_show_props = 1
9368 showregistryentryintpmstate gRegistryRoot
9369 end
9370
9371 document showregistrypmstate
9372 Syntax: (gdb) showregistrypmstate
9373 | Routine to dump the PM state of each IOPower registry entry
9374 end
9375
9376 define showstacksafterthread
9377 set $kgm_head_taskp = &tasks
9378 set $kgm_actp = (struct thread *)$arg0
9379 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
9380 set $kgm_taskp = (struct task *)$kgm_actp->task
9381 while $kgm_taskp != $kgm_head_taskp
9382 showtaskheader
9383 showtaskint $kgm_taskp
9384 set $kgm_head_actp = &($kgm_taskp->threads)
9385 if $kgm_actp == 0
9386 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
9387 end
9388 while $kgm_actp != $kgm_head_actp
9389 showactheader
9390 if ($decode_wait_events > 0)
9391 showactint $kgm_actp 1
9392 else
9393 showactint $kgm_actp 2
9394 end
9395 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
9396 end
9397 printf "\n"
9398 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
9399 set $kgm_actp = 0
9400 end
9401 end
9402
9403 document showstacksafterthread
9404 Syntax: (gdb) showstacksafterthread <thread>
9405 | Routine to print out all stacks (as in showallstacks) starting after a given thread
9406 | Useful if that gdb refuses to print a certain task's stack.
9407 end
9408
9409 define kdp-reenter
9410 set kdp_reentry_deadline = ((unsigned) $arg0)*1000
9411 continue
9412 end
9413
9414 document kdp-reenter
9415 Syntax: (gdb) kdp-reenter <seconds>
9416 | Schedules reentry into the debugger after <seconds> seconds, and resumes
9417 | the target system.
9418 end
9419
9420 define _if_present
9421 if (!$arg0)
9422 printf " not"
9423 end
9424 printf " present"
9425 end
9426
9427 define showMCAstate
9428 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
9429 printf "Not available for current architecture.\n"
9430 else
9431 printf "MCA"
9432 _if_present mca_MCA_present
9433 printf ", control MSR"
9434 _if_present mca_control_MSR_present
9435 printf ", threshold status"
9436 _if_present mca_threshold_status_present
9437 printf "\n%d error banks, ", mca_error_bank_count
9438 printf "family code 0x%x, ", mca_family
9439 printf "machine-check dump state: %d\n", mca_dump_state
9440 set $kgm_cpu = 0
9441 while cpu_data_ptr[$kgm_cpu] != 0
9442 set $kgm_mcp = cpu_data_ptr[$kgm_cpu]->cpu_mca_state
9443 if $kgm_mcp
9444 printf "CPU %d:", $kgm_cpu
9445 printf " mca_mcg_ctl: 0x%016llx", $kgm_mcp->mca_mcg_ctl
9446 printf " mca_mcg_status: 0x%016llx\n", $kgm_mcp->mca_mcg_status.u64
9447 printf "bank "
9448 printf "mca_mci_ctl "
9449 printf "mca_mci_status "
9450 printf "mca_mci_addr "
9451 printf "mca_mci_misc\n"
9452 set $kgm_bank = 0
9453 while $kgm_bank < mca_error_bank_count
9454 set $kgm_bp = &$kgm_mcp->mca_error_bank[$kgm_bank]
9455 printf " %2d:", $kgm_bank
9456 printf " 0x%016llx", $kgm_bp->mca_mci_ctl
9457 printf " 0x%016llx", $kgm_bp->mca_mci_status.u64
9458 printf " 0x%016llx", $kgm_bp->mca_mci_addr
9459 printf " 0x%016llx\n", $kgm_bp->mca_mci_misc
9460 set $kgm_bank = $kgm_bank + 1
9461 end
9462 end
9463 set $kgm_cpu = $kgm_cpu + 1
9464 end
9465 end
9466 end
9467
9468 document showMCAstate
9469 Syntax: showMCAstate
9470 | Print machine-check register state after MC exception.
9471 end
9472
9473 define _pt_step
9474 #
9475 # Step to lower-level page table and print attributes
9476 # $kgm_pt_paddr: current page table entry physical address
9477 # $kgm_pt_index: current page table entry index (0..511)
9478 # returns
9479 # $kgm_pt_paddr: next level page table entry physical address
9480 # or null if invalid
9481 # $kgm_pt_valid: 1 if $kgm_pt_paddr is valid, 0 if the walk
9482 # should be aborted
9483 # $kgm_pt_large: 1 if kgm_pt_paddr is a page frame address
9484 # of a large page and not another page table entry
9485 # For $kgm_pt_verbose = 0: print nothing
9486 # 1: print basic information
9487 # 2: print basic information and hex table dump
9488 #
9489 set $kgm_entryp = $kgm_pt_paddr + 8*$kgm_pt_index
9490 readphysint $kgm_entryp 64 $kgm_lcpu_self
9491 set $entry = $kgm_readphysint_result
9492 if $kgm_pt_verbose >= 3
9493 set $kgm_pte_loop = 0
9494 while $kgm_pte_loop < 512
9495 set $kgm_pt_paddr_tmp = $kgm_pt_paddr + $kgm_pte_loop*8
9496 readphys64 $kgm_pt_paddr_tmp
9497 set $kgm_pte_loop = $kgm_pte_loop + 1
9498 end
9499 end
9500 set $kgm_paddr_mask = ~((0xfffULL<<52) | 0xfffULL)
9501 set $kgm_paddr_largemask = ~((0xfffULL<<52) | 0x1fffffULL)
9502 if $kgm_pt_verbose < 2
9503 if $entry & (0x1 << 0)
9504 set $kgm_pt_valid = 1
9505 if $entry & (0x1 << 7)
9506 set $kgm_pt_large = 1
9507 set $kgm_pt_paddr = $entry & $kgm_paddr_largemask
9508 else
9509 set $kgm_pt_large = 0
9510 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
9511 end
9512 else
9513 set $kgm_pt_valid = 0
9514 set $kgm_pt_large = 0
9515 set $kgm_pt_paddr = 0
9516 end
9517 else
9518 printf "0x%016llx:\n\t0x%016llx\n\t", $kgm_entryp, $entry
9519 if $entry & (0x1 << 0)
9520 printf "valid"
9521 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
9522 set $kgm_pt_valid = 1
9523 else
9524 printf "invalid"
9525 set $kgm_pt_paddr = 0
9526 set $kgm_pt_valid = 0
9527 # stop decoding other bits
9528 set $entry = 0
9529 end
9530 if $entry & (0x1 << 1)
9531 printf " writeable"
9532 else
9533 printf " read-only"
9534 end
9535 if $entry & (0x1 << 2)
9536 printf " user"
9537 else
9538 printf " supervisor"
9539 end
9540 if $entry & (0x1 << 3)
9541 printf " PWT"
9542 end
9543 if $entry & (0x1 << 4)
9544 printf " PCD"
9545 end
9546 if $entry & (0x1 << 5)
9547 printf " accessed"
9548 end
9549 if $entry & (0x1 << 6)
9550 printf " dirty"
9551 end
9552 if $entry & (0x1 << 7)
9553 printf " large"
9554 set $kgm_pt_large = 1
9555 else
9556 set $kgm_pt_large = 0
9557 end
9558 if $entry & (0x1 << 8)
9559 printf " global"
9560 end
9561 if $entry & (0x3 << 9)
9562 printf " avail:0x%x", ($entry >> 9) & 0x3
9563 end
9564 if $entry & (0x1ULL << 63)
9565 printf " noexec"
9566 end
9567 printf "\n"
9568 end
9569 end
9570
9571 define _pml4_walk
9572 set $kgm_pt_paddr = $arg0
9573 set $kgm_vaddr = $arg1
9574 set $kgm_pt_valid = $kgm_pt_paddr != 0
9575 set $kgm_pt_large = 0
9576 set $kgm_pframe_offset = 0
9577 if $kgm_pt_valid && cpu_64bit
9578 # Look up bits 47:39 of the linear address in PML4T
9579 set $kgm_pt_index = ($kgm_vaddr >> 39) & 0x1ffULL
9580 set $kgm_pframe_offset = $kgm_vaddr & 0x7fffffffffULL
9581 if $kgm_pt_verbose >= 2
9582 printf "pml4 (index %d):\n", $kgm_pt_index
9583 end
9584 _pt_step
9585 end
9586 if $kgm_pt_valid
9587 # Look up bits 38:30 of the linear address in PDPT
9588 set $kgm_pt_index = ($kgm_vaddr >> 30) & 0x1ffULL
9589 set $kgm_pframe_offset = $kgm_vaddr & 0x3fffffffULL
9590 if $kgm_pt_verbose >= 2
9591 printf "pdpt (index %d):\n", $kgm_pt_index
9592 end
9593 _pt_step
9594 end
9595 if $kgm_pt_valid && !$kgm_pt_large
9596 # Look up bits 29:21 of the linear address in PDT
9597 set $kgm_pt_index = ($kgm_vaddr >> 21) & 0x1ffULL
9598 set $kgm_pframe_offset = $kgm_vaddr & 0x1fffffULL
9599 if $kgm_pt_verbose >= 2
9600 printf "pdt (index %d):\n", $kgm_pt_index
9601 end
9602 _pt_step
9603 end
9604 if $kgm_pt_valid && !$kgm_pt_large
9605 # Look up bits 20:21 of the linear address in PT
9606 set $kgm_pt_index = ($kgm_vaddr >> 12) & 0x1ffULL
9607 set $kgm_pframe_offset = $kgm_vaddr & 0xfffULL
9608 if $kgm_pt_verbose >= 2
9609 printf "pt (index %d):\n", $kgm_pt_index
9610 end
9611 _pt_step
9612 end
9613
9614 if $kgm_pt_valid
9615 set $kgm_paddr = $kgm_pt_paddr + $kgm_pframe_offset
9616 set $kgm_paddr_isvalid = 1
9617 else
9618 set $kgm_paddr = 0
9619 set $kgm_paddr_isvalid = 0
9620 end
9621
9622 if $kgm_pt_verbose >= 1
9623 if $kgm_paddr_isvalid
9624 readphysint $kgm_paddr 32 $kgm_lcpu_self
9625 set $kgm_value = $kgm_readphysint_result
9626 printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value
9627 else
9628 printf "(no translation)\n"
9629 end
9630 end
9631 end
9632
9633 define _pmap_walk_x86
9634 set $kgm_pmap = (pmap_t) $arg0
9635 _pml4_walk $kgm_pmap->pm_cr3 $arg1
9636 end
9637
9638 define _pmap_walk_arm
9639 set $kgm_paddr = 0
9640 set $kgm_paddr_isvalid = 0
9641 end
9642
9643 define pmap_walk
9644 if $argc != 2
9645 printf "pmap_walk <pmap> <vaddr>\n"
9646 else
9647 if !$kgm_pt_verbose
9648 set $kgm_pt_verbose = 2
9649 else
9650 if $kgm_pt_verbose > 3
9651 set $kgm_pt_verbose = 2
9652 end
9653 end
9654 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
9655 _pmap_walk_x86 $arg0 $arg1
9656 else
9657 if ($kgm_mtype == $kgm_mtype_arm)
9658 _pmap_walk_arm $arg0 $arg1
9659 else
9660 printf "Not available for current architecture.\n"
9661 end
9662 end
9663 end
9664 end
9665
9666 document pmap_walk
9667 Syntax: (gdb) pmap_walk <pmap> <virtual_address>
9668 | Perform a page-table walk in <pmap> for <virtual_address>.
9669 | Set:
9670 | $kgm_pt_verbose=0 for no output, $kgm_paddr will be set
9671 | if $kgm_paddr_isvalid is 1
9672 | $kgm_pt_verbose=1 for final physical address
9673 | $kgm_pt_verbose=2 for dump of page table entry.
9674 | $kgm_pt_verbose=3 for full hex dump of page tables.
9675 end
9676
9677 define pmap_vtop
9678 if $argc != 2
9679 printf "pmap_vtop <pamp> <vaddr>\n"
9680 else
9681 set $kgm_pt_verbose = 1
9682 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
9683 _pmap_walk_x86 $arg0 $arg1
9684 else
9685 if ($kgm_mtype == $kgm_mtype_arm)
9686 _pmap_walk_arm $arg0 $arg1
9687 else
9688 printf "Not available for current architecture.\n"
9689 end
9690 end
9691 end
9692 end
9693
9694 document pmap_vtop
9695 Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
9696 | For page-tables in <pmap> translate <virtual_address> to physical address.
9697 end
9698
9699 define zstack
9700 set $index = $arg0
9701
9702 if (log_records == 0)
9703 set $count = 0
9704 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
9705 else
9706 if ($argc == 2)
9707 set $count = $arg1
9708 else
9709 set $count = 1
9710 end
9711 end
9712
9713 while ($count)
9714 printf "\n--------------- "
9715
9716 if (zrecords[$index].z_opcode == 1)
9717 printf "ALLOC "
9718 else
9719 printf "FREE "
9720 end
9721
9722 showptr zrecords[$index].z_element
9723 printf " : index %d : ztime %d -------------\n", $index, zrecords[$index].z_time
9724
9725 set $frame = 0
9726
9727 while ($frame < 15)
9728 set $frame_pc = zrecords[$index].z_pc[$frame]
9729
9730 if ($frame_pc == 0)
9731 loop_break
9732 end
9733
9734 x/i $frame_pc
9735 set $frame = $frame + 1
9736 end
9737
9738 set $index = $index + 1
9739 set $count = $count - 1
9740 end
9741 end
9742
9743 document zstack
9744 Syntax: (gdb) zstack <index> [<count>]
9745 | Zone leak debugging: print the stack trace of log element at <index>.
9746 | If a <count> is supplied, it prints <count> log elements starting at <index>.
9747 |
9748 | The suggested usage is to look at indexes below zcurrent and look for common stack traces.
9749 | The stack trace that occurs the most is probably the cause of the leak. Find the pc of the
9750 | function calling into zalloc and use the countpcs kgmacro to find out how often that pc occurs in the log.
9751 | The pc occuring in a high percentage of records is most likely the source of the leak.
9752 |
9753 | The findoldest kgmacro is also useful for leak debugging since it identifies the oldest record
9754 | in the log, which may indicate the leaker.
9755 end
9756
9757 define findoldest
9758 set $index = 0
9759 set $count = log_records
9760 set $cur_min = 2000000000
9761 set $cur_index = 0
9762
9763 if (log_records == 0)
9764 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
9765 else
9766
9767 while ($count)
9768 if (zrecords[$index].z_element && zrecords[$index].z_time < $cur_min)
9769 set $cur_index = $index
9770 set $cur_min = zrecords[$index].z_time
9771 end
9772
9773 set $count = $count - 1
9774 set $index = $index + 1
9775 end
9776
9777 printf "oldest record is at log index %d:\n", $cur_index
9778 zstack $cur_index
9779 end
9780 end
9781
9782 document findoldest
9783 Syntax: (gdb) findoldest
9784 | Zone leak debugging: find and print the oldest record in the log. Note that this command
9785 | can take several minutes to run since it uses linear search.
9786 |
9787 | Once it prints a stack trace, find the pc of the caller above all the zalloc, kalloc and
9788 | IOKit layers. Then use the countpcs kgmacro to see how often this caller has allocated
9789 | memory. A caller with a high percentage of records in the log is probably the leaker.
9790 end
9791
9792 define countpcs
9793 set $target_pc = $arg0
9794 set $index = 0
9795 set $count = log_records
9796 set $found = 0
9797
9798 if (log_records == 0)
9799 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
9800 else
9801
9802 while ($count)
9803 set $frame = 0
9804
9805 if (zrecords[$index].z_element != 0)
9806 while ($frame < 15)
9807 if (zrecords[$index].z_pc[$frame] == $target_pc)
9808 set $found = $found + 1
9809 set $frame = 15
9810 end
9811
9812 set $frame = $frame + 1
9813 end
9814 end
9815
9816 set $index = $index + 1
9817 set $count = $count - 1
9818 end
9819
9820 printf "occurred %d times in log (%d%c of records)\n", $found, ($found * 100) / zrecorded, '%'
9821 end
9822 end
9823
9824 document countpcs
9825 Syntax: (gdb) countpcs <pc>
9826 | Zone leak debugging: search the log and print a count of all log entries that contain the given <pc>
9827 | in the stack trace. This is useful for verifying a suspected <pc> as being the source of
9828 | the leak. If a high percentage of the log entries contain the given <pc>, then it's most
9829 | likely the source of the leak. Note that this command can take several minutes to run.
9830 end
9831
9832 define findelem
9833 set $fe_index = zcurrent
9834 set $fe_count = log_records
9835 set $fe_elem = $arg0
9836 set $fe_prev_op = -1
9837
9838 if (log_records == 0)
9839 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n"
9840 end
9841
9842 while ($fe_count)
9843 if (zrecords[$fe_index].z_element == $fe_elem)
9844 zstack $fe_index
9845
9846 if (zrecords[$fe_index].z_opcode == $fe_prev_op)
9847 printf "*************** DOUBLE OP! *********************\n
9848 end
9849
9850 set $fe_prev_op = zrecords[$fe_index].z_opcode
9851 end
9852
9853 set $fe_count = $fe_count - 1
9854 set $fe_index = $fe_index + 1
9855
9856 if ($fe_index >= log_records)
9857 set $fe_index = 0
9858 end
9859 end
9860 end
9861
9862 document findelem
9863 Syntax: (gdb) findelem <elem addr>
9864 | Zone corruption debugging: search the log and print out the stack traces for all log entries that
9865 | refer to the given zone element. When the kernel panics due to a corrupted zone element, get the
9866 | element address and use this macro. This will show you the stack traces of all logged zalloc and
9867 | zfree operations which tells you who touched the element in the recent past. This also makes
9868 | double-frees readily apparent.
9869 end
9870
9871
9872 # This implements a shadowing scheme in kgmacros. If the
9873 # current user data can be accessed by simply changing kdp_pmap,
9874 # that is used. Otherwise, we copy data into a temporary buffer
9875 # in the kernel's address space and use that instead. Don't rely on
9876 # kdp_pmap between invocations of map/unmap. Since the shadow
9877 # codepath uses a manual KDP packet, request no more than 128 bytes.
9878 # Uses $kgm_lp64 for kernel address space size, and
9879 # $kgm_readphys_use_kdp/$kgm_readphys_force_physmap to override
9880 # how the user pages are accessed ($kgm_readphys_force_physmap
9881 # implies walking the user task's pagetables to get a physical
9882 # address and then shadowing data from there using the
9883 # physical mapping of memory).
9884 define _map_user_data_from_task
9885 set $kgm_map_user_taskp = (task_t)$arg0
9886 set $kgm_map_user_map = $kgm_map_user_taskp->map
9887 set $kgm_map_user_pmap = $kgm_map_user_map->pmap
9888 set $kgm_map_user_task_64 = ( $kgm_map_user_taskp->taskFeatures[0] & 0x80000000)
9889 set $kgm_map_user_window = 0
9890 set $kgm_map_switch_map = 0
9891
9892 if ($kgm_readphys_force_kdp != 0)
9893 set $kgm_readphys_use_kdp = 1
9894 else
9895 if ($kgm_readphys_force_physmap)
9896 set $kgm_readphys_use_kdp = 0
9897 else
9898 set $kgm_readphys_use_kdp = ( kdp->is_conn > 0 )
9899 end
9900 end
9901
9902 if ($kgm_readphys_use_kdp)
9903
9904 if $kgm_lp64
9905 set $kgm_map_switch_map = 1
9906 else
9907 if !$kgm_map_user_task_64
9908 set $kgm_map_switch_map = 1
9909 end
9910 end
9911
9912 if ($kgm_map_switch_map)
9913 # switch the map safely
9914 set $kgm_map_user_window = $arg1
9915 set kdp_pmap = $kgm_map_user_pmap
9916 else
9917 # requires shadowing/copying
9918
9919 # set up the manual KDP packet
9920 set manual_pkt.input = 0
9921 set manual_pkt.len = sizeof(kdp_readmem64_req_t)
9922 set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
9923 set $kgm_pkt->hdr.request = KDP_READMEM64
9924 set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
9925 set $kgm_pkt->hdr.is_reply = 0
9926 set $kgm_pkt->hdr.seq = 0
9927 set $kgm_pkt->hdr.key = 0
9928 set $kgm_pkt->address = (uint64_t)$arg1
9929 set $kgm_pkt->nbytes = (uint32_t)$arg2
9930
9931 set kdp_pmap = $kgm_map_user_pmap
9932 set manual_pkt.input = 1
9933 # dummy to make sure manual packet is executed
9934 set $kgm_dummy = &_mh_execute_header
9935 # Go back to kernel map so that we can access buffer directly
9936 set kdp_pmap = 0
9937
9938 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
9939 if ($kgm_pkt->error == 0)
9940 set $kgm_map_user_window = $kgm_pkt->data
9941 else
9942 set $kgm_map_user_window = 0
9943 end
9944 end
9945
9946 else
9947 # without the benefit of a KDP stub on the target, try to
9948 # find the user task's physical mapping and memcpy the data.
9949 # If it straddles a page boundary, copy in two passes
9950 set $kgm_vaddr_range1_start = (unsigned long long)$arg1
9951 set $kgm_vaddr_range1_count = (unsigned long long)$arg2
9952 if (($kgm_vaddr_range1_start + $kgm_vaddr_range1_count) & 0xFFF) < $kgm_vaddr_range1_count
9953 set $kgm_vaddr_range2_start = ($kgm_vaddr_range1_start + $kgm_vaddr_range1_count) & ~((unsigned long long)0xFFF)
9954 set $kgm_vaddr_range2_count = $kgm_vaddr_range1_start + $kgm_vaddr_range1_count - $kgm_vaddr_range2_start
9955 set $kgm_vaddr_range1_count = $kgm_vaddr_range2_start - $kgm_vaddr_range1_start
9956 else
9957 set $kgm_vaddr_range2_start = 0
9958 set $kgm_vaddr_range2_count = 0
9959 end
9960 set $kgm_paddr_range1_in_kva = 0
9961 set $kgm_paddr_range2_in_kva = 0
9962
9963 if ($kgm_mtype == $kgm_mtype_x86_64)
9964 set $kgm_pt_verbose = 0
9965 _pmap_walk_x86 $kgm_map_user_pmap $kgm_vaddr_range1_start
9966 if $kgm_paddr_isvalid
9967 set $kgm_paddr_range1_in_kva = $kgm_paddr + (((unsigned long long)-1 << 47) | ((unsigned long long)509 << 39))
9968 end
9969 if $kgm_vaddr_range2_start
9970 _pmap_walk_x86 $kgm_map_user_pmap $kgm_vaddr_range2_start
9971 if $kgm_paddr_isvalid
9972 set $kgm_paddr_range2_in_kva = $kgm_paddr + (((unsigned long long)-1 << 47) | ((unsigned long long)509 << 39))
9973 end
9974 end
9975 else
9976 if ($kgm_mtype == $kgm_mtype_arm)
9977 set $kgm_pt_verbose = 0
9978 _pmap_walk_arm $kgm_map_user_pmap $kgm_vaddr_range1_start
9979 if $kgm_paddr_isvalid
9980 set $kgm_paddr_range1_in_kva = $kgm_paddr - gPhysBase + gVirtBase
9981 end
9982 if $kgm_vaddr_range2_start
9983 _pmap_walk_arm $kgm_map_user_pmap $kgm_vaddr_range2_start
9984 if $kgm_paddr_isvalid
9985 set $kgm_paddr_range2_in_kva = $kgm_paddr - gPhysBase + gVirtBase
9986 end
9987 end
9988 else
9989 printf "Not available for current architecture.\n"
9990 set $kgm_paddr_isvalid = 0
9991 end
9992 end
9993 if $kgm_paddr_range1_in_kva
9994 set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
9995 memcpy $kgm_pkt->data $kgm_paddr_range1_in_kva $kgm_vaddr_range1_count
9996 if $kgm_paddr_range2_in_kva
9997 memcpy &$kgm_pkt->data[$kgm_vaddr_range1_count] $kgm_paddr_range2_in_kva $kgm_vaddr_range2_count
9998 end
9999 set $kgm_map_user_window = $kgm_pkt->data
10000 else
10001 set $kgm_map_user_window = 0
10002 end
10003 end
10004 end
10005
10006 define _unmap_user_data_from_task
10007 set kdp_pmap = 0
10008 end
10009
10010 # uses $kgm_taskp. Maps 32 bytes at a time and prints it
10011 define _print_path_for_image
10012 set $kgm_print_path_address = (unsigned long long)$arg0
10013 set $kgm_path_str_notdone = 1
10014
10015 if ($kgm_print_path_address == 0)
10016 set $kgm_path_str_notdone = 0
10017 end
10018
10019 while $kgm_path_str_notdone
10020 _map_user_data_from_task $kgm_taskp $kgm_print_path_address 32
10021
10022 set $kgm_print_path_ptr = (char *)$kgm_map_user_window
10023 set $kgm_path_i = 0
10024 while ($kgm_path_i < 32 && $kgm_print_path_ptr[$kgm_path_i] != '\0')
10025 set $kgm_path_i = $kgm_path_i + 1
10026 end
10027 printf "%.32s", $kgm_print_path_ptr
10028
10029 _unmap_user_data_from_task $kgm_taskp
10030
10031 # break out if we terminated on NUL
10032 if $kgm_path_i < 32
10033 set $kgm_path_str_notdone = 0
10034 else
10035 set $kgm_print_path_address = $kgm_print_path_address + 32
10036 end
10037 end
10038 end
10039
10040 # uses $kgm_taskp and $kgm_task_64. May modify $kgm_dyld_load_path
10041 define _print_image_info
10042 set $kgm_mh_image_address = (unsigned long long)$arg0
10043 set $kgm_mh_path_address = (unsigned long long)$arg1
10044
10045 # 32 bytes enough for mach_header/mach_header_64
10046 _map_user_data_from_task $kgm_taskp $kgm_mh_image_address 32
10047
10048 set $kgm_mh_ptr = (unsigned int*)$kgm_map_user_window
10049 set $kgm_mh_magic = $kgm_mh_ptr[0]
10050 set $kgm_mh_cputype = $kgm_mh_ptr[1]
10051 set $kgm_mh_cpusubtype = $kgm_mh_ptr[2]
10052 set $kgm_mh_filetype = $kgm_mh_ptr[3]
10053 set $kgm_mh_ncmds = $kgm_mh_ptr[4]
10054 set $kgm_mh_sizeofcmds = $kgm_mh_ptr[5]
10055 set $kgm_mh_flags = $kgm_mh_ptr[6]
10056
10057 _unmap_user_data_from_task $kgm_taskp
10058
10059 if $kgm_mh_magic == 0xfeedfacf
10060 set $kgm_mh_64 = 1
10061 set $kgm_lc_address = $kgm_mh_image_address + 32
10062 else
10063 set $kgm_mh_64 = 0
10064 set $kgm_lc_address = $kgm_mh_image_address + 28
10065 end
10066
10067 set $kgm_lc_idx = 0
10068 set $kgm_uuid_data = 0
10069 while $kgm_lc_idx < $kgm_mh_ncmds
10070
10071 # 24 bytes is size of uuid_command
10072 _map_user_data_from_task $kgm_taskp $kgm_lc_address 24
10073
10074 set $kgm_lc_ptr = (unsigned int *)$kgm_map_user_window
10075 set $kgm_lc_cmd = $kgm_lc_ptr[0]
10076 set $kgm_lc_cmd_size = $kgm_lc_ptr[1]
10077 set $kgm_lc_data = (unsigned char *)$kgm_lc_ptr + 8
10078
10079 if $kgm_lc_cmd == 0x1b
10080 set $kgm_uuid_data = $kgm_lc_data
10081 if $kgm_mh_64
10082 printf "0x%016llx ", $kgm_mh_image_address
10083 else
10084 printf "0x%08x ", $kgm_mh_image_address
10085 end
10086
10087 set $kgm_printed_type = 0
10088 if $kgm_mh_filetype == 0x2
10089 printf "MH_EXECUTE "
10090 set $kgm_printed_type = 1
10091 end
10092 if $kgm_mh_filetype == 0x6
10093 printf "MH_DYLIB "
10094 set $kgm_printed_type = 1
10095 end
10096 if $kgm_mh_filetype == 0x7
10097 printf "MH_DYLINKER "
10098 set $kgm_printed_type = 1
10099 end
10100 if $kgm_mh_filetype == 0x8
10101 printf "MH_BUNDLE "
10102 set $kgm_printed_type = 1
10103 end
10104 if !$kgm_printed_type
10105 printf "UNKNOWN "
10106 end
10107 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]
10108 printf "%02.2X%02.2X-", $kgm_uuid_data[4], $kgm_uuid_data[5]
10109 printf "%02.2X%02.2X-", $kgm_uuid_data[6], $kgm_uuid_data[7]
10110 printf "%02.2X%02.2X-", $kgm_uuid_data[8], $kgm_uuid_data[9]
10111 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]
10112
10113 _unmap_user_data_from_task $kgm_taskp
10114
10115 printf " "
10116 _print_path_for_image $kgm_mh_path_address
10117 printf "\n"
10118
10119 loop_break
10120 else
10121 if $kgm_lc_cmd == 0xe
10122 set $kgm_load_dylinker_data = $kgm_lc_data
10123 set $kgm_dyld_load_path = $kgm_lc_address + *((unsigned int *)$kgm_load_dylinker_data)
10124 end
10125 _unmap_user_data_from_task $kgm_taskp
10126 end
10127
10128 set $kgm_lc_address = $kgm_lc_address + $kgm_lc_cmd_size
10129 set $kgm_lc_idx = $kgm_lc_idx + 1
10130 end
10131
10132 if (!$kgm_uuid_data)
10133 # didn't find LC_UUID, for a dylib, just print out basic info
10134 if $kgm_mh_64
10135 printf "0x%016llx ", $kgm_mh_image_address
10136 else
10137 printf "0x%08x ", $kgm_mh_image_address
10138 end
10139 set $kgm_printed_type = 0
10140 if $kgm_mh_filetype == 0x2
10141 printf "MH_EXECUTE "
10142 set $kgm_printed_type = 1
10143 end
10144 if $kgm_mh_filetype == 0x6
10145 printf "MH_DYLIB "
10146 set $kgm_printed_type = 1
10147 end
10148 if $kgm_mh_filetype == 0x7
10149 printf "MH_DYLINKER "
10150 set $kgm_printed_type = 1
10151 end
10152 if $kgm_mh_filetype == 0x8
10153 printf "MH_BUNDLE "
10154 set $kgm_printed_type = 1
10155 end
10156 if !$kgm_printed_type
10157 printf "UNKNOWN "
10158 end
10159 printf " ",
10160
10161 printf " "
10162 _print_path_for_image $kgm_mh_path_address
10163 printf "\n"
10164
10165 end
10166
10167 end
10168
10169 define _print_images_for_dyld_image_info
10170 set $kgm_taskp = $arg0
10171 set $kgm_task_64 = $arg1
10172 set $kgm_dyld_all_image_infos_address = (unsigned long long)$arg2
10173
10174 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 112
10175
10176 set $kgm_dyld_all_image_infos = (unsigned int *)$kgm_map_user_window
10177 set $kgm_dyld_all_image_infos_version = $kgm_dyld_all_image_infos[0]
10178 if ($kgm_dyld_all_image_infos_version > 12)
10179 printf "Unknown dyld all_image_infos version number %d\n", $kgm_dyld_all_image_infos_version
10180 end
10181 set $kgm_image_info_count = $kgm_dyld_all_image_infos[1]
10182
10183 set $kgm_dyld_load_path = 0
10184 if $kgm_task_64
10185 set $kgm_image_info_size = 24
10186 set $kgm_image_info_array_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[1]
10187 set $kgm_dyld_load_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[4]
10188 else
10189 set $kgm_image_info_size = 12
10190 set $kgm_image_info_array_address = ((unsigned int *)$kgm_dyld_all_image_infos)[2]
10191 set $kgm_dyld_load_address = ((unsigned int *)$kgm_dyld_all_image_infos)[5]
10192 end
10193
10194 _unmap_user_data_from_task $kgm_taskp
10195
10196 set $kgm_image_info_i = 0
10197 while $kgm_image_info_i < $kgm_image_info_count
10198
10199 set $kgm_image_info_address = $kgm_image_info_array_address + $kgm_image_info_size*$kgm_image_info_i
10200
10201 _map_user_data_from_task $kgm_taskp $kgm_image_info_address $kgm_image_info_size
10202 if $kgm_task_64
10203 set $kgm_image_info_addr = ((unsigned long long *)$kgm_map_user_window)[0]
10204 set $kgm_image_info_path = ((unsigned long long *)$kgm_map_user_window)[1]
10205 else
10206 set $kgm_image_info_addr = ((unsigned int *)$kgm_map_user_window)[0]
10207 set $kgm_image_info_path = ((unsigned int *)$kgm_map_user_window)[1]
10208 end
10209 _unmap_user_data_from_task $kgm_taskp
10210
10211 # printf "[%d] = image address %llx path address %llx\n", $kgm_image_info_i, $kgm_image_info_addr, $kgm_image_info_path
10212 _print_image_info $kgm_image_info_addr $kgm_image_info_path
10213
10214 set $kgm_image_info_i = $kgm_image_info_i + 1
10215 end
10216
10217 # $kgm_dyld_load_path may get set when the main executable is processed
10218 # printf "[dyld] = image address %llx path address %llx\n", $kgm_dyld_load_address, $kgm_dyld_load_path
10219 _print_image_info $kgm_dyld_load_address $kgm_dyld_load_path
10220
10221 end
10222
10223 define showuserlibraries
10224 set $kgm_taskp = (task_t)$arg0
10225 set $kgm_dyld_image_info = $kgm_taskp->all_image_info_addr
10226
10227 set $kgm_map = $kgm_taskp->map
10228 set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
10229
10230 if ($kgm_dyld_image_info != 0)
10231 printf "address "
10232 if $kgm_task_64
10233 printf " "
10234 end
10235 printf " type "
10236 printf " uuid "
10237 printf "path\n"
10238
10239 _print_images_for_dyld_image_info $kgm_taskp $kgm_task_64 $kgm_dyld_image_info
10240 else
10241 printf "No dyld shared library information available for task\n"
10242 end
10243 end
10244 document showuserlibraries
10245 Syntax: (gdb) showuserlibraries <task_t>
10246 | For a given user task, inspect the dyld shared library state and print
10247 | information about all Mach-O images.
10248 end
10249
10250 define showuserdyldinfo
10251 set $kgm_taskp = (task_t)$arg0
10252 set $kgm_dyld_all_image_infos_address = (unsigned long long)$kgm_taskp->all_image_info_addr
10253
10254 set $kgm_map = $kgm_taskp->map
10255 set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
10256
10257 if ($kgm_dyld_all_image_infos_address != 0)
10258
10259 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 112
10260
10261 set $kgm_dyld_all_image_infos = (unsigned char *)$kgm_map_user_window
10262 set $kgm_dyld_all_image_infos_version = ((unsigned int *)$kgm_dyld_all_image_infos)[0]
10263 if ($kgm_dyld_all_image_infos_version > 12)
10264 printf "Unknown dyld all_image_infos version number %d\n", $kgm_dyld_all_image_infos_version
10265 end
10266
10267 # Find fields by byte offset. We assume at least version 9 is supported
10268 if $kgm_task_64
10269 set $kgm_dyld_all_image_infos_infoArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[4])
10270 set $kgm_dyld_all_image_infos_infoArray = *(unsigned long long *)(&$kgm_dyld_all_image_infos[8])
10271 set $kgm_dyld_all_image_infos_notification = *(unsigned long long *)(&$kgm_dyld_all_image_infos[16])
10272 set $kgm_dyld_all_image_infos_processDetachedFromSharedRegion = *(unsigned char *)(&$kgm_dyld_all_image_infos[24])
10273 set $kgm_dyld_all_image_infos_libSystemInitialized = *(unsigned char *)(&$kgm_dyld_all_image_infos[25])
10274 set $kgm_dyld_all_image_infos_dyldImageLoadAddress = *(unsigned long long *)(&$kgm_dyld_all_image_infos[32])
10275 set $kgm_dyld_all_image_infos_jitInfo = *(unsigned long long *)(&$kgm_dyld_all_image_infos[40])
10276 set $kgm_dyld_all_image_infos_dyldVersion = *(unsigned long long *)(&$kgm_dyld_all_image_infos[48])
10277 set $kgm_dyld_all_image_infos_errorMessage = *(unsigned long long *)(&$kgm_dyld_all_image_infos[56])
10278 set $kgm_dyld_all_image_infos_terminationFlags = *(unsigned long long *)(&$kgm_dyld_all_image_infos[64])
10279 set $kgm_dyld_all_image_infos_coreSymbolicationShmPage = *(unsigned long long *)(&$kgm_dyld_all_image_infos[72])
10280 set $kgm_dyld_all_image_infos_systemOrderFlag = *(unsigned long long *)(&$kgm_dyld_all_image_infos[80])
10281 set $kgm_dyld_all_image_infos_uuidArrayCount = *(unsigned long long *)(&$kgm_dyld_all_image_infos[88])
10282 set $kgm_dyld_all_image_infos_uuidArray = *(unsigned long long *)(&$kgm_dyld_all_image_infos[96])
10283 set $kgm_dyld_all_image_infos_dyldAllImageInfosAddress = *(unsigned long long *)(&$kgm_dyld_all_image_infos[104])
10284 else
10285 set $kgm_dyld_all_image_infos_infoArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[4])
10286 set $kgm_dyld_all_image_infos_infoArray = *(unsigned int *)(&$kgm_dyld_all_image_infos[8])
10287 set $kgm_dyld_all_image_infos_notification = *(unsigned int *)(&$kgm_dyld_all_image_infos[12])
10288 set $kgm_dyld_all_image_infos_processDetachedFromSharedRegion = *(unsigned char *)(&$kgm_dyld_all_image_infos[16])
10289 set $kgm_dyld_all_image_infos_libSystemInitialized = *(unsigned char *)(&$kgm_dyld_all_image_infos[17])
10290 set $kgm_dyld_all_image_infos_dyldImageLoadAddress = *(unsigned int *)(&$kgm_dyld_all_image_infos[20])
10291 set $kgm_dyld_all_image_infos_jitInfo = *(unsigned int *)(&$kgm_dyld_all_image_infos[24])
10292 set $kgm_dyld_all_image_infos_dyldVersion = *(unsigned int *)(&$kgm_dyld_all_image_infos[28])
10293 set $kgm_dyld_all_image_infos_errorMessage = *(unsigned int *)(&$kgm_dyld_all_image_infos[32])
10294 set $kgm_dyld_all_image_infos_terminationFlags = *(unsigned int *)(&$kgm_dyld_all_image_infos[36])
10295 set $kgm_dyld_all_image_infos_coreSymbolicationShmPage = *(unsigned int *)(&$kgm_dyld_all_image_infos[40])
10296 set $kgm_dyld_all_image_infos_systemOrderFlag = *(unsigned int *)(&$kgm_dyld_all_image_infos[44])
10297 set $kgm_dyld_all_image_infos_uuidArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[48])
10298 set $kgm_dyld_all_image_infos_uuidArray = *(unsigned int *)(&$kgm_dyld_all_image_infos[52])
10299 set $kgm_dyld_all_image_infos_dyldAllImageInfosAddress = *(unsigned int *)(&$kgm_dyld_all_image_infos[56])
10300 end
10301
10302 _unmap_user_data_from_task $kgm_taskp
10303
10304 printf " version %u\n", $kgm_dyld_all_image_infos_version
10305 printf " infoArrayCount %u\n", $kgm_dyld_all_image_infos_infoArrayCount
10306 printf " infoArray "
10307 showuserptr $kgm_dyld_all_image_infos_infoArray
10308 printf "\n"
10309 printf " notification "
10310 showuserptr $kgm_dyld_all_image_infos_notification
10311 printf "\n"
10312 printf "processDetachedFromSharedRegion %d\n", $kgm_dyld_all_image_infos_processDetachedFromSharedRegion
10313 printf " libSystemInitialized %d\n", $kgm_dyld_all_image_infos_libSystemInitialized
10314 printf " dyldImageLoadAddress "
10315 showuserptr $kgm_dyld_all_image_infos_dyldImageLoadAddress
10316 printf "\n"
10317 printf " jitInfo "
10318 showuserptr $kgm_dyld_all_image_infos_jitInfo
10319 printf "\n"
10320 printf " dyldVersion "
10321 showuserptr $kgm_dyld_all_image_infos_dyldVersion
10322 printf "\n"
10323 printf " "
10324 _print_path_for_image $kgm_dyld_all_image_infos_dyldVersion
10325 printf "\n"
10326
10327 printf " errorMessage "
10328 showuserptr $kgm_dyld_all_image_infos_errorMessage
10329 printf "\n"
10330 if $kgm_dyld_all_image_infos_errorMessage != 0
10331 printf " "
10332 _print_path_for_image $kgm_dyld_all_image_infos_errorMessage
10333 printf "\n"
10334 end
10335
10336 printf " terminationFlags "
10337 showuserptr $kgm_dyld_all_image_infos_terminationFlags
10338 printf "\n"
10339 printf " coreSymbolicationShmPage "
10340 showuserptr $kgm_dyld_all_image_infos_coreSymbolicationShmPage
10341 printf "\n"
10342 printf " systemOrderFlag "
10343 showuserptr $kgm_dyld_all_image_infos_systemOrderFlag
10344 printf "\n"
10345 printf " uuidArrayCount "
10346 showuserptr $kgm_dyld_all_image_infos_uuidArrayCount
10347 printf "\n"
10348 printf " uuidArray "
10349 showuserptr $kgm_dyld_all_image_infos_uuidArray
10350 printf "\n"
10351 printf " dyldAllImageInfosAddress "
10352 showuserptr $kgm_dyld_all_image_infos_dyldAllImageInfosAddress
10353 printf "\n"
10354 printf " (currently "
10355 showuserptr $kgm_dyld_all_image_infos_address
10356 printf ")\n"
10357
10358 if $kgm_task_64
10359 set $kgm_dyld_all_image_infos_address = $kgm_dyld_all_image_infos_address + 112
10360 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 64
10361 set $kgm_dyld_all_image_infos_v10 = (unsigned char *)$kgm_map_user_window
10362 set $kgm_dyld_all_image_infos_initialImageCount = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[112-112])
10363 set $kgm_dyld_all_image_infos_errorKind = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[120-112])
10364 set $kgm_dyld_all_image_infos_errorClientOfDylibPath = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[128-112])
10365 set $kgm_dyld_all_image_infos_errorTargetDylibPath = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[136-112])
10366 set $kgm_dyld_all_image_infos_errorSymbol = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[144-112])
10367 set $kgm_dyld_all_image_infos_sharedCacheSlide = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[152-112])
10368
10369 _unmap_user_data_from_task $kgm_taskp
10370 else
10371 set $kgm_dyld_all_image_infos_address = $kgm_dyld_all_image_infos_address + 60
10372 _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 64
10373 set $kgm_dyld_all_image_infos_v10 = (unsigned char *)$kgm_map_user_window
10374 set $kgm_dyld_all_image_infos_initialImageCount = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[60-60])
10375 set $kgm_dyld_all_image_infos_errorKind = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[64-60])
10376 set $kgm_dyld_all_image_infos_errorClientOfDylibPath = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[68-60])
10377 set $kgm_dyld_all_image_infos_errorTargetDylibPath = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[72-60])
10378 set $kgm_dyld_all_image_infos_errorSymbol = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[76-60])
10379 set $kgm_dyld_all_image_infos_sharedCacheSlide = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[80-60])
10380 _unmap_user_data_from_task $kgm_taskp
10381 end
10382
10383 if $kgm_dyld_all_image_infos_version >= 10
10384 printf " initialImageCount "
10385 showuserptr $kgm_dyld_all_image_infos_initialImageCount
10386 printf "\n"
10387 end
10388
10389 if $kgm_dyld_all_image_infos_version >= 11
10390 printf " errorKind "
10391 showuserptr $kgm_dyld_all_image_infos_errorKind
10392 printf "\n"
10393 printf " errorClientOfDylibPath "
10394 showuserptr $kgm_dyld_all_image_infos_errorClientOfDylibPath
10395 printf "\n"
10396 if $kgm_dyld_all_image_infos_errorClientOfDylibPath != 0
10397 printf " "
10398 _print_path_for_image $kgm_dyld_all_image_infos_errorClientOfDylibPath
10399 printf "\n"
10400 end
10401 printf " errorTargetDylibPath "
10402 showuserptr $kgm_dyld_all_image_infos_errorTargetDylibPath
10403 printf "\n"
10404 if $kgm_dyld_all_image_infos_errorTargetDylibPath != 0
10405 printf " "
10406 _print_path_for_image $kgm_dyld_all_image_infos_errorTargetDylibPath
10407 printf "\n"
10408 end
10409 printf " errorSymbol "
10410 showuserptr $kgm_dyld_all_image_infos_errorSymbol
10411 printf "\n"
10412 if $kgm_dyld_all_image_infos_errorSymbol != 0
10413 printf " "
10414 _print_path_for_image $kgm_dyld_all_image_infos_errorSymbol
10415 printf "\n"
10416 end
10417 end
10418
10419 if $kgm_dyld_all_image_infos_version >= 12
10420 printf " sharedCacheSlide "
10421 showuserptr $kgm_dyld_all_image_infos_sharedCacheSlide
10422 printf "\n"
10423 end
10424
10425 else
10426 printf "No dyld information available for task\n"
10427 end
10428 end
10429 document showuserdyldinfo
10430 Syntax: (gdb) showuserdyldinfo <task_t>
10431 | For a given user task, inspect the dyld global info and print
10432 | out all fields, including error messages.
10433 end
10434
10435 define showkerneldebugheader
10436 printf "kd_buf "
10437 showptrhdrpad
10438 printf "CPU Thread "
10439 showptrhdrpad
10440 printf "Timestamp S/E Class Sub Code Code Specific Info\n"
10441 end
10442
10443 define _printevflags
10444 if $arg0 & 1
10445 printf "EV_RE "
10446 end
10447 if $arg0 & 2
10448 printf "EV_WR "
10449 end
10450 if $arg0 & 4
10451 printf "EV_EX "
10452 end
10453 if $arg0 & 8
10454 printf "EV_RM "
10455 end
10456
10457 if $arg0 & 0x00100
10458 printf "EV_RBYTES "
10459 end
10460 if $arg0 & 0x00200
10461 printf "EV_WBYTES "
10462 end
10463 if $arg0 & 0x00400
10464 printf "EV_RCLOSED "
10465 end
10466 if $arg0 & 0x00800
10467 printf "EV_RCONN "
10468 end
10469 if $arg0 & 0x01000
10470 printf "EV_WCLOSED "
10471 end
10472 if $arg0 & 0x02000
10473 printf "EV_WCONN "
10474 end
10475 if $arg0 & 0x04000
10476 printf "EV_OOB "
10477 end
10478 if $arg0 & 0x08000
10479 printf "EV_FIN "
10480 end
10481 if $arg0 & 0x10000
10482 printf "EV_RESET "
10483 end
10484 if $arg0 & 0x20000
10485 printf "EV_TIMEOUT "
10486 end
10487 end
10488
10489 define showkerneldebugbufferentry
10490 set $kgm_kdebug_entry = (kd_buf *) $arg0
10491
10492 set $kgm_debugid = $kgm_kdebug_entry->debugid
10493 set $kgm_kdebug_arg1 = $kgm_kdebug_entry->arg1
10494 set $kgm_kdebug_arg2 = $kgm_kdebug_entry->arg2
10495 set $kgm_kdebug_arg3 = $kgm_kdebug_entry->arg3
10496 set $kgm_kdebug_arg4 = $kgm_kdebug_entry->arg4
10497
10498 if $kgm_lp64
10499 set $kgm_kdebug_cpu = $kgm_kdebug_entry->cpuid
10500 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0xFFFFFFFF
10501 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
10502 else
10503 set $kgm_kdebug_cpu = ($kgm_kdebug_entry->timestamp >> 56)
10504 set $kgm_ts_hi = ($kgm_kdebug_entry->timestamp >> 32) & 0x00FFFFFF
10505 set $kgm_ts_lo = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
10506 end
10507
10508 set $kgm_kdebug_class = ($kgm_debugid >> 24) & 0x000FF
10509 set $kgm_kdebug_subclass = ($kgm_debugid >> 16) & 0x000FF
10510 set $kgm_kdebug_code = ($kgm_debugid >> 2) & 0x03FFF
10511 set $kgm_kdebug_qual = ($kgm_debugid ) & 0x00003
10512
10513 if $kgm_kdebug_qual == 0
10514 set $kgm_kdebug_qual = '-'
10515 else
10516 if $kgm_kdebug_qual == 1
10517 set $kgm_kdebug_qual = 'S'
10518 else
10519 if $kgm_kdebug_qual == 2
10520 set $kgm_kdebug_qual = 'E'
10521 else
10522 if $kgm_kdebug_qual == 3
10523 set $kgm_kdebug_qual = '?'
10524 end
10525 end
10526 end
10527 end
10528
10529 # preamble and qual
10530
10531 showptr $kgm_kdebug_entry
10532 printf " %d ", $kgm_kdebug_cpu
10533 showptr $kgm_kdebug_entry->arg5
10534 printf " 0x%08X%08X %c ", $kgm_ts_hi, $kgm_ts_lo, $kgm_kdebug_qual
10535
10536 # class
10537
10538 if $kgm_kdebug_class == 1
10539 printf "MACH"
10540 else
10541 if $kgm_kdebug_class == 2
10542 printf "NET "
10543 else
10544 if $kgm_kdebug_class == 3
10545 printf "FS "
10546 else
10547 if $kgm_kdebug_class == 4
10548 printf "BSD "
10549 else
10550 if $kgm_kdebug_class == 5
10551 printf "IOK "
10552 else
10553 if $kgm_kdebug_class == 6
10554 printf "DRVR"
10555 else
10556 if $kgm_kdebug_class == 7
10557 printf "TRAC"
10558 else
10559 if $kgm_kdebug_class == 8
10560 printf "DLIL"
10561 else
10562 if $kgm_kdebug_class == 8
10563 printf "SEC "
10564 else
10565 if $kgm_kdebug_class == 20
10566 printf "MISC"
10567 else
10568 if $kgm_kdebug_class == 31
10569 printf "DYLD"
10570 else
10571 if $kgm_kdebug_class == 32
10572 printf "QT "
10573 else
10574 if $kgm_kdebug_class == 33
10575 printf "APPS"
10576 else
10577 if $kgm_kdebug_class == 255
10578 printf "MIG "
10579 else
10580 printf "0x%02X", $kgm_kdebug_class
10581 end
10582 end
10583 end
10584 end
10585 end
10586 end
10587 end
10588 end
10589 end
10590 end
10591 end
10592 end
10593 end
10594 end
10595
10596 # subclass and code
10597
10598 printf " 0x%02X %5d ", $kgm_kdebug_subclass, $kgm_kdebug_code
10599
10600 # space for debugid-specific processing
10601
10602 # EVPROC from bsd/kern/sys_generic.c
10603
10604 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT)
10605 if $kgm_debugid == 0x14100048
10606 printf "waitevent "
10607 if $kgm_kdebug_arg1 == 1
10608 printf "before sleep"
10609 else
10610 if $kgm_kdebug_arg1 == 2
10611 printf "after sleep"
10612 else
10613 printf "????????????"
10614 end
10615 end
10616 printf " chan=0x%08X ", $kgm_kdebug_arg2
10617 else
10618 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_START)
10619 if $kgm_debugid == 0x14100049
10620 printf "waitevent "
10621 else
10622 # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_END)
10623 if $kgm_debugid == 0x1410004a
10624 printf "waitevent error=%d ", $kgm_kdebug_arg1
10625 printf "eqp=0x%08X ", $kgm_kdebug_arg4
10626 _printevflags $kgm_kdebug_arg3
10627 printf "er_handle=%d ", $kgm_kdebug_arg2
10628 else
10629 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_START)
10630 if $kgm_debugid == 0x14100059
10631 printf "evprocdeque proc=0x%08X ", $kgm_kdebug_arg1
10632 if $kgm_kdebug_arg2 == 0
10633 printf "remove first "
10634 else
10635 printf "remove 0x%08X ", $kgm_kdebug_arg2
10636 end
10637 else
10638 # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_END)
10639 if $kgm_debugid == 0x1410005a
10640 printf "evprocdeque "
10641 if $kgm_kdebug_arg1 == 0
10642 printf "result=NULL "
10643 else
10644 printf "result=0x%08X ", $kgm_kdebug_arg1
10645 end
10646 else
10647 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_START)
10648 if $kgm_debugid == 0x14100041
10649 printf "postevent "
10650 _printevflags $kgm_kdebug_arg1
10651 else
10652 # MISCDBG_CODE(DBG_EVENT,DBG_POST)
10653 if $kgm_debugid == 0x14100040
10654 printf "postevent "
10655 printf "evq=0x%08X ", $kgm_kdebug_arg1
10656 printf "er_eventbits="
10657 _printevflags $kgm_kdebug_arg2
10658 printf "mask="
10659 _printevflags $kgm_kdebug_arg3
10660 else
10661 # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_END)
10662 if $kgm_debugid == 0x14100042
10663 printf "postevent "
10664 else
10665 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_START)
10666 if $kgm_debugid == 0x14100055
10667 printf "evprocenque eqp=0x%08d ", $kgm_kdebug_arg1
10668 if $kgm_kdebug_arg2 & 1
10669 printf "EV_QUEUED "
10670 end
10671 _printevflags $kgm_kdebug_arg3
10672 else
10673
10674 # MISCDBG_CODE(DBG_EVENT,DBG_EWAKEUP)
10675 if $kgm_debugid == 0x14100050
10676 printf "evprocenque before wakeup eqp=0x%08d ", $kgm_kdebug_arg4
10677 else
10678 # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_END)
10679 if $kgm_debugid == 0x14100056
10680 printf "evprocenque "
10681 else
10682 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_START)
10683 if $kgm_debugid == 0x1410004d
10684 printf "modwatch "
10685 else
10686 # MISCDBG_CODE(DBG_EVENT,DBG_MOD)
10687 if $kgm_debugid == 0x1410004c
10688 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
10689 _printevflags $kgm_kdebug_arg2
10690 printf "evq=0x%08X ", $kgm_kdebug_arg3
10691 else
10692 # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_END)
10693 if $kgm_debugid == 0x1410004e
10694 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
10695 printf "ee_eventmask="
10696 _printevflags $kgm_kdebug_arg2
10697 printf "sp=0x%08X ", $kgm_kdebug_arg3
10698 printf "flag="
10699 _printevflags $kgm_kdebug_arg4
10700 else
10701 printf "arg1=0x%08X ", $kgm_kdebug_arg1
10702 printf "arg2=0x%08X ", $kgm_kdebug_arg2
10703 printf "arg3=0x%08X ", $kgm_kdebug_arg3
10704 printf "arg4=0x%08X ", $kgm_kdebug_arg4
10705 end
10706 end
10707 end
10708 end
10709 end
10710 end
10711 end
10712 end
10713 end
10714 end
10715 end
10716 end
10717 end
10718 end
10719
10720 # finish up
10721
10722 printf "\n"
10723 end
10724
10725 define showkerneldebugbuffercpu
10726 set $kgm_cpu_number = (int) $arg0
10727 set $kgm_entry_count = (int) $arg1
10728 set $kgm_debugentriesfound = 0
10729
10730 if (kdebug_flags & 0x80000000) # 0x80000000 == KDBG_BFINIT
10731 showkerneldebugheader
10732
10733 if $kgm_entry_count == 0
10734 printf "<count> is 0, dumping 50 entries\n"
10735 set $kgm_entry_count = 50
10736 end
10737
10738 if $kgm_cpu_number >= kd_cpus
10739 printf "cpu number too big\n"
10740 else
10741 set $kgm_kdbp = &kdbip[$kgm_cpu_number]
10742 set $kgm_kdsp = $kgm_kdbp->kd_list_head
10743 while (($kgm_kdsp != 0) && ($kgm_entry_count > 0))
10744 if $kgm_kdsp->kds_readlast != $kgm_kdsp->kds_bufptr
10745 set $kgm_kds_bufptr = $kgm_kdsp->kds_bufptr
10746 while (($kgm_kds_bufptr > $kgm_kdsp->kds_readlast) && ($kgm_entry_count > 0))
10747 set $kgm_kds_bufptr = $kgm_kds_bufptr - 1
10748 set $kgm_entry_count = $kgm_entry_count - 1
10749 showkerneldebugbufferentry $kgm_kds_bufptr
10750 end
10751 end
10752 set $kgm_kdsp = $kgm_kdsp->kds_next
10753 end
10754 end
10755 else
10756 printf "Trace buffer not enabled\n"
10757 end
10758 end
10759
10760 document showkerneldebugbuffercpu
10761 Syntax: showkerneldebugbuffercpu <cpu> <count>
10762 | Prints the last N entries in the kernel debug buffer for CPU x.
10763 end
10764
10765 define showkerneldebugbuffer
10766
10767 if (kdebug_flags & 0x80000000) # 0x80000000 == KDBG_BFINIT
10768
10769 set $kgm_entrycount = (int) $arg0
10770
10771 if $kgm_entrycount == 0
10772 printf "<count> is 0, dumping 50 entries per cpu\n"
10773 set $kgm_entrycount = 50
10774 end
10775
10776 set $kgm_cpu = (int) 0
10777
10778 while $kgm_cpu < kd_cpus
10779 showkerneldebugbuffercpu $kgm_cpu $kgm_entrycount
10780 set $kgm_cpu = $kgm_cpu + 1
10781 end
10782 else
10783 printf "Trace buffer not enabled\n"
10784 end
10785 end
10786
10787 document showkerneldebugbuffer
10788 Syntax: showkerneldebugbuffer <count>
10789 | Prints the last N entries in the kernel debug buffer per cpu. i.e. showkerneldebugbuffer 50 will
10790 | display the last 50 entries in each CPU's debug buffer.
10791 end
10792
10793 define showallvmstats
10794 printf " pid command #ents wired vsize rsize max rsize\n"
10795 printf " (pages) (pages) (pages) (pages)\n"
10796 set $kgm_head_taskp = &tasks
10797 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
10798 while $kgm_taskp != $kgm_head_taskp
10799 set $kgm_procp = (struct proc *)($kgm_taskp->bsd_info)
10800 set $kgm_mapp = (struct _vm_map *)($kgm_taskp->map)
10801 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
10802 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
10803 end
10804 end
10805
10806 document showallvmstats
10807 Syntax: showallvmstats
10808 | prints a summary of vm statistics in a table format
10809 end
10810
10811 define memstats
10812 if ($kgm_mtype == $kgm_mtype_arm)
10813 printf "kern_memorystatus_level: %8d\n", kern_memorystatus_level
10814 end
10815 printf "vm_page_throttled_count: %8d\n", vm_page_throttled_count
10816 printf "vm_page_active_count: %8d\n", vm_page_active_count
10817 printf "vm_page_inactive_count: %8d\n", vm_page_inactive_count
10818 printf "vm_page_wire_count: %8d\n", vm_page_wire_count
10819 printf "vm_page_free_count: %8d\n", vm_page_free_count
10820 printf "vm_page_purgeable_count: %8d\n", vm_page_purgeable_count
10821 printf "vm_page_inactive_target: %8d\n", vm_page_inactive_target
10822 printf "vm_page_free_target: %8d\n", vm_page_free_target
10823 printf "inuse_ptepages_count: %8d\n", inuse_ptepages_count
10824 printf "vm_page_free_reserved: %8d\n", vm_page_free_reserved
10825 end
10826
10827 document memstats
10828 Syntax: (gdb) memstats
10829 | Prints out a summary of various memory statistics. In particular vm_page_wire_count should
10830 | be greater than 2K or you are under memory pressure.
10831 end
10832
10833 define show_user_registers
10834 showuserregisters $arg0
10835 end
10836
10837 document show_user_registers
10838 Syntax: show_user_registers <thread_address>
10839 | Display user registers associated with a kernel thread
10840 | properly displays the 32 bit or 64 bit registers for intel architecture
10841 end
10842
10843 define _cmp
10844 set $cmp0 = $arg0
10845 set $cmp1 = $arg1
10846
10847 # check for end of string. cmp0 can be longer than cmp1. it
10848 # can't be shorter.
10849 if $cmp1 == '\0'
10850 set $kgm_strcmp_result = 0
10851 set $kgm_strcmp_done = 1
10852 end
10853
10854 if !$kgm_strcmp_done && $cmp0 == '\0'
10855 set $kgm_strcmp_result = -1
10856 set $kgm_strcmp_done = 1
10857 end
10858
10859 # do they match?
10860 if !$kgm_strcmp_done
10861 set $kgm_strcmp_result = (uint8_t) $cmp0 - (uint8_t) $cmp1
10862 if $kgm_strcmp_result != 0
10863 set $kgm_strcmp_done = 1
10864 end
10865 end
10866 end
10867
10868 define _cmp_arg64
10869 set $cmp = $arg1
10870 set $masked = $cmp & 0xFF
10871 _cmp $arg0[0] $masked
10872
10873 if !$kgm_strcmp_done
10874 set $cmp = $cmp >> 8
10875 set $masked = $cmp & 0xFF
10876 _cmp $arg0[1] $masked
10877 end
10878 if !$kgm_strcmp_done
10879 set $cmp = $cmp >> 8
10880 set $masked = $cmp & 0xFF
10881 _cmp $arg0[2] $masked
10882 end
10883 if !$kgm_strcmp_done
10884 set $cmp = $cmp >> 8
10885 set $masked = $cmp & 0xFF
10886 _cmp $arg0[3] $masked
10887 end
10888 if !$kgm_strcmp_done
10889 set $cmp = $cmp >> 8
10890 set $masked = $cmp & 0xFF
10891 _cmp $arg0[4] $masked
10892 end
10893 if !$kgm_strcmp_done
10894 set $cmp = $cmp >> 8
10895 set $masked = $cmp & 0xFF
10896 _cmp $arg0[5] $masked
10897 end
10898 if !$kgm_strcmp_done
10899 set $cmp = $cmp >> 8
10900 set $masked = $cmp & 0xFF
10901 _cmp $arg0[6] $masked
10902 end
10903 if !$kgm_strcmp_done
10904 set $cmp = $cmp >> 8
10905 set $masked = $cmp & 0xFF
10906 _cmp $arg0[7] $masked
10907 end
10908 end
10909
10910 define strcmp_arg_pack64
10911 set $kgm_strcmp_arg = ((((((((((((((uint64_t) $arg7 << 8) | $arg6) << 8) | $arg5) << 8) | $arg4) << 8) | $arg3) << 8) | $arg2) << 8) | $arg1) << 8) | $arg0
10912 end
10913
10914 document strcmp_arg_pack64
10915 Syntax: strcmp_arg_pack64 <a> <b> <c> <d> <e <f> <g> <h>
10916 | Packs a string given as 8 character arguments into a 64-bit int stored in
10917 | $kgm_strcmp_arg. Use 0 or '\0' for unused arguments. The encoded string
10918 | is suitable for use by strcmp_nomalloc and setfindregistrystr.
10919 | e.g., strcmp_arg_pack64 'H' 'e' 'l' 'l' 'o' 0 0 0
10920 | packs "Hello" into $kgm_strcmp_arg.
10921 |
10922 end
10923
10924 define strcmp_nomalloc
10925 set $str = $arg0
10926 set $count = $argc - 1
10927
10928 set $kgm_strcmp_result = 0
10929 set $kgm_strcmp_done = 0
10930
10931 if $count > 0
10932 _cmp_arg64 $str $arg1
10933 end
10934 if !$kgm_strcmp_done && $count > 1
10935 set $str = $str + 8
10936 _cmp_arg64 $str $arg2
10937 end
10938 if !$kgm_strcmp_done && $count > 2
10939 set $str = $str + 8
10940 _cmp_arg64 $str $arg3
10941 end
10942 if !$kgm_strcmp_done && $count > 3
10943 set $str = $str + 8
10944 _cmp_arg64 $str $arg4
10945 end
10946 if !$kgm_strcmp_done && $count > 4
10947 set $str = $str + 8
10948 _cmp_arg64 $str $arg5
10949 end
10950 if !$kgm_strcmp_done && $count > 5
10951 set $str = $str + 8
10952 _cmp_arg64 $str $arg6
10953 end
10954 if !$kgm_strcmp_done && $count > 6
10955 set $str = $str + 8
10956 _cmp_arg64 $str $arg7
10957 end
10958 if !$kgm_strcmp_done && $count > 7
10959 set $str = $str + 8
10960 _cmp_arg64 $str $arg8
10961 end
10962 if !$kgm_strcmp_done && $count > 8
10963 set $str = $str + 8
10964 _cmp_arg64 $str $arg9
10965 end
10966 end
10967
10968 document strcmp_nomalloc
10969 Syntax: strcmp_nomalloc <string> <a> [b] [c] [d] [e] [f] [g] [h] [i]
10970 | Given a pre-allocated <string>, perform a string compare with the
10971 | encoded string stored in arguments a - i. The result is stored in
10972 | $kgm_strcmp_result.
10973 |
10974 | For example, the following will result in $kgm_strcmp_result == 0:
10975 | strcmp_arg_pack64 'D' 'a' 'r' 'w' 'i' 'n' ' ' 'K'
10976 | strcmp_nomalloc version $kgm_strcmp_arg
10977 end
10978
10979 define memcpy
10980 set $kgm_dst = (unsigned char *)$arg0
10981 set $kgm_src = (unsigned char *)$arg1
10982 set $kgm_count = $arg2
10983
10984 # printf "src %p dst %p len %d\n", $kgm_src, $kgm_dst, $kgm_count
10985
10986 while ($kgm_count >= 8)
10987 set *(unsigned long long *)$kgm_dst = *(unsigned long long *)$kgm_src
10988
10989 set $kgm_dst = $kgm_dst + 8
10990 set $kgm_src = $kgm_src + 8
10991 set $kgm_count = $kgm_count - 8
10992 end
10993 while ($kgm_count > 0)
10994 set *$kgm_dst = *$kgm_src
10995
10996 set $kgm_dst = $kgm_dst + 1
10997 set $kgm_src = $kgm_src + 1
10998 set $kgm_count = $kgm_count - 1
10999 end
11000 end
11001
11002 document memcpy
11003 Syntax: memcpy <dst> <src> <n>
11004 | Given two addresses that are accessible by the debugger, perform
11005 | a memory copy of <n> bytes from <src> to <dst>
11006 end
11007
11008 # _pci_cfg_addr_value $addr $size
11009 define _pci_cfg_addr_value
11010 readphysint $arg0 $arg1 $kgm_lcpu_self
11011 set $kgm_pci_cfg_value = $kgm_readphysint_result
11012 end
11013
11014
11015 set $kgm_pci_cfg_init = 0
11016 define _pci_cfg_init
11017 # get this from the registry if it exists there
11018 if $kgm_pci_cfg_init == 0
11019 strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
11020 set $AppleACP = $kgm_strcmp_arg
11021 strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
11022 set $IPlatfor = $kgm_strcmp_arg
11023 strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
11024 set $mExpert = $kgm_strcmp_arg
11025 setfindregistrystr $AppleACP $IPlatfor $mExpert
11026
11027 set $olddepth = $kgm_reg_depth_max
11028 set $kgm_reg_depth_max = 2
11029 _findregistryentry
11030 set $kgm_reg_depth_max = $olddepth
11031
11032 if $kgm_registry_entry
11033 strcmp_arg_pack64 'a' 'c' 'p' 'i' '-' 'm' 'm' 'c'
11034 set $acpi_mmc = $kgm_strcmp_arg
11035 strcmp_arg_pack64 'f' 'g' '-' 's' 'e' 'g' '0' 0
11036 set $fg_seg0 = $kgm_strcmp_arg
11037 setfindregistrystr $acpi_mmc $fg_seg0
11038
11039 _findregistryprop $kgm_registry_entry
11040 if $kgm_registry_value
11041 set $kgm_pci_cfg_base = ((OSNumber *) $kgm_registry_value)->value
11042 set $kgm_pci_cfg_init = 1
11043 end
11044 end
11045 end
11046
11047 # search for 0:0:0 in likely places if the above fails
11048 if $kgm_pci_cfg_init == 0
11049 set $kgm_pci_cfg_base = 0xF0000000
11050 while $kgm_pci_cfg_init == 0 && $kgm_pci_cfg_base > 0xA0000000
11051 _pci_cfg_addr_value $kgm_pci_cfg_base 8
11052 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xFF
11053 set $kgm_pci_cfg_init = 1
11054 else
11055 set $kgm_pci_cfg_base = $kgm_pci_cfg_base - 0x10000000
11056 end
11057 end
11058 end
11059 end
11060
11061 # _pci_cfg_addr $bus $dev $fcn $off
11062 define _pci_cfg_addr
11063 set $bus = $arg0
11064 set $dev = $arg1
11065 set $fcn = $arg2
11066 set $off = $arg3
11067
11068 _pci_cfg_init
11069 set $kgm_pci_cfg_addr = $kgm_pci_cfg_base | ($bus << 20) | ($dev << 15) | ($fcn << 12) | $off
11070 end
11071
11072 define _pci_cfg_value
11073 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
11074 _pci_cfg_addr_value $kgm_pci_cfg_addr $arg4
11075 end
11076
11077 define pci_cfg_read8
11078 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 8
11079 printf "%08X: %02X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11080 end
11081
11082 define pci_cfg_read16
11083 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 16
11084 printf "%08X: %04X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11085 end
11086
11087 define pci_cfg_read32
11088 _pci_cfg_value $arg0 $arg1 $arg2 $arg3 32
11089 printf "%08X: %08X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11090 end
11091
11092 document pci_cfg_read8
11093 Syntax: (gdb) pci_cfg_read8 <bus> <dev> <fcn> <off>
11094 | read 8 bits for the given <off> of the pci device located at
11095 | <bus>:<dev>:<fcn>.
11096 end
11097
11098 document pci_cfg_read16
11099 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
11100 | read 16 bits for the given <off> of the pci device located at
11101 | <bus>:<dev>:<fcn>.
11102 end
11103
11104 document pci_cfg_read32
11105 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
11106 | read 32 bits for the given <off> of the pci device located at
11107 | <bus>:<dev>:<fcn>.
11108 end
11109
11110 define pci_cfg_write8
11111 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
11112 writephysint $kgm_pci_cfg_addr 8 $arg4 $kgm_lcpu_self
11113 end
11114
11115 define pci_cfg_write16
11116 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
11117 writephysint $kgm_pci_cfg_addr 16 $arg4 $kgm_lcpu_self
11118 end
11119
11120 define pci_cfg_write32
11121 _pci_cfg_addr $arg0 $arg1 $arg2 $arg3
11122 writephysint $kgm_pci_cfg_addr 32 $arg4 $kgm_lcpu_self
11123 end
11124
11125 document pci_cfg_write8
11126 Syntax: (gdb) pci_cfg_write8 <bus> <dev> <fcn> <off> <value>
11127 | write an 8-bit <value> into the given <off> of the pci device located at
11128 | <bus>:<dev>:<fcn>.
11129 end
11130
11131 document pci_cfg_write16
11132 Syntax: (gdb) pci_cfg_write16 <bus> <dev> <fcn> <off> <value>
11133 | write a 16-bit <value> into the given <off> of the pci device located at
11134 | <bus>:<dev>:<fcn>.
11135 end
11136
11137 document pci_cfg_write32
11138 Syntax: (gdb) pci_cfg_write32 <bus> <dev> <fcn> <off> <value>
11139 | write a 32-bit <value> into the given <off> of the pci device located at
11140 | <bus>:<dev>:<fcn>.
11141 end
11142
11143
11144 define pci_cfg_dump
11145 set $bus = $arg0
11146 set $dev = $arg1
11147 set $fcn = $arg2
11148 set $off = 0
11149
11150 # check for a valid pci device
11151 _pci_cfg_value $bus $dev $fcn $off 8
11152 if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xff
11153 printf " address: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
11154 printf "---------------------------------------------------------"
11155
11156 while $off < 256
11157 _pci_cfg_value $bus $dev $fcn $off 32
11158 if ($off & 0xF) == 0
11159 printf "\n%08X: ", $kgm_pci_cfg_addr
11160 end
11161 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
11162 set $off = $off + 4
11163 end
11164 printf "\n"
11165
11166 # check for pcie extended capability config space
11167 _pci_cfg_value $bus $dev $fcn $off 8
11168 if $kgm_pci_cfg_value < 0xff
11169 while $off < 4096
11170 _pci_cfg_value $bus $dev $fcn $off 32
11171 if ($off & 0xF) == 0
11172 printf "\n%08X: ", $kgm_pci_cfg_addr
11173 end
11174 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
11175 set $off = $off + 4
11176 end
11177 printf "\n"
11178 end
11179 end
11180 end
11181
11182 document pci_cfg_dump
11183 Syntax: (gdb) pci_cfg_dump <bus> <dev> <fcn>
11184 | dump config space for the pci device located at <bus>:<dev>:<fcn>
11185 | if you specify an invalid/inaccessible pci device, nothing will be
11186 | printed out.
11187 end
11188
11189 set $kgm_pci_cfg_bus_start = 0
11190 set $kgm_pci_cfg_bus_max = 8
11191 set $kgm_pci_cfg_device_max = 32
11192 set $kgm_pci_cfg_function_max = 8
11193 define _pci_cfg_scan
11194 set $dump = $arg0
11195
11196 set $bus = $kgm_pci_cfg_bus_start
11197 while $bus < $kgm_pci_cfg_bus_max
11198 # check for bus:0:0 to see if we should
11199 # probe this bus further
11200 _pci_cfg_value $bus 0x0 0x0 0x0 32
11201 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
11202
11203 set $dev = 0
11204 while $dev < $kgm_pci_cfg_device_max
11205
11206 set $fcn = 0
11207 while $fcn < $kgm_pci_cfg_function_max
11208 _pci_cfg_value $bus $dev $fcn 0x0 32
11209 if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
11210 if $dump == 0
11211 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
11212 _pci_cfg_value $bus $dev $fcn 0x8 32
11213 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
11214 else
11215 printf " device: %03X:%03X:%03X\n", $bus, $dev, $fcn
11216 pci_cfg_dump $bus $dev $fcn
11217 printf "\n"
11218 end
11219 end
11220 set $fcn = $fcn + 1
11221 end
11222 set $dev = $dev + 1
11223 end
11224 end
11225 set $bus = $bus + 1
11226 end
11227 end
11228
11229 define pci_cfg_dump_all
11230 _pci_cfg_scan 1
11231 end
11232
11233 document pci_cfg_dump_all
11234 Syntax: (gdb) pci_cfg_dump_all
11235 | dump config spaces for scanned pci devices. the number of busses to scan
11236 | is stored in $kgm_pci_cfg_bus_max. the default for that is 8. you can also
11237 | specify the starting bus with $kgm_pci_cfg_bus_start.
11238 end
11239
11240 define pci_cfg_scan
11241 printf "bus:dev:fcn: vendor device rev | class\n"
11242 printf "---------------------------------------\n"
11243 _pci_cfg_scan 0
11244 end
11245
11246 document pci_cfg_scan
11247 Syntax: (gdb) pci_cfg_scan
11248 | scan for pci devices. the number of busses to scan is stored in
11249 | $kgm_pci_cfg_bus_max. the default for that is 8. you can also specify the
11250 | starting bus with $kgm_pci_cfg_bus_start.
11251 end
11252
11253 define readioportint
11254 set $kgm_readioportint_result = 0xBAD10AD
11255 # set up the manual KDP packet
11256 set manual_pkt.input = 0
11257 set manual_pkt.len = sizeof(kdp_readioport_req_t)
11258 set $kgm_pkt = (kdp_readioport_req_t *)&manual_pkt.data
11259 set $kgm_pkt->hdr.request = KDP_READIOPORT
11260 set $kgm_pkt->hdr.len = sizeof(kdp_readioport_req_t)
11261 set $kgm_pkt->hdr.is_reply = 0
11262 set $kgm_pkt->hdr.seq = 0
11263 set $kgm_pkt->hdr.key = 0
11264 set $kgm_pkt->address = (uint16_t)$arg0
11265 set $kgm_pkt->nbytes = $arg1 >> 3
11266 set $kgm_pkt->lcpu = (uint16_t)$arg2
11267 set manual_pkt.input = 1
11268 # dummy to make sure manual packet is executed
11269 set $kgm_dummy = &_mh_execute_header
11270 set $kgm_pkt = (kdp_readioport_reply_t *)&manual_pkt.data
11271 if ($kgm_pkt->error == 0)
11272 if $arg1 == 8
11273 set $kgm_readioportint_result = *((uint8_t *) $kgm_pkt->data)
11274 end
11275 if $arg1 == 16
11276 set $kgm_readioportint_result = *((uint16_t *) $kgm_pkt->data)
11277 end
11278 if $arg1 == 32
11279 set $kgm_readioportint_result = *((uint32_t *) $kgm_pkt->data)
11280 end
11281 end
11282 end
11283
11284 define readioport8
11285 set $lcpu = $kgm_lcpu_self
11286 if $argc > 1
11287 set $lcpu = $arg1
11288 end
11289 readioportint $arg0 8 $lcpu
11290 output /a $arg0
11291 printf ":\t0x%02hhx\n", $kgm_readioportint_result
11292 end
11293
11294 define readioport16
11295 set $lcpu = $kgm_lcpu_self
11296 if $argc > 1
11297 set $lcpu = $arg1
11298 end
11299 readioportint $arg0 16 $lcpu
11300 output /a $arg0
11301 printf ":\t0x%04hx\n", $kgm_readioportint_result
11302 end
11303
11304 define readioport32
11305 set $lcpu = $kgm_lcpu_self
11306 if $argc > 1
11307 set $lcpu = $arg1
11308 end
11309 readioportint $arg0 32 $lcpu
11310 output /a $arg0
11311 printf ":\t0x%08x\n", $kgm_readioportint_result
11312 end
11313
11314 document readioport8
11315 | See readioport32.
11316 end
11317
11318 document readioport16
11319 | See readioport32.
11320 end
11321
11322 document readioport32
11323 Syntax: (gdb) readioport32 <port> [lcpu (kernel's numbering convention)]
11324 | Read value stored in the specified IO port. The CPU can be optionally
11325 | specified as well.
11326 end
11327
11328 define writeioportint
11329 # set up the manual KDP packet
11330 set manual_pkt.input = 0
11331 set manual_pkt.len = sizeof(kdp_writeioport_req_t)
11332 set $kgm_pkt = (kdp_writeioport_req_t *)&manual_pkt.data
11333 set $kgm_pkt->hdr.request = KDP_WRITEIOPORT
11334 set $kgm_pkt->hdr.len = sizeof(kdp_writeioport_req_t)
11335 set $kgm_pkt->hdr.is_reply = 0
11336 set $kgm_pkt->hdr.seq = 0
11337 set $kgm_pkt->hdr.key = 0
11338 set $kgm_pkt->address = (uint16_t)$arg0
11339 set $kgm_pkt->nbytes = $arg1 >> 3
11340 set $kgm_pkt->lcpu = (uint16_t)$arg3
11341 if $arg1 == 8
11342 set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
11343 end
11344 if $arg1 == 16
11345 set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
11346 end
11347 if $arg1 == 32
11348 set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
11349 end
11350 set manual_pkt.input = 1
11351 # dummy to make sure manual packet is executed
11352 set $kgm_dummy = &_mh_execute_header
11353 set $kgm_pkt = (kdp_writeioport_reply_t *)&manual_pkt.data
11354 set $kgm_writeioportint_result = $kgm_pkt->error
11355 end
11356
11357 define writeioport8
11358 set $lcpu = $kgm_lcpu_self
11359 if $argc > 2
11360 set $lcpu = $arg2
11361 end
11362 writeioportint $arg0 8 $arg1 $lcpu
11363 end
11364
11365 define writeioport16
11366 set $lcpu = $kgm_lcpu_self
11367 if $argc > 2
11368 set $lcpu = $arg2
11369 end
11370 writeioportint $arg0 16 $arg1 $lcpu
11371 end
11372
11373 define writeioport32
11374 set $lcpu = $kgm_lcpu_self
11375 if $argc > 2
11376 set $lcpu = $arg2
11377 end
11378 writeioportint $arg0 32 $arg1 $lcpu
11379 end
11380
11381 document writeioport8
11382 | See writeioport32.
11383 end
11384
11385 document writeioport16
11386 | See writeioport32.
11387 end
11388
11389 document writeioport32
11390 Syntax: (gdb) writeioport32 <port> <value> [lcpu (kernel's numbering convention)]
11391 | Write the value to the specified IO port. The size of the value is
11392 | determined by the name of the command. The CPU used can be optionally
11393 | specified.
11394 end
11395
11396 define readmsr64int
11397 set $kgm_readmsr64int_result = 0xBAD10AD
11398 # set up the manual KDP packet
11399 set manual_pkt.input = 0
11400 set manual_pkt.len = sizeof(kdp_readmsr64_req_t)
11401 set $kgm_pkt = (kdp_readmsr64_req_t *)&manual_pkt.data
11402 set $kgm_pkt->hdr.request = KDP_READMSR64
11403 set $kgm_pkt->hdr.len = sizeof(kdp_readmsr64_req_t)
11404 set $kgm_pkt->hdr.is_reply = 0
11405 set $kgm_pkt->hdr.seq = 0
11406 set $kgm_pkt->hdr.key = 0
11407 set $kgm_pkt->address = (uint32_t)$arg0
11408 set $kgm_pkt->lcpu = (uint16_t)$arg1
11409 set manual_pkt.input = 1
11410 # dummy to make sure manual packet is executed
11411 set $kgm_dummy = &_mh_execute_header
11412 set $kgm_pkt = (kdp_readmsr64_reply_t *)&manual_pkt.data
11413 if ($kgm_pkt->error == 0)
11414 set $kgm_readmsr64int_result = *((uint64_t *) $kgm_pkt->data)
11415 end
11416 end
11417
11418 define readmsr64
11419 set $lcpu = $kgm_lcpu_self
11420 if $argc > 1
11421 set $lcpu = $arg1
11422 end
11423 readmsr64int $arg0 $lcpu
11424 output /a $arg0
11425 printf ":\t0x%016llx\n", $kgm_readmsr64int_result
11426 end
11427
11428 define writemsr64int
11429 # set up the manual KDP packet
11430 set manual_pkt.input = 0
11431 set manual_pkt.len = sizeof(kdp_writemsr64_req_t)
11432 set $kgm_pkt = (kdp_writemsr64_req_t *)&manual_pkt.data
11433 set $kgm_pkt->hdr.request = KDP_WRITEMSR64
11434 set $kgm_pkt->hdr.len = sizeof(kdp_writemsr64_req_t)
11435 set $kgm_pkt->hdr.is_reply = 0
11436 set $kgm_pkt->hdr.seq = 0
11437 set $kgm_pkt->hdr.key = 0
11438 set $kgm_pkt->address = (uint32_t)$arg0
11439 set $kgm_pkt->lcpu = (uint16_t)$arg2
11440 set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg1
11441 set manual_pkt.input = 1
11442 # dummy to make sure manual packet is executed
11443 set $kgm_dummy = &_mh_execute_header
11444 set $kgm_pkt = (kdp_writemsr64_reply_t *)&manual_pkt.data
11445 set $kgm_writemsr64int_result = $kgm_pkt->error
11446 end
11447
11448 define writemsr64
11449 set $lcpu = $kgm_lcpu_self
11450 if $argc > 2
11451 set $lcpu = $arg2
11452 end
11453 writemsr64int $arg0 $arg1 $lcpu
11454 end
11455
11456 document writemsr64
11457 Syntax: (gdb) writemsr64 <msr> <value> [lcpu (kernel's numbering convention)]
11458 | Write <value> to the specified MSR. The CPU can be optionally specified.
11459 end
11460
11461 document readmsr64
11462 Syntax: (gdb) readmsr64 <msr> [lcpu (kernel's numbering convention)]
11463 | Read the specified MSR. The CPU can be optionally specified.
11464 end
11465
11466 # default if we can't find a registry entry
11467 set $kgm_ioapic_addr = 0xFEC00000
11468 set $kgm_ioapic_init = 0
11469
11470 set $_ioapic_index_off = 0x00
11471 set $_ioapic_data_off = 0x10
11472 set $_ioapic_eoi_off = 0x40
11473
11474 set $_ioapic_index_id = 0x00
11475 set $_ioapic_index_ver = 0x01
11476 set $_ioapic_index_redir_base = 0x10
11477
11478 set $_apic_vector_mask = 0xFF
11479 set $_apic_timer_tsc_deadline = 0x40000
11480 set $_apic_timer_periodic = 0x20000
11481 set $_apic_masked = 0x10000
11482 set $_apic_trigger_level = 0x08000
11483 set $_apic_polarity_high = 0x02000
11484 set $_apic_pending = 0x01000
11485
11486 define _ioapic_init
11487 if $kgm_ioapic_init == 0
11488 strcmp_arg_pack64 'i' 'o' '-' 'a' 'p' 'i' 'c' 0
11489 setfindregistrystr $kgm_strcmp_arg
11490
11491 set $olddepth = $kgm_reg_depth_max
11492 set $kgm_reg_depth_max = 3
11493 _findregistryentry
11494 set $kgm_reg_depth_max = $olddepth
11495
11496 if $kgm_registry_entry
11497 strcmp_arg_pack64 'P' 'h' 'y' 's' 'i' 'c' 'a' 'l'
11498 set $Physical = $kgm_strcmp_arg
11499 strcmp_arg_pack64 ' ' 'A' 'd' 'd' 'r' 'e' 's' 's'
11500 set $_Address = $kgm_strcmp_arg
11501 setfindregistrystr $Physical $_Address
11502
11503 _findregistryprop $kgm_registry_entry
11504 if $kgm_registry_value
11505 set $kgm_ioapic_addr = ((OSNumber *) $kgm_registry_value)->value
11506 end
11507 end
11508 set $kgm_ioapic_index_addr = $kgm_ioapic_addr + $_ioapic_index_off
11509 set $kgm_ioapic_data_addr = $kgm_ioapic_addr + $_ioapic_data_off
11510 set $kgm_ioapic_init = 1
11511 end
11512 end
11513
11514 define _ioapic_addr_value
11515 _ioapic_init
11516 writephysint $kgm_ioapic_index_addr 8 $arg0 $kgm_lcpu_self
11517 if $argc > 1
11518 writephysint $kgm_ioapic_data_addr 32 $arg1 $kgm_lcpu_self
11519 else
11520 readphysint $kgm_ioapic_data_addr 32 $kgm_lcpu_self
11521 set $kgm_ioapic_value = $kgm_readphysint_result
11522 end
11523 end
11524
11525 define _apic_print
11526 set $value = $arg0
11527
11528 printf "[VEC=%3d", $value & $_apic_vector_mask
11529 if $value & $_apic_masked
11530 printf " MASK=yes"
11531 else
11532 printf " MASK=no "
11533 end
11534
11535 if $value & $_apic_trigger_level
11536 printf " TRIG=level"
11537 else
11538 printf " TRIG=edge "
11539 end
11540
11541 if $value & $_apic_polarity_high
11542 printf " POL=high"
11543 else
11544 printf " POL=low "
11545 end
11546
11547 if $value & $_apic_pending
11548 printf " PEND=yes"
11549 else
11550 printf " PEND=no "
11551 end
11552
11553 if $value & $_apic_timer_periodic
11554 printf " PERIODIC"
11555 end
11556 if $value & $_apic_timer_tsc_deadline
11557 printf " TSC_DEADLINE"
11558 end
11559
11560 printf "]\n"
11561 end
11562
11563 define ioapic_read32
11564 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11565 printf "ioapic_read32 not supported on this architecture.\n"
11566 else
11567 _ioapic_addr_value $arg0
11568 printf "IOAPIC[0x%02X]: 0x%08X\n", $arg0, $kgm_ioapic_value
11569 end
11570 end
11571
11572 document ioapic_read32
11573 Syntax: (gdb) ioapic_read <offset>
11574 | Read the IOAPIC register at the offset specified.
11575 end
11576
11577 define ioapic_write32
11578 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11579 printf "ioapic_write32 not supported on this architecture.\n"
11580 else
11581 _ioapic_addr_value $arg0 $arg1
11582 end
11583 end
11584
11585 document ioapic_write32
11586 Syntax: (gdb) ioapic_write32 <offset> <value>
11587 | Write the IOAPIC register at the offset specified.
11588 end
11589
11590 define ioapic_dump
11591 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11592 printf "ioapic_dump not supported on this architecture.\n"
11593 else
11594 # id
11595 _ioapic_addr_value $_ioapic_index_id
11596 printf "IOAPIC[0x%02X] ID: 0x%08X\n", $_ioapic_index_id, $kgm_ioapic_value
11597
11598 # version
11599 _ioapic_addr_value $_ioapic_index_ver
11600 set $maxredir = (($kgm_ioapic_value & 0xFF0000) >> 16) + 1
11601
11602 printf "IOAPIC[0x%02X] VERSION: 0x%08X [", $_ioapic_index_ver, $kgm_ioapic_value
11603 printf "MAXREDIR=%02d PRQ=%d VERSION=0x%02X]\n", $maxredir, ($kgm_ioapic_value >> 15) & 0x1, $kgm_ioapic_value & 0xFF
11604
11605 # all the redir entries
11606 set $i = 0
11607 while $i < $maxredir
11608 set $addr0 = $_ioapic_index_redir_base + ($i << 1)
11609 set $addr1 = $addr0 + 1
11610 _ioapic_addr_value $addr1
11611 printf "IOAPIC[0x%02X] IOREDIR%02d: 0x%08X", $addr0, $i, $kgm_ioapic_value
11612
11613 _ioapic_addr_value $addr0
11614 printf "%08X ", $kgm_ioapic_value
11615 _apic_print $kgm_ioapic_value
11616 set $i = $i + 1
11617 end
11618 end
11619 end
11620
11621 document ioapic_dump
11622 Syntax: (gdb) ioapic_dump
11623 | Dump all the IOAPIC entries.
11624 end
11625
11626
11627 set $_lapic_base_addr = 0xFEE00000
11628 set $_lapic_id = 0x20
11629 set $_lapic_version = 0x30
11630 set $_lapic_tpr = 0x80
11631 set $_lapic_apr = 0x90
11632 set $_lapic_ppr = 0xA0
11633 set $_lapic_eoi = 0xB0
11634 set $_lapic_ldr = 0xD0
11635 set $_lapic_dfr = 0xE0
11636 set $_lapic_sivr = 0xF0
11637
11638 set $_lapic_isr_size = 0x10
11639 set $_lapic_isr_num = 8
11640 set $_lapic_isr0 = 0x100
11641 set $_lapic_tmr0 = 0x180
11642 set $_lapic_irr0 = 0x200
11643
11644 set $_lapic_esr = 0x280
11645 set $_lapic_esr_register = 0x80
11646 set $_lapic_esr_recv_vect = 0x40
11647 set $_lapic_esr_send_vect = 0x20
11648
11649 set $_lapic_icr0 = 0x300
11650 set $_lapic_icr1 = 0x310
11651
11652 set $_lapic_lvt_timer = 0x320
11653 set $_lapic_lvt_thermal = 0x330
11654 set $_lapic_lvt_pmcr = 0x340
11655 set $_lapic_lvt_lint0 = 0x350
11656 set $_lapic_lvt_lint1 = 0x360
11657 set $_lapic_lvt_error = 0x370
11658
11659 set $_lapic_icr = 0x380
11660 set $_lapic_ccr = 0x390
11661 set $_lapic_dcr = 0x3E0
11662
11663 set $_apic_cfg_msr = 0x1B
11664 set $_apic_cfg_msr_x2EN = 0x00000C00
11665 set $_x2apic_enabled = -1
11666
11667 # _lapic_addr $offset returns the actual address to use
11668 define _lapic_addr
11669 if $_x2apic_enabled < 0
11670 readmsr64int $_apic_cfg_msr $kgm_lcpu_self
11671 if ($kgm_readmsr64int_result & $_apic_cfg_msr_x2EN) == $_apic_cfg_msr_x2EN
11672 set $_x2apic_enabled = 1
11673 else
11674 set $_x2apic_enabled = 0
11675 end
11676 end
11677
11678 if $_x2apic_enabled
11679 # x2APIC addresses are MSRs that use xAPIC offsets that
11680 # are 4-bit shifted
11681 set $kgm_lapic_addr = $arg0 >> 4
11682 else
11683 set $kgm_lapic_addr = $_lapic_base_addr + $arg0
11684 end
11685 end
11686
11687 # _lapic_addr_value $offset $lcpu
11688 define _lapic_addr_value
11689 _lapic_addr $arg0
11690 if $_x2apic_enabled
11691 readmsr64int $kgm_lapic_addr $arg1
11692 set $kgm_lapic_value = $kgm_readmsr64int_result
11693 else
11694 readphysint $kgm_lapic_addr 32 $arg1
11695 set $kgm_lapic_value = $kgm_readphysint_result
11696 end
11697 end
11698
11699 # lapic_read32 $offset [$lcpu]
11700 define lapic_read32
11701 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11702 printf "lapic_read32 not supported on this architecture.\n"
11703 else
11704 set $lcpu = $kgm_lcpu_self
11705 if $argc > 1
11706 set $lcpu = $arg1
11707 end
11708 _lapic_addr_value $arg0 $lcpu
11709 printf "LAPIC[0x%03X]: 0x%08X\n", $arg0, $kgm_lapic_value
11710 end
11711 end
11712
11713 document lapic_read32
11714 Syntax: (gdb) apic_read32_cpu <offset> [lcpu (kernel's numbering convention)]
11715 | Read the LAPIC register at the offset specified. The CPU can be optionally
11716 | specified.
11717 end
11718
11719 # lapic_write32 $offset $value [$lcpu]
11720 define lapic_write32
11721 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11722 printf "lapic_write32_cpu not supported on this architecture.\n"
11723 else
11724 set $lcpu = $kgm_lcpu_self
11725 if $argc > 2
11726 set $lcpu = $arg2
11727 end
11728
11729 _lapic_addr $arg0
11730 if $_x2apic_enabled
11731 writemsr64int $kgm_lapic_addr $arg1 $lcpu
11732 else
11733 writephysint $kgm_lapic_addr 32 $arg1 $lcpu
11734 end
11735 end
11736 end
11737
11738 document lapic_write32
11739 Syntax: (gdb) lapic_write32 <offset> <value> [lcpu (kernel's numbering convention)]
11740 | Write the LAPIC register at the offset specified. The CPU can be optionally
11741 | specified.
11742 end
11743
11744 # lapic_dump [lcpu]
11745 define lapic_dump
11746 if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11747 printf "lapic_dump not supported on this architecture.\n"
11748 else
11749 set $lcpu = $kgm_lcpu_self
11750 if $argc > 0
11751 set $lcpu = $arg0
11752 end
11753
11754 _lapic_addr_value $_lapic_id $lcpu
11755
11756 # the above also figures out if we're using an xAPIC or an x2APIC
11757 printf "LAPIC operating mode: "
11758 if $_x2apic_enabled
11759 printf " x2APIC\n"
11760 else
11761 printf " xAPIC\n"
11762 end
11763
11764 printf "LAPIC[0x%03X] ID: 0x%08X\n", $_lapic_id, $kgm_lapic_value
11765
11766 _lapic_addr_value $_lapic_version $lcpu
11767 set $lvt_num = ($kgm_lapic_value >> 16) + 1
11768 printf "LAPIC[0x%03X] VERSION: 0x%08X [VERSION=%d MaxLVT=%d]\n", $_lapic_version, $kgm_lapic_value, $kgm_lapic_value & 0xFF, $lvt_num
11769
11770 _lapic_addr_value $_lapic_tpr $lcpu
11771 printf "LAPIC[0x%03X] TASK PRIORITY: 0x%08X\n", $_lapic_tpr, $kgm_lapic_value
11772
11773 _lapic_addr_value $_lapic_ppr $lcpu
11774 printf "LAPIC[0x%03X] PROCESSOR PRIORITY: 0x%08X\n", $_lapic_ppr, $kgm_lapic_value
11775
11776 _lapic_addr_value $_lapic_ldr $lcpu
11777 printf "LAPIC[0x%03X] LOGICAL DEST: 0x%08X\n", $_lapic_ldr, $kgm_lapic_value
11778
11779 _lapic_addr_value $_lapic_dfr $lcpu
11780 printf "LAPIC[0x%03X] DEST FORMAT: 0x%08X\n", $_lapic_dfr, $kgm_lapic_value
11781
11782 _lapic_addr_value $_lapic_sivr $lcpu
11783 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,
11784
11785 set $i = 0
11786 while $i < $_lapic_isr_num
11787 set $addr = $_lapic_isr0 + $i * $_lapic_isr_size
11788 _lapic_addr_value $addr $lcpu
11789 printf "LAPIC[0x%03X] ISR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
11790 set $i = $i + 1
11791 end
11792
11793 set $i = 0
11794 while $i < $_lapic_isr_num
11795 set $addr = $_lapic_tmr0 + $i * $_lapic_isr_size
11796 _lapic_addr_value $addr $lcpu
11797 printf "LAPIC[0x%03X] TMR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
11798 set $i = $i + 1
11799 end
11800
11801 set $i = 0
11802 while $i < $_lapic_isr_num
11803 set $addr = $_lapic_irr0 + $i * $_lapic_isr_size
11804 _lapic_addr_value $addr $lcpu
11805 printf "LAPIC[0x%03X] IRR[%03d:%03d]: 0x%08X\n", $addr, 32*($i + 1) - 1, 32*$i, $kgm_lapic_value
11806 set $i = $i + 1
11807 end
11808
11809 _lapic_addr_value $_lapic_esr $lcpu
11810 printf "LAPIC[0x%03X] ERROR STATUS: 0x%08X ", $_lapic_esr, $kgm_lapic_value
11811 if $kgm_lapic_value
11812 printf "["
11813 end
11814 if $kgm_lapic_value & $_lapic_esr_register
11815 printf "Register "
11816 end
11817 if $kgm_lapic_value & $_lapic_esr_recv_vect
11818 printf "Received Vector "
11819 end
11820 if $kgm_lapic_value & $_lapic_esr_send_vect
11821 printf "Send Vector"
11822 end
11823 if $kgm_lapic_value
11824 printf "]"
11825 end
11826 printf "\n"
11827
11828 _lapic_addr_value $_lapic_icr1 $lcpu
11829 printf "LAPIC[0x%03X] Interrupt Command: 0x%08X [DEST=%d]\n", $_lapic_icr0, $kgm_lapic_value, $kgm_lapic_value >> 24
11830 _lapic_addr_value $_lapic_icr0 $lcpu
11831 printf " 0x%08X ", $kgm_lapic_value
11832 _apic_print $kgm_lapic_value
11833
11834 if $lvt_num > 0
11835 _lapic_addr_value $_lapic_lvt_timer $lcpu
11836 printf "LAPIC[0x%03X] LVT Timer: 0x%08X ", $_lapic_lvt_timer, $kgm_lapic_value
11837 _apic_print $kgm_lapic_value
11838 end
11839
11840 if $lvt_num > 1
11841 _lapic_addr_value $_lapic_lvt_lint0 $lcpu
11842 printf "LAPIC[0x%03X] LVT LINT0: 0x%08X ", $_lapic_lvt_lint0, $kgm_lapic_value
11843 _apic_print $kgm_lapic_value
11844 end
11845
11846 if $lvt_num > 2
11847 _lapic_addr_value $_lapic_lvt_lint1 $lcpu
11848 printf "LAPIC[0x%03X] LVT LINT1: 0x%08X ", $_lapic_lvt_lint1, $kgm_lapic_value
11849 _apic_print $kgm_lapic_value
11850 end
11851
11852 if $lvt_num > 3
11853 _lapic_addr_value $_lapic_lvt_error $lcpu
11854 printf "LAPIC[0x%03X] LVT Error: 0x%08X ", $_lapic_lvt_error, $kgm_lapic_value
11855 _apic_print $kgm_lapic_value
11856 end
11857
11858 if $lvt_num > 4
11859 _lapic_addr_value $_lapic_lvt_pmcr $lcpu
11860 printf "LAPIC[0x%03X] LVT PerfMon: 0x%08X ", $_lapic_lvt_pmcr, $kgm_lapic_value
11861 _apic_print $kgm_lapic_value
11862 end
11863
11864 if $lvt_num > 5
11865 _lapic_addr_value $_lapic_lvt_thermal $lcpu
11866 printf "LAPIC[0x%03X] LVT Thermal: 0x%08X ", $_lapic_lvt_thermal, $kgm_lapic_value
11867 _apic_print $kgm_lapic_value
11868 end
11869
11870 _lapic_addr_value $_lapic_dcr $lcpu
11871 printf "LAPIC[0x%03X] Timer Divide: 0x%08X [Divide by ", $_lapic_dcr, $kgm_lapic_value
11872 set $kgm_lapic_value = ($kgm_lapic_value & 0x8) >> 1 | $kgm_lapic_value & 0x3
11873 if $kgm_lapic_value == 0x7
11874 printf "1]\n"
11875 else
11876 printf "%d]\n", 2 << $kgm_lapic_value
11877 end
11878
11879 _lapic_addr_value $_lapic_icr $lcpu
11880 printf "LAPIC[0x%03X] Timer Init Count: 0x%08X\n", $_lapic_icr, $kgm_lapic_value
11881
11882 _lapic_addr_value $_lapic_ccr $lcpu
11883 printf "LAPIC[0x%03X] Timer Cur Count: 0x%08X\n", $_lapic_ccr, $kgm_lapic_value
11884 end
11885 end
11886
11887 document lapic_dump
11888 Syntax: (gdb) lapic_dump [lcpu (kernel's numbering convention)]
11889 | Dump all the LAPIC entries. The CPU can be optionally specified.
11890 end
11891
11892 define showknoteheader
11893 printf " knote filter ident kn_ptr status\n"
11894 end
11895
11896 define showknoteint
11897 set $kgm_knotep = ((struct knote *) $arg0)
11898 printf " "
11899 showptr $kgm_knotep
11900 printf " "
11901 set $kgm_filt = -$kgm_knotep->kn_kevent.filter
11902 if ($kgm_filt == 1)
11903 printf "EVFILT_READ "
11904 end
11905 if ($kgm_filt == 2)
11906 printf "EVFILT_WRITE "
11907 end
11908 if ($kgm_filt == 3)
11909 printf "EVFILT_AIO "
11910 end
11911 if ($kgm_filt == 4)
11912 printf "EVFILT_VNODE "
11913 end
11914 if ($kgm_filt == 5)
11915 printf "EVFILT_PROC "
11916 end
11917 if ($kgm_filt == 6)
11918 printf "EVFILT_SIGNAL "
11919 end
11920 if ($kgm_filt == 7)
11921 printf "EVFILT_TIMER "
11922 end
11923 if ($kgm_filt == 8)
11924 printf "EVFILT_MACHPORT"
11925 end
11926 if ($kgm_filt == 9)
11927 printf "EVFILT_FS "
11928 end
11929 if ($kgm_filt == 10)
11930 printf "EVFILT_USER "
11931 end
11932 if ($kgm_filt == 11)
11933 printf "EVFILT_SESSION "
11934 end
11935 printf "%7d ", $kgm_knotep->kn_kevent.ident
11936 showptr $kgm_knotep->kn_ptr.p_fp
11937 printf " "
11938 if ($kgm_knotep->kn_status == 0)
11939 printf "-"
11940 else
11941 if ($kgm_knotep->kn_status & 0x01)
11942 printf "A"
11943 end
11944 if ($kgm_knotep->kn_status & 0x02)
11945 printf "Q"
11946 end
11947 if ($kgm_knotep->kn_status & 0x04)
11948 printf "Dis"
11949 end
11950 if ($kgm_knotep->kn_status & 0x08)
11951 printf "Dr"
11952 end
11953 if ($kgm_knotep->kn_status & 0x10)
11954 printf "Uw"
11955 end
11956 if ($kgm_knotep->kn_status & 0x20)
11957 printf "Att"
11958 end
11959 if ($kgm_knotep->kn_status & 0x40)
11960 printf "Stq"
11961 end
11962 end
11963 printf "\n"
11964 end
11965
11966 define showprocknotes
11967 showknoteheader
11968 set $kgm_fdp = ((proc_t)$arg0)->p_fd
11969 set $kgm_knlist = $kgm_fdp->fd_knlist
11970 set $i = 0
11971 while (($i < $kgm_fdp->fd_knlistsize) && ($kgm_knlist != 0))
11972 set $kgm_kn = ((struct knote *)$kgm_knlist[$i].slh_first)
11973 while ($kgm_kn != 0)
11974 showknoteint $kgm_kn
11975 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
11976 end
11977 set $i = $i + 1
11978 end
11979 set $kgm_knhash = $kgm_fdp->fd_knhash
11980 set $i = 0
11981 while (($i < $kgm_fdp->fd_knhashmask + 1) && ($kgm_knhash != 0))
11982 set $kgm_kn = ((struct knote *)$kgm_knhash[$i].slh_first)
11983 while ($kgm_kn != 0)
11984 showknoteint $kgm_kn
11985 set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
11986 end
11987 set $i = $i + 1
11988 end
11989 end
11990
11991 define showallknotes
11992 set $kgm_head_taskp = &tasks
11993 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
11994 while $kgm_taskp != $kgm_head_taskp
11995 showtaskheader
11996 showtaskint $kgm_taskp
11997 showprocknotes $kgm_taskp->bsd_info
11998 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
11999 end
12000 end
12001 document showprocknotes
12002 Syntax: showprocknotes <proc>
12003 | Displays filter and status information for every kevent registered for
12004 | the process.
12005 end
12006
12007 #
12008 # Device node related debug macros
12009 #
12010
12011 define _showtty
12012 set $kgm_tty = (struct tty *) $arg0
12013 printf "tty struct at "
12014 showptr $kgm_tty
12015 printf "\n"
12016 printf "-last input to raw queue:\n"
12017 p $kgm_tty->t_rawq->c_cs
12018 printf "-last input to canonical queue:\n"
12019 p $kgm_tty->t_canq->c_cs
12020 printf "-last output data:\n"
12021 p $kgm_tty->t_outq->c_cs
12022 printf "state:\n"
12023 if ($kgm_tty->t_state & 0x00000001)
12024 printf " TS_SO_OLOWAT (Wake up when output <= low water)\n"
12025 end
12026 if ($kgm_tty->t_state & 0x00000002)
12027 printf " TS_ASYNC (async I/O mode)\n"
12028 else
12029 printf " - (synchronous I/O mode)\n"
12030 end
12031 if ($kgm_tty->t_state & 0x00000004)
12032 printf " TS_BUSY (Draining output)\n"
12033 end
12034 if ($kgm_tty->t_state & 0x00000008)
12035 printf " TS_CARR_ON (Carrier is present)\n"
12036 else
12037 printf " - (Carrier is NOT present)\n"
12038 end
12039 if ($kgm_tty->t_state & 0x00000010)
12040 printf " TS_FLUSH (Outq has been flushed during DMA)\n"
12041 end
12042 if ($kgm_tty->t_state & 0x00000020)
12043 printf " TS_ISOPEN (Open has completed)\n"
12044 else
12045 printf " - (Open has NOT completed)\n"
12046 end
12047 if ($kgm_tty->t_state & 0x00000040)
12048 printf " TS_TBLOCK (Further input blocked)\n"
12049 end
12050 if ($kgm_tty->t_state & 0x00000080)
12051 printf " TS_TIMEOUT (Wait for output char processing)\n"
12052 end
12053 if ($kgm_tty->t_state & 0x00000100)
12054 printf " TS_TTSTOP (Output paused)\n"
12055 end
12056 if ($kgm_tty->t_state & 0x00000200)
12057 printf " TS_WOPEN (Open in progress)\n"
12058 end
12059 if ($kgm_tty->t_state & 0x00000400)
12060 printf " TS_XCLUDE (Tty requires exclusivity)\n"
12061 end
12062 if ($kgm_tty->t_state & 0x00000800)
12063 printf " TS_BKSL (State for lowercase \\ work)\n"
12064 end
12065 if ($kgm_tty->t_state & 0x00001000)
12066 printf " TS_CNTTB (Counting tab width, ignore FLUSHO)\n"
12067 end
12068 if ($kgm_tty->t_state & 0x00002000)
12069 printf " TS_ERASE (Within a \\.../ for PRTRUB)\n"
12070 end
12071 if ($kgm_tty->t_state & 0x00004000)
12072 printf " TS_LNCH (Next character is literal)\n"
12073 end
12074 if ($kgm_tty->t_state & 0x00008000)
12075 printf " TS_TYPEN (Retyping suspended input (PENDIN))\n"
12076 end
12077 if ($kgm_tty->t_state & 0x00010000)
12078 printf " TS_CAN_BYPASS_L_RINT (Device in "raw" mode)\n"
12079 end
12080 if ($kgm_tty->t_state & 0x00020000)
12081 printf " TS_CONNECTED (Connection open)\n"
12082 else
12083 printf " - (Connection NOT open)\n"
12084 end
12085 if ($kgm_tty->t_state & 0x00040000)
12086 printf " TS_SNOOP (Device is being snooped on)\n"
12087 end
12088 if ($kgm_tty->t_state & 0x80000)
12089 printf " TS_SO_OCOMPLETE (Wake up when output completes)\n"
12090 end
12091 if ($kgm_tty->t_state & 0x00100000)
12092 printf " TS_ZOMBIE (Connection lost)\n"
12093 end
12094 if ($kgm_tty->t_state & 0x00200000)
12095 printf " TS_CAR_OFLOW (For MDMBUF - handle in driver)\n"
12096 end
12097 if ($kgm_tty->t_state & 0x00400000)
12098 printf " TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)\n"
12099 end
12100 if ($kgm_tty->t_state & 0x00800000)
12101 printf " TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)\n"
12102 end
12103 # xxx todo: do we care about decoding flags?
12104 printf "flags: 0x%08x\n", $kgm_tty->t_flags
12105 printf "foreground process group: "
12106 showptr $kgm_tty->t_pgrp
12107 printf "\n"
12108 printf "enclosing session: "
12109 showptr $kgm_tty->t_session
12110 printf "\n"
12111 printf "Termios:\n"
12112 # XXX todo: decode these flags, someday
12113 printf " Input flags: 0x%08x\n", $kgm_tty->t_termios.c_iflag
12114 printf " Output flags: 0x%08x\n", $kgm_tty->t_termios.c_oflag
12115 printf " Control flags: 0x%08x\n", $kgm_tty->t_termios.c_cflag
12116 printf " Local flags: 0x%08x\n", $kgm_tty->t_termios.c_lflag
12117 printf " Input speed: %d\n", $kgm_tty->t_termios.c_ispeed
12118 printf " Output speed: %d\n", $kgm_tty->t_termios.c_ospeed
12119 # XXX todo: useful to decode t_winsize? t_iokit? c_cc? anything else?
12120 printf "high watermark: %d bytes\n", $kgm_tty->t_hiwat
12121 printf "low watermark: %d bytes\n", $kgm_tty->t_lowat
12122 end
12123
12124 define _showwhohas
12125 # _showwhohas <major> <minor>
12126 printf "fd "
12127 printf "fileglob "
12128 showptrhdrpad
12129 printf "vnode "
12130 showptrhdrpad
12131 printf "process "
12132 showptrhdrpad
12133 printf "name\n"
12134
12135 set $kgm_swh_devnode_dev = (((int) $arg0) << 24) | (int) $arg1
12136 # iterate all tasks to iterate all processes to iterate all
12137 # open files in each process to see who has a given major/minor
12138 # device open
12139 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12140 while $kgm_taskp != $kgm_head_taskp
12141 set $kgm_procp = (proc_t) $kgm_taskp->bsd_info
12142 set $kgm_spf_filedesc = $kgm_procp->p_fd
12143 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
12144 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
12145 set $kgm_spf_count = 0
12146 while (($kgm_spf_ofiles != 0) && ($kgm_spf_count <= $kgm_spf_last))
12147 # only files currently open
12148 if ($kgm_spf_ofiles[$kgm_spf_count] != 0)
12149 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
12150 if ($kgm_spf_fg->fg_type == 1)
12151 # display fd #, fileglob & vnode address, proc name
12152 set $kgm_swh_m_vnode = (vnode_t) $kgm_spf_fg->fg_data
12153 set $kgm_swh_m_vtype = (enum vtype) $kgm_swh_m_vnode->v_type
12154 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)
12155 printf "%-5d ", $kgm_spf_count
12156 showptr $kgm_spf_fg
12157 printf " "
12158 showptr $kgm_swh_m_vnode
12159 printf " "
12160 showptr $kgm_procp
12161 printf " %s\n", $kgm_procp->p_comm
12162 end
12163 end
12164 end
12165 set $kgm_spf_count = $kgm_spf_count + 1
12166 end
12167
12168 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
12169 end
12170 end
12171
12172 define _showvnodedev_cpty
12173 set $kgm_ptmx_major = (int) $arg0
12174 set $kgm_ptmx_minor = (int) $arg1
12175 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
12176 set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
12177 printf " ptmx_ioctl struct at "
12178 showptr $kgm_ptmx_ioctl
12179 printf "\n"
12180 printf " flags:\n"
12181 if ($kgm_ptmx_ioctl->pt_flags & 0x0008)
12182 printf " PF_PKT (packet mode)\n"
12183 end
12184 if ($kgm_ptmx_ioctl->pt_flags & 0x0010)
12185 printf " PF_STOPPED (user told stopped)\n"
12186 end
12187 if ($kgm_ptmx_ioctl->pt_flags & 0x0020)
12188 printf " PF_REMOTE (remote and flow controlled input)\n"
12189 end
12190 if ($kgm_ptmx_ioctl->pt_flags & 0x0040)
12191 printf " PF_NOSTOP"
12192 end
12193 if ($kgm_ptmx_ioctl->pt_flags & 0x0080)
12194 printf " PF_UCNTL (user control mode)\n"
12195 end
12196 if ($kgm_ptmx_ioctl->pt_flags & 0x0100)
12197 printf " PF_UNLOCKED (slave unlock - master open resets)\n"
12198 end
12199 if ($kgm_ptmx_ioctl->pt_flags & 0x0200)
12200 printf " PF_OPEN_M (master is open)\n"
12201 # XXX we should search for who has the master open, but
12202 # XXX each master gets the same minor, even though it
12203 # XXX gets a different vnode. we chold probably change
12204 # XXX this, but to do it we would need some way of
12205 # XXX expressing the information in the vnode structure
12206 # XXX somewhere. If we *did* change it, it would buy us
12207 # XXX the ability to determine who has the corresponding
12208 # XXX master end of the pty open
12209 else
12210 printf " PF_OPEN_M (master is closed)\n"
12211 end
12212 if ($kgm_ptmx_ioctl->pt_flags & 0x0400)
12213 printf " PF_OPEN_S (slave is open)\n"
12214 printf "---vvvvv--- fds open on this device ---vvvvv---\n"
12215 _showwhohas ($kgm_ptmx_major) ($kgm_ptmx_minor)
12216 printf "---^^^^^--- fds open on this device ---^^^^^---\n"
12217 else
12218 printf " - (slave is closed)\n"
12219 end
12220 printf "TTY Specific Information\n"
12221 _showtty $kgm_ptmx_ioctl->pt_tty
12222 end
12223
12224 define showvnodedev
12225 if ($argc == 1)
12226 set $kgm_vnode = (vnode_t) $arg0
12227 set $kgm_vtype = (enum vtype) $kgm_vnode->v_type
12228 if (($kgm_vtype == VBLK) || ($kgm_vtype == VCHR))
12229 set $kgm_devnode = (devnode_t *) $kgm_vnode->v_data
12230 set $kgm_devnode_dev = $kgm_devnode->dn_typeinfo.dev
12231 set $kgm_devnode_major = ($kgm_devnode_dev >> 24) & 0xff
12232 set $kgm_devnode_minor = $kgm_devnode_dev & 0x00ffffff
12233
12234 # boilerplate device information for a vnode
12235 printf "Device Info:\n"
12236 printf " vnode: "
12237 showptr $kgm_vnode
12238 printf "\n"
12239 printf " type: "
12240 if ($kgm_vtype == VBLK)
12241 printf "VBLK "
12242 end
12243 if ($kgm_vtype == VCHR)
12244 printf "VCHR"
12245 end
12246 printf "\n"
12247 printf " name: %s\n", $kgm_vnode->v_name
12248 printf " major, minor: %d, %d\n", $kgm_devnode_major, $kgm_devnode_minor
12249 printf " mode 0%o\n", $kgm_devnode->dn_mode
12250 printf " owner (u,g): %d %d", $kgm_devnode->dn_uid, $kgm_devnode->dn_gid
12251 printf "\n"
12252
12253 # decode device specific data
12254 printf "Device Specific Information: "
12255 if ($kgm_vtype == VBLK)
12256 printf " Sorry, I do not know how to decode block devices yet!\n"
12257 printf " Maybe you can write me!"
12258 end
12259 if ($kgm_vtype == VCHR)
12260 # Device information; this is scanty
12261 # range check
12262 if ($kgm_devnode_major > 42) || ($kgm_devnode_major < 0)
12263 printf "Invalid major #\n"
12264 else
12265 # static assignments in conf
12266 if ($kgm_devnode_major == 0)
12267 printf "Console mux device\n"
12268 else
12269 if ($kgm_devnode_major == 2)
12270 printf "Current tty alias\n"
12271 else
12272 if ($kgm_devnode_major == 3)
12273 printf "NULL device\n"
12274 else
12275 if ($kgm_devnode_major == 4)
12276 printf "Old pty slave\n"
12277 else
12278 if ($kgm_devnode_major == 5)
12279 printf "Old pty master\n"
12280 else
12281 if ($kgm_devnode_major == 6)
12282 printf "Kernel log\n"
12283 else
12284 if ($kgm_devnode_major == 12)
12285 printf "Memory devices\n"
12286 else
12287 # Statically linked dynamic assignments
12288 if cdevsw[$kgm_devnode_major].d_open == ptmx_open
12289 printf "Cloning pty master\n"
12290 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
12291 else
12292 if cdevsw[$kgm_devnode_major].d_open == ptsd_open
12293 printf "Cloning pty slave\n"
12294 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
12295 else
12296 printf "RESERVED SLOT\n"
12297 end
12298 end
12299 end
12300 end
12301 end
12302 end
12303 end
12304 end
12305 end
12306 end
12307 end
12308 else
12309 showptr $kgm_vnode
12310 printf " is not a device\n"
12311 end
12312 else
12313 printf "| Usage:\n|\n"
12314 help showvnodedev
12315 end
12316 end
12317 document showvnodedev
12318 Syntax: (gdb) showvnodedev <vnode>
12319 | showvnodedev Display information about a device vnode
12320 end
12321
12322 define showtty
12323 if ($argc == 1)
12324 _showtty $arg0
12325 else
12326 printf "| Usage:\n|\n"
12327 help showtty
12328 end
12329 end
12330 document showtty
12331 Syntax: (gdb) showtty <tty struct>
12332 | showtty Display information about a struct tty
12333 end
12334
12335 define showeventsourceobject
12336 set $kgm_vt = *((void **) $arg1)
12337 if $kgm_lp64
12338 set $kgm_vt = $kgm_vt - 16
12339 end
12340 pcprint $kgm_vt
12341 end
12342 document showeventsourceobject
12343 Syntax: (gdb) showeventsourceobject <prefix> <object>
12344 | Routine to display information about an IOEventSource subclass.
12345 end
12346
12347 define showworkloopallocator
12348 set $kgm_workloop = (struct IOWorkLoop*)$arg0
12349 set $kgm_bt = (void**)$kgm_workloop->reserved->allocationBacktrace
12350 set $kgm_bt_count = 0
12351 while $kgm_bt_count != (sizeof(IOWorkLoop::ExpansionData.allocationBacktrace) / sizeof(IOWorkLoop::ExpansionData.allocationBacktrace[0]))
12352 set $kgm_frame_address = (void*)$kgm_bt[$kgm_bt_count]
12353 if $kgm_frame_address != 0
12354 if (((unsigned long) $kgm_frame_address < (unsigned long) &_mh_execute_header || \
12355 (unsigned long) $kgm_frame_address >= (unsigned long) &last_kernel_symbol ) \
12356 && ($kgm_show_kmod_syms == 0))
12357 showkmodaddr $kgm_frame_address
12358 else
12359 output /a $kgm_frame_address
12360 end
12361 printf "\n"
12362 end
12363 set $kgm_bt_count = $kgm_bt_count + 1
12364 end
12365 end
12366 document showworkloopallocator
12367 Syntax: (gdb) showworkloopallocator <workloop>
12368 | Routine to display the backtrace of the thread which allocated the workloop in question. Only
12369 | valid on DEBUG kernels.
12370 end
12371
12372 define showworkloopeventsources
12373 set $kgm_eventsource = (struct IOEventSource*)$arg0
12374 while $kgm_eventsource != 0
12375 printf " "
12376 printf "EventSource:\t"
12377 showptr $kgm_eventsource
12378 printf " Description: "
12379 showeventsourceobject _ $kgm_eventsource
12380 printf "\n"
12381 if $kgm_eventsource->action != 0
12382 printf " "
12383 printf "Action: \t"
12384 pcprint $kgm_eventsource->action
12385 printf "\n"
12386 end
12387 if $kgm_eventsource->owner != 0
12388 printf " "
12389 printf "Owner: \t"
12390 showptr $kgm_eventsource->owner
12391 printf " Description: "
12392 showeventsourceobject _ $kgm_eventsource->owner
12393 printf "\n"
12394 end
12395 set $kgm_eventsource = $kgm_eventsource->eventChainNext
12396 printf "\n"
12397 end
12398 end
12399 document showworkloopeventsources
12400 Syntax: (gdb) showworkloopeventsources
12401 | Routine to walk an IOEventSource chain associated with an IOWorkLoop and print information
12402 | about each event source in the chain.
12403 end
12404
12405 define showworkloopheader
12406 printf "thread "
12407 showptrhdrpad
12408 printf " workloop "
12409 showptrhdrpad
12410 printf " pri state\tLockGroupName\n"
12411 end
12412 document showworkloopheader
12413 Syntax: (gdb) showworkloopheader
12414 | Routine to print out header info about an IOKit workloop.
12415 end
12416
12417 define showworkloop
12418 set $kgm_workloopthread = (struct thread*)$arg0
12419 set $kgm_workloop = (struct IOWorkLoop*)$arg1
12420 showptr $kgm_workloopthread
12421 printf " "
12422 showptr $kgm_workloop
12423 printf " %3d ", $kgm_workloopthread.sched_pri
12424 set $kgm_state = $kgm_workloopthread.state
12425 if $kgm_state & 0x80
12426 printf "I"
12427 end
12428 if $kgm_state & 0x40
12429 printf "P"
12430 end
12431 if $kgm_state & 0x20
12432 printf "A"
12433 end
12434 if $kgm_state & 0x10
12435 printf "H"
12436 end
12437 if $kgm_state & 0x08
12438 printf "U"
12439 end
12440 if $kgm_state & 0x04
12441 printf "R"
12442 end
12443 if $kgm_state & 0x02
12444 printf "S"
12445 end
12446 if $kgm_state & 0x01
12447 printf "W"
12448 end
12449 printf "\t\t"
12450 set $kgm_gateLock = ( struct _IORecursiveLock *)$kgm_workloop->gateLock
12451 if $kgm_gateLock != 0
12452 set $kgm_lockGroup = (struct _lck_grp_*)($kgm_gateLock->group)
12453 printf "%s", $kgm_lockGroup->lck_grp_name
12454 else
12455 printf "No WorkLoop Lock found"
12456 end
12457 printf "\n\n"
12458
12459 #Allocation backtrace is only valid on DEBUG kernels.
12460 #printf "Allocation path:\n\n"
12461 #showworkloopallocator $kgm_workloop
12462 #printf "\n\n"
12463
12464 if $kgm_workloop->eventChain != 0
12465 printf "Active event sources:\n\n"
12466 showworkloopeventsources $kgm_workloop->eventChain
12467 end
12468 if $kgm_workloop->reserved->passiveEventChain != 0
12469 printf "Passive event sources:\n"
12470 showworkloopeventsources $kgm_workloop->reserved->passiveEventChain
12471 end
12472 end
12473 document showworkloop
12474 Syntax: (gdb) showworkloop <thread> <workloop>
12475 | Routine to print out info about an IOKit workloop.
12476 end
12477
12478 define showallworkloopthreads
12479 set $kgm_head_taskp = &tasks
12480 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12481 set $kgm_head_actp = &($kgm_taskp->threads)
12482 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
12483 while $kgm_actp != $kgm_head_actp
12484 if ($kgm_actp->continuation == _ZN10IOWorkLoop10threadMainEv)
12485 showworkloopheader
12486 showworkloop $kgm_actp $kgm_actp->parameter
12487 else
12488 if ($kgm_actp->kernel_stack != 0)
12489 if ($kgm_mtype == $kgm_mtype_x86_64)
12490 #Warning: Grokking stack looking for hopeful workloops until we squirrel some info in thread_t.
12491 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0xB8))
12492 else
12493 if ($kgm_mtype == $kgm_mtype_i386)
12494 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0x3C))
12495 end
12496 end
12497 if ($kgm_workloop != 0)
12498 set $kgm_vt = *((void **) $kgm_workloop)
12499 if $kgm_lp64
12500 set $kgm_vt = $kgm_vt - 16
12501 end
12502 if ($kgm_vt == &_ZTV10IOWorkLoop)
12503 showworkloopheader
12504 showworkloop $kgm_actp $kgm_workloop
12505 end
12506 end
12507 end
12508 end
12509 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
12510 end
12511 printf "\n"
12512 end
12513 document showallworkloopthreads
12514 Syntax: (gdb) showallworkloopthreads
12515 | Routine to print out info about all IOKit workloop threads in the system. This macro will find
12516 | all IOWorkLoop threads blocked in continuations and on i386 and x86_64 systems will make a
12517 | best-effort guess to find any workloops that are actually not blocked in a continuation. For a
12518 | complete list, it is best to compare the output of this macro against the output of 'showallstacks'.
12519 end
12520
12521 define showthreadfortid
12522 set $kgm_id_found = 0
12523
12524 set $kgm_head_taskp = &tasks
12525 set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12526 while $kgm_taskp != $kgm_head_taskp
12527 set $kgm_head_actp = &($kgm_taskp->threads)
12528 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
12529 while $kgm_actp != $kgm_head_actp
12530 set $kgm_thread = *(struct thread *)$kgm_actp
12531 set $kgm_thread_id = $kgm_thread.thread_id
12532 if ($kgm_thread_id == $arg0)
12533 showptr $kgm_actp
12534 printf "\n"
12535 set $kgm_id_found = 1
12536 loop_break
12537 end
12538 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
12539 end
12540 if ($kgm_id_found == 1)
12541 loop_break
12542 end
12543 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
12544 end
12545 if ($kgm_id_found == 0)
12546 printf "Not a valid thread_id\n"
12547 end
12548 end
12549
12550 document showthreadfortid
12551 Syntax: showthreadfortid <thread_id>
12552 |The thread structure contains a unique thread_id value for each thread.
12553 |This command is used to retrieve the address of the thread structure(thread_t)
12554 |corresponding to a given thread_id.
12555 end
12556
12557 define showtaskbusyportsint
12558 set $kgm_isp = ((task_t)$arg0)->itk_space
12559 set $kgm_iindex = 0
12560 while ( $kgm_iindex < $kgm_isp->is_table_size )
12561 set $kgm_iep = &($kgm_isp->is_table[$kgm_iindex])
12562 if $kgm_iep->ie_bits & 0x00020000
12563 set $kgm_port = ((ipc_port_t)$kgm_iep->ie_object)
12564 if $kgm_port->ip_messages.data.port.msgcount > 0
12565 showport $kgm_port
12566 end
12567 end
12568 set $kgm_iindex = $kgm_iindex + 1
12569 end
12570 end
12571
12572 define showtaskbusyports
12573 showtaskbusyportsint $arg0
12574 end
12575
12576 document showtaskbusyports
12577 Syntax: showtaskbusyports <task>
12578 |Routine to print information about receive rights belonging to this task that
12579 |have enqueued messages. This is often a sign of a blocked or hung process.
12580 end
12581
12582 define showallbusyports
12583 set $kgm_head_taskp = &tasks
12584 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
12585 while $kgm_cur_taskp != $kgm_head_taskp
12586 showtaskbusyportsint $kgm_cur_taskp
12587 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
12588 end
12589 end
12590
12591 document showallbusyports
12592 Syntax: showallbusyports
12593 |Routine to print information about all receive rights on the system that
12594 |have enqueued messages.
12595 end
12596
12597 define showallproviders
12598 set $kgm_providerp = dtrace_provider
12599 while $kgm_providerp
12600 p *(dtrace_provider_t *)$kgm_providerp
12601 printf "\n"
12602 set $kgm_providerp = (dtrace_provider_t *)($kgm_providerp->dtpv_next)
12603 end
12604 end
12605
12606 document showallproviders
12607 Syntax: showallproviders
12608 | Display summary listing of all dtrace_providers
12609 end
12610
12611 define showmodctlheader
12612 printf "modctl "
12613 showptrhdrpad
12614 printf " stale "
12615 showptrhdrpad
12616 printf " symbols "
12617 showptrhdrpad
12618 printf " address "
12619 showptrhdrpad
12620 printf " size "
12621 showptrhdrpad
12622 printf " loadid loaded nenabled flags name\n"
12623 end
12624
12625 define showmodctlint
12626 set $kgm_modctlp = (struct modctl *)$arg0
12627 showptr $kgm_modctlp
12628 printf " "
12629 showptr $kgm_modctlp->mod_stale
12630 printf " "
12631 showptr $kgm_modctlp->mod_user_symbols
12632 printf " "
12633 showptr $kgm_modctlp->mod_address
12634 printf " "
12635 showptr $kgm_modctlp->mod_size
12636 printf " "
12637 printf "%6d ", $kgm_modctlp->mod_loadcnt
12638 printf "%6d ", $kgm_modctlp->mod_loaded
12639 printf "%6d ", $kgm_modctlp->mod_nenabled
12640 printf " 0x%x ", $kgm_modctlp->mod_flags
12641 printf "%s\n", $kgm_modctlp->mod_modname
12642 end
12643
12644 define showmodctl
12645 showmodctlheader
12646 showmodctlint $arg0
12647 end
12648 document showmodctl
12649 Syntax: (gdb) showmodctl <addr>
12650 | Display info about a dtrace modctl
12651 end
12652
12653 define showallmodctls
12654 showmodctlheader
12655 set $kgm_modctlp = (struct modctl *)dtrace_modctl_list
12656 while $kgm_modctlp
12657 showmodctlint $kgm_modctlp
12658 set $kgm_modctlp = $kgm_modctlp->mod_next
12659 end
12660 end
12661 document showallmodctls
12662 Syntax: (gdb) showallmodctls
12663 | Display summary listing of all dtrace modctls
12664 end
12665
12666 define showfbtprobe
12667 printf "Be very patient, this traverses a large list \n"
12668 set $kgm_indx = 0
12669 set $kgm_found = 0
12670 set $kgm_depth = 0
12671 while $kgm_indx < fbt_probetab_size && !$kgm_found
12672 set $kgm_fbt_probep = (struct fbt_probe *)fbt_probetab[$kgm_indx]
12673 set $kgm_depth = 0
12674 if $kgm_fbt_probep
12675 set $kgm_probeid = (struct fbt_probe *)$kgm_fbt_probep->fbtp_id
12676 if $kgm_probeid == $arg0
12677 set $kgm_found = 1
12678 loop_break
12679 else
12680 set $kgm_fbt_probep = $kgm_fbt_probep->fbtp_hashnext
12681 while $kgm_fbt_probep
12682 set $kgm_depth++
12683 set $kgm_probeid = (struct fbt_probe *)$kgm_fbt_probep->fbtp_id
12684 if $kgm_probeid == $arg0
12685 set $kgm_found = 1
12686 loop_break
12687 else
12688 set $kgm_fbt_probep = $kgm_fbt_probep->fbtp_hashnext
12689 end
12690 end
12691 end
12692 end
12693 if !$kgm_found
12694 set $kgm_indx++
12695 else
12696 printf "fbt_probetab[index=%d], depth=%d, 0x%x\n", $kgm_indx, $kgm_depth, $kgm_fbt_probep
12697 printf "(gdb) p *(struct fbt_probe *)0x%x\n", $kgm_fbt_probep
12698 p *(struct fbt_probe *)$kgm_fbt_probep
12699 set $kgm_fbtp_ctl = (struct fbt_probe *)$kgm_fbt_probep->fbtp_ctl
12700 showmodctl $kgm_fbtp_ctl
12701 loop_break
12702 end
12703 end
12704 end
12705 document showfbtprobe
12706 Syntax: (gdb) showfbtprobe <id>
12707 | Display info about an fbt probe given an id.
12708 | Traverses fbt_probetab and matches <id> with fbtp_id.
12709 | The <id> is found using dtrace -l
12710 end
12711
12712 define showzstacktrace
12713 set $kgm_trace = (void*)$arg0
12714 if ($argc == 1)
12715 set $kgm_trace_size = 15
12716 end
12717 if ($argc == 2)
12718 set $kgm_trace_size = $arg1
12719 end
12720 set $kgm_trace_current = 0
12721 while ($kgm_trace_current < $kgm_trace_size)
12722 set $kgm_trace_addr = (void**)$kgm_trace + $kgm_trace_current
12723 set $kgm_trace_value = *((void**)$kgm_trace_addr)
12724 #printf "\t\t"
12725 output /a $kgm_trace_value
12726 set $kgm_trace_current = $kgm_trace_current + 1
12727 printf "\n"
12728 end
12729 end
12730
12731 document showzstacktrace
12732 Syntax: showzstacktrace <saved stacktrace> [size]
12733 | Routine to print a stacktrace stored by OSBacktrace.
12734 | size is optional, defaults to 15.
12735 end
12736
12737 define showzalloc
12738 set $kgm_zallocation = zallocations[$arg0]
12739 print $kgm_zallocation
12740 showztrace $kgm_zallocation->za_trace_index
12741 end
12742
12743 document showzalloc
12744 Syntax: showzalloc <index>
12745 | Prints a zallocation from the zallocations array based off its index,
12746 | and prints the associated symbolicated backtrace.
12747 end
12748
12749 define showztrace
12750 set $kgm_ztrace = &ztraces[$arg0]
12751 showztraceaddr $kgm_ztrace
12752 end
12753
12754 document showztrace
12755 Syntax: showztrace <trace index>
12756 | Prints the backtrace from the ztraces array at index
12757 end
12758
12759 define showztraceaddr
12760 print *$arg0
12761 showzstacktrace $arg0->zt_stack ($arg0)->zt_depth
12762 end
12763
12764 document showztraceaddr
12765 Syntax: showztraceaddr <trace address>
12766 | Prints the struct ztrace passed in
12767 end
12768
12769 #TODO: Iterate through the hash table, or make top_ztrace accurate in the face of deallocations (better idea).
12770 define showtopztrace
12771 set $kgm_top_ztrace = top_ztrace
12772 printf "Index: %d\n", (top_ztrace - ztraces)
12773 showztraceaddr $kgm_top_ztrace
12774 end
12775
12776 document showtopztrace
12777 Syntax: showtopztrace
12778 | Shows the ztrace with the biggest size. (according to top_ztrace, not by iterating through the hash table)
12779 end
12780
12781 define showzallocs
12782 set $kgm_zallocation_current_index = 0
12783 set $kgm_zallocations_count = 0
12784 set $kgm_max_zallocation = zleak_alloc_buckets
12785 printf "INDEX ADDRESS "
12786 if $kgm_lp64
12787 printf " "
12788 end
12789 printf "TRACE SIZE\n"
12790 while ($kgm_zallocation_current_index < $kgm_max_zallocation)
12791 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
12792 if ($kgm_zallocation_current->element != 0)
12793 printf "%5d %p ", $kgm_zallocation_current_index, $kgm_zallocation_current->za_element
12794 printf "%5d %6lu\n", $kgm_zallocation_current->za_trace_index, $kgm_zallocation_current->za_size
12795 set $kgm_zallocations_count = $kgm_zallocations_count + 1
12796 end
12797 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
12798 end
12799 printf "Total allocations: %d\n", $kgm_zallocations_count
12800 end
12801
12802 document showzallocs
12803 Syntax: showzallocs
12804 | Prints all allocations in the zallocations table
12805 end
12806
12807 define showzallocsfortrace
12808 set $kgm_zallocation_current_index = 0
12809 set $kgm_zallocations_count = 0
12810 set $kgm_max_zallocation = zleak_alloc_buckets
12811 printf "INDEX ADDRESS "
12812 if $kgm_lp64
12813 printf " "
12814 end
12815 printf "SIZE\n"
12816 while ($kgm_zallocation_current_index < $kgm_max_zallocation)
12817 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
12818 if ($kgm_zallocation_current->element != 0 && $kgm_zallocation_current->za_trace_index == $arg0)
12819 printf "%5d %p ", $kgm_zallocation_current_index, $kgm_zallocation_current->za_element
12820 printf "%6lu\n", $kgm_zallocation_current->size
12821 set $kgm_zallocations_count = $kgm_zallocations_count + 1
12822 end
12823 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
12824 end
12825 printf "Total allocations: %d\n", $kgm_zallocations_count
12826 end
12827
12828 document showzallocsfortrace
12829 Syntax: showzallocsfortrace <trace index>
12830 | Prints all allocations pointing to the passed in trace's index into ztraces by looking through zallocations table
12831 end
12832
12833 define showztraces
12834 showztracesabove 0
12835 end
12836
12837 document showztraces
12838 Syntax: showztraces
12839 | Prints all traces with size > 0
12840 end
12841
12842 define showztracesabove
12843 set $kgm_ztrace_current_index = 0
12844 set $kgm_ztrace_count = 0
12845 set $kgm_max_ztrace = zleak_trace_buckets
12846 printf "INDEX SIZE\n"
12847 while ($kgm_ztrace_current_index < $kgm_max_ztrace)
12848 set $kgm_ztrace_current = ztraces[$kgm_ztrace_current_index]
12849 if ($kgm_ztrace_current->zt_size > $arg0)
12850 printf "%5d %6lu\n", $kgm_ztrace_current_index, $kgm_ztrace_current->zt_size
12851 set $kgm_ztrace_count = $kgm_ztrace_count + 1
12852 end
12853 set $kgm_ztrace_current_index = $kgm_ztrace_current_index + 1
12854 end
12855 printf "Total traces: %d\n", $kgm_ztrace_count
12856 end
12857
12858 document showztracesabove
12859 Syntax: showztracesabove <size>
12860 | Prints all traces with size greater than X
12861 end
12862
12863 define showztracehistogram
12864 set $kgm_ztrace_current_index = 0
12865 set $kgm_ztrace_count = 0
12866 set $kgm_max_ztrace = zleak_trace_buckets
12867 printf "INDEX HIT_COUNT COLLISIONS\n"
12868 while ($kgm_ztrace_current_index < $kgm_max_ztrace)
12869 set $kgm_ztrace_current = ztraces[$kgm_ztrace_current_index]
12870 if ($kgm_ztrace_current->zt_hit_count != 0)
12871 printf "%5d %5d %5d\n", $kgm_ztrace_current_index, $kgm_ztrace_current->zt_hit_count, $kgm_ztrace_current->zt_collisions
12872 set $kgm_ztrace_count = $kgm_ztrace_count + 1
12873 end
12874 set $kgm_ztrace_current_index = $kgm_ztrace_current_index + 1
12875 end
12876 printf "Total traces: %d\n", $kgm_ztrace_count
12877 end
12878
12879 document showztracehistogram
12880 Syntax: showztracehistogram
12881 | Prints the histogram of the ztrace table
12882 end
12883
12884 define showzallochistogram
12885 set $kgm_zallocation_current_index = 0
12886 set $kgm_zallocations_count = 0
12887 set $kgm_max_zallocation = zleak_alloc_buckets
12888 printf "INDEX HIT_COUNT\n"
12889 while ($kgm_zallocation_current_index < $kgm_max_zallocation)
12890 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
12891 if ($kgm_zallocation_current->za_hit_count != 0)
12892 printf "%5d %5d\n", $kgm_zallocation_current_index, $kgm_zallocation_current->za_hit_count
12893 set $kgm_zallocations_count = $kgm_zallocations_count + 1
12894 end
12895 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
12896 end
12897 printf "Total allocations: %d\n", $kgm_zallocations_count
12898 end
12899
12900 document showzallochistogram
12901 Syntax: showzallochistogram
12902 | Prints the histogram for the zalloc table
12903 end
12904
12905 define showzstats
12906 printf "z_alloc_collisions: %u, z_trace_collisions: %u\n", z_alloc_collisions, z_trace_collisions
12907 printf "z_alloc_overwrites: %u, z_trace_overwrites: %u\n", z_alloc_overwrites, z_trace_overwrites
12908 printf "z_alloc_recorded: %u, z_trace_recorded: %u\n", z_alloc_recorded, z_trace_recorded
12909 end
12910
12911 document showzstats
12912 Syntax: showzstats
12913 | Prints the zone leak detection stats
12914 end
12915
12916
12917 set $kgm_au_sentry_hash_table_size = 97
12918
12919 define showsession1
12920 set $p = (struct au_sentry *)$arg0
12921 showptr $p
12922 printf " 0x%08x 0x%08x 0x%016x", $p->se_auinfo.ai_asid, $p->se_auinfo.ai_auid, $p->se_auinfo.ai_flags
12923 printf " %3ld %3ld", $p->se_refcnt, $p->se_procnt
12924 printf "\n"
12925 end
12926
12927 define showsessionhdr
12928 printf "au_sentry "
12929 showptrhdrpad
12930 printf " ASID AUID FLAGS C P\n"
12931 end
12932
12933 define showsession
12934 showsessionhdr
12935 showsession1 $arg0
12936 end
12937
12938 document showsession
12939 Syntax: showsession
12940 | Display info about a specified audit session
12941 end
12942
12943 define showallsessions
12944 showsessionhdr
12945 set $kgm_au_sentry_hash_table = au_sentry_bucket
12946 set $i = $kgm_au_sentry_hash_table_size - 1
12947 while $i >= 0
12948 set $p = $kgm_au_sentry_hash_table[$i].lh_first
12949 while $p != 0
12950 showsession1 $p
12951 set $p = $p->se_link.le_next
12952 end
12953 set $i = $i - 1
12954 end
12955 end
12956
12957 document showallsessions
12958 Syntax: showallsessions
12959 | Prints the audit sessions in the global hash table
12960 end
12961
12962 define showauhistorystack
12963 set $ii = $arg0
12964 set $pp = (void **)$arg1
12965 while $ii > 0
12966 printf " "
12967 x/i $pp[$ii-1]
12968 set $ii = $ii - 1
12969 end
12970 end
12971
12972 define showauhistory1
12973 set $p = (struct au_history *)$arg0
12974 set $stack_depth = $p->stack_depth
12975 set $stack = $p->stack
12976 showptr $p->ptr
12977 if $p->event == 1
12978 printf " REF"
12979 end
12980 if $p->event == 2
12981 printf " UNREF"
12982 end
12983 if $p->event == 3
12984 printf " BIRTH"
12985 end
12986 if $p->event == 4
12987 printf " DEATH"
12988 end
12989 if $p->event == 5
12990 printf " FIND"
12991 end
12992 set $p = &$p->se
12993 printf " 0x%08x 0x%08x 0x%016x", $p->se_auinfo.ai_asid, $p->se_auinfo.ai_auid, $p->se_auinfo.ai_flags
12994 printf " %3ld %3ld", $p->se_refcnt, $p->se_procnt
12995 printf "\n"
12996 showauhistorystack $stack_depth $stack
12997 end
12998
12999 define showauhistory
13000 set $i = (au_history_index-1) % au_history_size
13001 if au_history_index >= au_history_size
13002 set $n = au_history_size
13003 else
13004 set $n = au_history_index
13005 end
13006 while $n > 0
13007 if au_history[$i].ptr != 0 && (0 == $arg0 || au_history[$i].ptr == $arg0)
13008 printf "[% 4d] ", $i
13009 showauhistory1 &au_history[$i]
13010 end
13011 set $n = $n - 1
13012 set $i = ($i - 1) % au_history_size
13013 end
13014 end
13015
13016 define showallauhistory
13017 showauhistory 0
13018 end
13019
13020 define showkwqheader
13021 printf " kwq "
13022 showptrhdrpad
13023 printf " kwqaddr "
13024 showptrhdrpad
13025 printf " inqueue fakecount highseq lowseq flags lastunlock p_rwwc"
13026 printf "\n "
13027 end
13028
13029 define showkwqint
13030 printf " "
13031 set $kgm_kwq = (ksyn_wait_queue_t)$arg0
13032 showptr $kgm_kwq
13033 printf " "
13034 showptr $kgm_kwq->kw_addr
13035 printf " "
13036 printf " %d ", $kgm_kwq->kw_inqueue
13037 printf " %d ", $kgm_kwq->kw_fakecount
13038 printf " 0x%x ", $kgm_kwq->kw_highseq
13039 printf " 0x%x ", $kgm_kwq->kw_lowseq
13040 printf " 0x%x ", $kgm_kwq->kw_flags
13041 printf " 0x%x ", $kgm_kwq->kw_lastunlockseq
13042 printf " 0x%x ", $kgm_kwq->kw_pre_rwwc
13043 printf "\n"
13044 end
13045
13046 define show_kwq
13047 showkwqheader
13048 showkwqint $arg0
13049 end
13050
13051 document show_kwq
13052 Syntax: (gdb) show_kwq <kwq>
13053 | Display info about one ksyn_wait_queue
13054 end
13055
13056 # Internal routine used by "showpthread_mutex" to abstract possible loads from
13057 # user space
13058 define _loadfrommutex
13059 if (kdp_pmap == 0)
13060 set $kgm_loadval = *(uintptr_t *)$arg0
13061 else
13062 if ($kgm_x86_abi == 0xe)
13063 set $kgm_loadval = *(uint32_t *)$arg0
13064 else
13065 if ($kgm_x86_abi == 0xf)
13066 if ($kgm_mtype == $kgm_mtype_i386)
13067 _loadk32m64 $arg0
13068 set $kgm_loadval = $kgm_k32read64
13069 else
13070 set $kgm_loadval = *(uint32_t *)$arg0
13071 end
13072 end
13073 end
13074 end
13075 end
13076
13077 define show_pthreadmutex
13078 set $newact = (struct thread *) $arg0
13079 set $ourtask = (struct task *)($newact->task)
13080 set $our_user_is64 = ($ourtask->taskFeatures[0] & 0x80000000)
13081 _kgm_flush_loop
13082 set $mutex = (void *)$arg1
13083 set kdp_pmap = $newact->task->map->pmap
13084 _kgm_flush_loop
13085 _kgm_update_loop
13086 set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
13087 set $kgm_x86_abi = $newiss.flavor
13088 if ($our_user_is64 != 0)
13089 printf "\tUser 64Bit\n "
13090 printf "\tSignature: "
13091 set $nextval = $mutex
13092 _loadfrommutex $nextval
13093 printf "0x%x\n",$kgm_loadval
13094 printf "\tflags: "
13095 set $nextval = $mutex + 12
13096 _loadfrommutex $nextval
13097 printf "0x%x\n",$kgm_loadval
13098 printf "\tSeqs: "
13099 set $nextval = $mutex + 20
13100 _loadfrommutex $nextval
13101 printf "0x%x ",$kgm_loadval
13102 set $nextval = $mutex + 24
13103 _loadfrommutex $nextval
13104 printf "0x%x ",$kgm_loadval
13105 set $nextval = $mutex + 28
13106 _loadfrommutex $nextval
13107 printf "0x%x\n",$kgm_loadval
13108 printf "\ttid[0]: "
13109 set $nextval = $mutex + 32
13110 _loadfrommutex $nextval
13111 printf "0x%x\n",$kgm_loadval
13112 printf "\ttid[1]: "
13113 set $nextval = $mutex + 36
13114 _loadfrommutex $nextval
13115 printf "0x%x\n",$kgm_loadval
13116 else
13117 printf "\tUser 32Bit\n "
13118 printf "\tSignature: "
13119 set $nextval = $mutex
13120 _loadfrommutex $nextval
13121 printf "0x%x\n",$kgm_loadval
13122 printf "\tflags: "
13123 set $nextval = $mutex + 8
13124 _loadfrommutex $nextval
13125 printf "0x%x\n",$kgm_loadval
13126 printf "\tSeqs: "
13127 set $nextval = $mutex + 16
13128 _loadfrommutex $nextval
13129 printf "0x%x ",$kgm_loadval
13130 set $nextval = $mutex + 20
13131 _loadfrommutex $nextval
13132 printf "0x%x ",$kgm_loadval
13133 set $nextval = $mutex + 24
13134 _loadfrommutex $nextval
13135 printf "0x%x\n",$kgm_loadval
13136 printf "\ttid[0]: "
13137 set $nextval = $mutex + 32
13138 _loadfrommutex $nextval
13139 printf "0x%x\n",$kgm_loadval
13140 printf "\ttid[1]: "
13141 set $nextval = $mutex + 36
13142 _loadfrommutex $nextval
13143 printf "0x%x\n",$kgm_loadval
13144 end
13145 printf "\n"
13146 resetstacks
13147 end
13148
13149
13150 document show_pthreadmutex
13151 Syntax: (gdb) show_pthreadmutex <thread> <user_mutexaddr>
13152 | Display the mutex contents from userspace.
13153 end
13154
13155
13156 define show_pthreadcondition
13157 set $newact = (struct thread *) $arg0
13158 set $ourtask = (struct task *)($newact->task)
13159 set $our_user_is64 = ($ourtask->taskFeatures[0] & 0x80000000)
13160 _kgm_flush_loop
13161 set $cond = (void *)$arg1
13162 set kdp_pmap = $newact->task->map->pmap
13163 _kgm_flush_loop
13164 _kgm_update_loop
13165 set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
13166 set $kgm_x86_abi = $newiss.flavor
13167 if ($our_user_is64 != 0)
13168 printf "\tUser 64Bit\n "
13169 printf "\tSignature: "
13170 set $nextval = $cond
13171 _loadfrommutex $nextval
13172 printf "0x%x\n",$kgm_loadval
13173 printf "\tflags: "
13174 set $nextval = $cond + 12
13175 _loadfrommutex $nextval
13176 printf "0x%x\n",$kgm_loadval
13177 printf "\tSeqs: "
13178 set $nextval = $cond + 24
13179 _loadfrommutex $nextval
13180 printf "0x%x ",$kgm_loadval
13181 set $nextval = $cond + 28
13182 _loadfrommutex $nextval
13183 printf "0x%x ",$kgm_loadval
13184 set $nextval = $cond + 32
13185 _loadfrommutex $nextval
13186 printf "0x%x\n",$kgm_loadval
13187 printf "\tMutex lowaddr: "
13188 set $nextval = $cond + 16
13189 _loadfrommutex $nextval
13190 printf "0x%08x\n",$kgm_loadval
13191 printf "\tMutex highaddr: "
13192 set $nextval = $cond + 20
13193 _loadfrommutex $nextval
13194 printf "0x%x\n",$kgm_loadval
13195 else
13196 printf "\tUser 32Bit\n "
13197 printf "\tSignature: "
13198 set $nextval = $cond
13199 _loadfrommutex $nextval
13200 printf "0x%x\n",$kgm_loadval
13201 printf "\tflags: "
13202 set $nextval = $cond + 8
13203 _loadfrommutex $nextval
13204 printf "0x%x\n",$kgm_loadval
13205 printf "\tSeqs: "
13206 set $nextval = $cond + 16
13207 _loadfrommutex $nextval
13208 printf "0x%x ",$kgm_loadval
13209 set $nextval = $cond + 20
13210 _loadfrommutex $nextval
13211 printf "0x%x ",$kgm_loadval
13212 set $nextval = $cond + 24
13213 _loadfrommutex $nextval
13214 printf "0x%x\n",$kgm_loadval
13215 printf "\tMutex addr: "
13216 set $nextval = $cond + 12
13217 _loadfrommutex $nextval
13218 printf "0x%x\n",$kgm_loadval
13219 end
13220 printf "\n"
13221 resetstacks
13222 end
13223
13224
13225 document show_pthreadcondition
13226 Syntax: (gdb) show_pthreadcondition <thread> <user_cvaddr>
13227 | Display the condition variable contents from userspace.
13228 end
13229
13230 define processortimers
13231 set $kgm_p = processor_list
13232 printf "Processor\t\t\t Last dispatch\t\t Next deadline\t\t difference\n"
13233 while $kgm_p
13234 printf "Processor %d: %p\t", $kgm_p->cpu_id, $kgm_p
13235 printf " 0x%016llx\t", $kgm_p->last_dispatch
13236 set $kgm_rt_timer = &(cpu_data_ptr[$kgm_p->cpu_id].rtclock_timer)
13237 printf " 0x%016llx \t", $kgm_rt_timer->deadline
13238 set $kgm_rt_diff = ((long long)$kgm_p->last_dispatch) - ((long long)$kgm_rt_timer->deadline)
13239 printf " 0x%016llx ", $kgm_rt_diff
13240 # normally the $kgm_rt_diff will be close to the last dispatch time, or negative
13241 # When it isn't, mark the result as bad. This is a suggestion, not an absolute
13242 if ( ($kgm_rt_diff > 0) && ((long long)$kgm_p->last_dispatch) - ($kgm_rt_diff + 1) > 0 )
13243 printf "probably BAD\n"
13244 else
13245 printf "(ok)\n"
13246 end
13247 # dump the call entries (Intel only)
13248 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
13249 printf "Next deadline set at: 0x%016llx. Timer call list:", $kgm_rt_timer->when_set
13250 set $kgm_entry = (queue_t *)$kgm_rt_timer->queue
13251 if ($kgm_entry == $kgm_rt_timer)
13252 printf " (empty)\n"
13253 else
13254 printf "\n entry: "
13255 showptrhdrpad
13256 printf "deadline soft_deadline delta (*func)(param0,param1)\n"
13257 while $kgm_entry != $kgm_rt_timer
13258 set $kgm_timer_call = (timer_call_t) $kgm_entry
13259 set $kgm_call_entry = (struct call_entry *) $kgm_entry
13260 printf " "
13261 showptr $kgm_entry
13262 printf ": 0x%016llx 0x%016llx 0x%08x (%p)(%p,%p)\n", \
13263 $kgm_call_entry->deadline, \
13264 $kgm_timer_call->soft_deadline, \
13265 ($kgm_call_entry->deadline - $kgm_timer_call->soft_deadline), \
13266 $kgm_call_entry->func, \
13267 $kgm_call_entry->param0, $kgm_call_entry->param1
13268 set $kgm_entry = $kgm_entry->next
13269 end
13270 end
13271 end
13272 set $kgm_p = $kgm_p->processor_list
13273 end
13274 printf "\n"
13275 end
13276
13277 document processortimers
13278 Syntax: (gdb) processortimers
13279 | Print details of processor timers, noting any timer which might be suspicious
13280 end
13281
13282