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