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