1# Kernel gdb macros 2# 3# These gdb macros should be useful during kernel development in 4# determining what's going on in the kernel. 5# 6# All the convenience variables used by these macros begin with $kgm_ 7 8set print asm-demangle on 9set cp-abi gnu-v2 10 11echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n 12 13define kgm 14printf "" 15echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n 16end 17 18document kgm 19| These are the kernel gdb macros. These gdb macros are intended to be 20| used when debugging a remote kernel via the kdp protocol. Typically, you 21| would connect to your remote target like so: 22| (gdb) target remote-kdp 23| (gdb) attach <name-of-remote-host> 24| 25| The following macros are available in this package: 26| showversion Displays a string describing the remote kernel version 27| 28| showalltasks Display a summary listing of all tasks 29| showallthreads Display info about all threads in the system 30| showallstacks Display the stack for each thread in the system 31| showcurrentthreads Display info about the thread running on each cpu 32| showcurrentstacks Display the stack for the thread running on each cpu 33| showallvm Display a summary listing of all the vm maps 34| showallvme Display a summary listing of all the vm map entries 35| showallipc Display a summary listing of all the ipc spaces 36| showallrights Display a summary listing of all the ipc rights 37| showallkmods Display a summary listing of all the kernel modules 38| 39| showallclasses Display info about all OSObject subclasses in the system 40| showobject Show info about an OSObject - its vtable ptr and retain count, & more info for simple container classes. 41| showregistry Show info about all registry entries in the current plane 42| showregistryprops Show info about all registry entries in the current plane, and their properties 43| showregistryentry Show info about a registry entry; its properties and descendants in the current plane 44| setregistryplane Set the plane to be used for the iokit registry macros (pass zero for list) 45| 46| showtask Display info about the specified task 47| showtaskthreads Display info about the threads in the task 48| showtaskstacks Display the stack for each thread in the task 49| showtaskvm Display info about the specified task's vm_map 50| showtaskvme Display info about the task's vm_map entries 51| showtaskipc Display info about the specified task's ipc space 52| showtaskrights Display info about the task's ipc space entries 53| 54| showact Display info about a thread specified by activation 55| showactstack Display the stack for a thread specified by activation 56| 57| showmap Display info about the specified vm_map 58| showmapvme Display a summary list of the specified vm_map's entries 59| 60| showipc Display info about the specified ipc space 61| showrights Display a summary list of all the rights in an ipc space 62| 63| showpid Display info about the process identified by pid 64| showproc Display info about the process identified by proc struct 65| showprocinfo Display detailed info about the process identified by proc struct 66| showprocfiles Given a proc_t pointer, display the list of open file descriptors 67| showproclocks Given a proc_t pointer, display the list of advisory file locks 68| zombproc Print out all procs in the zombie list 69| allproc Print out all process in the system not in the zombie list 70| zombstacks Print out all stacks of tasks that are exiting 71| 72| showinitchild Print out all processes in the system which are children of init process 73| 74| showkmod Display info about a kernel module 75| showkmodaddr Given an address, display the kernel module and offset 76| 77| dumpcallqueue Dump out all the entries given a queue head 78| 79| showallmtx Display info about mutexes usage 80| showallrwlck Display info about reader/writer locks usage 81| 82| zprint Display info about the memory zones 83| showioalloc Display info about iokit allocations 84| paniclog Display the panic log info 85| 86| switchtoact Switch to different context specified by activation 87| switchtoctx Switch to different context 88| showuserstack Display numeric backtrace of the user stack for an 89| activation 90| 91| switchtouserthread Switch to the user context of the specified thread 92| resetstacks Return to the original kernel context 93| 94| resetctx Reset context 95| resume_on Resume when detaching from gdb 96| resume_off Don't resume when detaching from gdb 97| 98| sendcore Configure kernel to send a coredump to the specified IP 99| disablecore Configure the kernel to disable coredump transmission 100| switchtocorethread Corefile version of "switchtoact" 101| resetcorectx Corefile version of "resetctx" 102| 103| readphys Reads the specified untranslated address 104| readphys64 Reads the specified untranslated 64-bit address 105| 106| rtentry_showdbg Print the debug information of a route entry 107| rtentry_trash Walk the list of trash route entries 108| 109| mbuf_walkpkt Walk the mbuf packet chain (m_nextpkt) 110| mbuf_walk Walk the mbuf chain (m_next) 111| mbuf_buf2slab Find the slab structure of the corresponding buffer 112| mbuf_buf2mca Find the mcache audit structure of the corresponding mbuf 113| mbuf_showmca Print the contents of an mbuf mcache audit structure 114| mbuf_showactive Print all active/in-use mbuf objects 115| mbuf_showinactive Print all freed/in-cache mbuf objects 116| mbuf_showall Print all mbuf objects 117| mbuf_slabs Print all slabs in the group 118| mbuf_slabstbl Print slabs table 119| mbuf_stat Print extended mbuf allocator statistics 120| 121| mcache_walkobj Walk the mcache object chain (obj_next) 122| mcache_stat Print all mcaches in the system 123| mcache_showcache Display the number of objects in the cache 124| 125| showbootermemorymap Dump phys memory map from EFI 126| 127| systemlog Display the kernel's printf ring buffer 128| 129| showvnodepath Print the path for a vnode 130| showvnodelocks Display list of advisory locks held/blocked on a vnode 131| showallvols Display a summary of mounted volumes 132| showvnode Display info about one vnode 133| showvolvnodes Display info about all vnodes of a given volume 134| showvolbusyvnodes Display info about busy (iocount!=0) vnodes of a given volume 135| showallbusyvnodes Display info about all busy (iocount!=0) vnodes 136| showallvnodes Display info about all vnodes 137| print_vnode Print out the fields of a vnode struct 138| showprocvnodes Print out all the open fds which are vnodes in a process 139| showallprocvnodes Print out all the open fds which are vnodes in any process 140| showmountvnodes Print the vnode list 141| showmountallvnodes Print the vnode inactive list 142| showworkqvnodes Print the vnode worker list 143| shownewvnodes Print the new vnode list 144| 145| ifconfig display ifconfig-like output 146| showifaddrs show the list of addresses for the given ifp 147| showifmultiaddrs show the list of multicast addresses for the given ifp 148| 149| showallpmworkqueues Display info about all IOPMWorkQueue objects 150| showregistrypmstate Display power management state for all IOPower registry entries 151| showioservicepm Display the IOServicePM object 152| showstacksaftertask showallstacks starting after a given task 153| showstacksafterthread showallstacks starting after a given thread 154| 155| showMCAstate Print machine-check register state after MC exception. 156| 157| showallgdbstacks Cause GDB to trace all thread stacks 158| showallgdbcorestacks Corefile equivalent of "showallgdbstacks" 159| kdp-reenter Schedule reentry into the debugger and continue. 160| kdp-reboot Restart remote target 161| 162| zstack Print zalloc caller stack (zone leak debugging) 163| findoldest Find oldest zone leak debugging record 164| countpcs Print how often a pc occurs in the zone leak log 165| 166| 167| Type "help <macro>" for more specific help on a particular macro. 168| Type "show user <macro>" to see what the macro is really doing. 169end 170 171# This macro should appear before any symbol references, to facilitate 172# a gdb "source" without a loaded symbol file. 173define showversion 174 printf "%s\n", *(char **)0x501C 175end 176 177document showversion 178Syntax: showversion 179| Read the kernel version string from a fixed address in low 180| memory. Useful if you don't know which kernel is on the other end, 181| and need to find the appropriate symbols. Beware that if you've 182| loaded a symbol file, but aren't connected to a remote target, 183| the version string from the symbol file will be displayed instead. 184| This macro expects to be connected to the remote kernel to function 185| correctly. 186end 187 188set $kgm_mtype = ((struct mach_header)_mh_execute_header).cputype 189 190# This option tells gdb to relax its stack tracing heuristics 191# Useful for debugging across stack switches 192# (to the interrupt stack, for instance). Requires gdb-675 or greater. 193# Don't do this for arm as a workaround to 5486905 194if ($kgm_mtype != 12) 195 set backtrace sanity-checks off 196end 197 198set $kgm_dummy = &proc0 199set $kgm_dummy = &kmod 200 201set $kgm_reg_depth = 0 202set $kgm_reg_plane = (void **) gIOServicePlane 203set $kgm_namekey = (OSSymbol *) 0 204set $kgm_childkey = (OSSymbol *) 0 205 206set $kgm_show_object_addrs = 0 207set $kgm_show_object_retain = 0 208set $kgm_show_props = 0 209 210set $kgm_show_kmod_syms = 0 211 212define showkmodheader 213 printf "kmod address size " 214 printf "id refs version name\n" 215end 216 217define showkmodint 218 set $kgm_kmodp = (struct kmod_info *)$arg0 219 printf "0x%08x ", $arg0 220 printf "0x%08x ", $kgm_kmodp->address 221 printf "0x%08x ", $kgm_kmodp->size 222 printf "%3d ", $kgm_kmodp->id 223 printf "%5d ", $kgm_kmodp->reference_count 224 printf "%10s ", &$kgm_kmodp->version 225 printf "%s\n", &$kgm_kmodp->name 226end 227 228set $kgm_kmodmin = 0xffffffff 229set $kgm_fkmodmin = 0x00000000 230set $kgm_kmodmax = 0x00000000 231set $kgm_fkmodmax = 0xffffffff 232set $kgm_pkmod = 0 233set $kgm_pkmodst = 0 234set $kgm_pkmoden = 0 235define showkmodaddrint 236 printf "0x%x" , $arg0 237 if ((unsigned int)$arg0 >= (unsigned int)$kgm_pkmodst) && ((unsigned int)$arg0 <= (unsigned int)$kgm_pkmoden) 238 set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_pkmodst) 239 printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off 240 else 241 if ((unsigned int)$arg0 <= (unsigned int)$kgm_fkmodmax) && ((unsigned int)$arg0 >= (unsigned int)$kgm_fkmodmin) 242 set $kgm_kmodp = (struct kmod_info *)kmod 243 while $kgm_kmodp 244 set $kgm_kmod = *$kgm_kmodp 245 if $kgm_kmod.address && ($kgm_kmod.address < $kgm_kmodmin) 246 set $kgm_kmodmin = $kgm_kmod.address 247 end 248 if ($kgm_kmod.address + $kgm_kmod.size) > $kgm_kmodmax 249 set $kgm_kmodmax = $kgm_kmod.address + $kgm_kmod.size 250 end 251 set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_kmod.address) 252 if ($kgm_kmod.address <= $arg0) && ($kgm_off <= $kgm_kmod.size) 253 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off 254 set $kgm_pkmod = $kgm_kmodp 255 set $kgm_pkmodst = $kgm_kmod.address 256 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmod.size 257 set $kgm_kmodp = 0 258 else 259 set $kgm_kmodp = $kgm_kmod.next 260 end 261 end 262 if !$kgm_pkmod 263 set $kgm_fkmodmin = $kgm_kmodmin 264 set $kgm_fkmodmax = $kgm_kmodmax 265 end 266 end 267 end 268end 269 270define showkmodaddr 271 showkmodaddrint $arg0 272end 273 274document showkmodaddr 275Syntax: (gdb) showkmodaddr <addr> 276| Given an address, print the offset and name for the kmod containing it 277end 278 279define showkmod 280 showkmodheader 281 showkmodint $arg0 282end 283document showkmod 284Syntax: (gdb) showkmod <kmod> 285| Routine to print info about a kernel module 286end 287 288define showallkmods 289 showkmodheader 290 set $kgm_kmodp = (struct kmod_info *)kmod 291 while $kgm_kmodp 292 showkmodint $kgm_kmodp 293 set $kgm_kmodp = $kgm_kmodp->next 294 end 295end 296document showallkmods 297Syntax: (gdb) showallkmods 298| Routine to print a summary listing of all the kernel modules 299end 300 301define showactheader 302 printf " thread " 303 printf "processor pri state wait_queue wait_event\n" 304end 305 306 307define showactint 308 printf " 0x%08x ", $arg0 309 set $kgm_thread = *(struct thread *)$arg0 310 printf "0x%08x ", $kgm_thread.last_processor 311 printf "%3d ", $kgm_thread.sched_pri 312 set $kgm_state = $kgm_thread.state 313 if $kgm_state & 0x80 314 printf "I" 315 end 316 if $kgm_state & 0x40 317 printf "P" 318 end 319 if $kgm_state & 0x20 320 printf "A" 321 end 322 if $kgm_state & 0x10 323 printf "H" 324 end 325 if $kgm_state & 0x08 326 printf "U" 327 end 328 if $kgm_state & 0x04 329 printf "R" 330 end 331 if $kgm_state & 0x02 332 printf "S" 333 end 334 if $kgm_state & 0x01 335 printf "W\t" 336 printf "0x%08x ", $kgm_thread.wait_queue 337 if (((unsigned)$kgm_thread.wait_event > (unsigned)sectPRELINKB) \ 338 && ($arg1 != 2) && ($kgm_show_kmod_syms == 0)) 339 showkmodaddr $kgm_thread.wait_event 340 else 341 output /a (unsigned) $kgm_thread.wait_event 342 end 343 if ($kgm_thread.uthread != 0) 344 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread 345 if ($kgm_uthread->uu_wmesg != 0) 346 printf " \"%s\"", $kgm_uthread->uu_wmesg 347 end 348 end 349 end 350 if $arg1 != 0 351 if ($kgm_thread.kernel_stack != 0) 352 if ($kgm_thread.reserved_stack != 0) 353 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack 354 end 355 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack 356 if ($kgm_mtype == 18) 357 set $mysp = $kgm_thread.machine.pcb->save_r1 358 end 359 if ($kgm_mtype == 7) 360 set $kgm_statep = (struct x86_kernel_state32 *) \ 361 ($kgm_thread->kernel_stack + 0x4000 \ 362 - sizeof(struct x86_kernel_state32)) 363 set $mysp = $kgm_statep->k_ebp 364 end 365 if ($kgm_mtype == 12) 366 if ($arg0 == $r9) 367 set $mysp = $r7 368 else 369 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr 370 set $mysp = $kgm_statep->r[7] 371 end 372 end 373 set $prevsp = $mysp - 16 374 printf "\n\t\tstacktop=0x%08x", $mysp 375 if ($kgm_mtype == 18) 376 set $stkmask = 0xf 377 else 378 set $stkmask = 0x3 379 end 380 set $kgm_return = 0 381 while ($mysp != 0) && (($mysp & $stkmask) == 0) \ 382 && ($mysp != $prevsp) \ 383 && ((((unsigned) $mysp ^ (unsigned) $prevsp) < 0x2000) \ 384 || (((unsigned)$mysp < ((unsigned) ($kgm_thread->kernel_stack+0x4000))) \ 385 && ((unsigned)$mysp > (unsigned) ($kgm_thread->kernel_stack)))) 386 printf "\n\t\t0x%08x ", $mysp 387 if ($kgm_mtype == 18) 388 set $kgm_return = *($mysp + 8) 389 end 390 if ($kgm_mtype == 7) 391 set $kgm_return = *($mysp + 4) 392 end 393 if ($kgm_mtype == 12) 394 set $kgm_return = *($mysp + 4) 395 end 396 if (((unsigned) $kgm_return > (unsigned) sectPRELINKB) \ 397 && ($kgm_show_kmod_syms == 0)) 398 showkmodaddr $kgm_return 399 else 400 output /a (unsigned) $kgm_return 401 end 402 set $prevsp = $mysp 403 set $mysp = * $mysp 404 end 405 set $kgm_return = 0 406 printf "\n\t\tstackbottom=0x%08x", $prevsp 407 else 408 printf "\n\t\t\tcontinuation=" 409 output /a (unsigned) $kgm_thread.continuation 410 end 411 printf "\n" 412 else 413 printf "\n" 414 end 415end 416 417define showact 418 showactheader 419 showactint $arg0 0 420end 421document showact 422Syntax: (gdb) showact <activation> 423| Routine to print out the state of a specific thread. 424end 425 426 427define showactstack 428 showactheader 429 showactint $arg0 1 430end 431document showactstack 432Syntax: (gdb) showactstack <activation> 433| Routine to print out the stack of a specific thread. 434end 435 436 437define showallthreads 438 set $kgm_head_taskp = &tasks 439 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 440 while $kgm_taskp != $kgm_head_taskp 441 showtaskheader 442 showtaskint $kgm_taskp 443 showactheader 444 set $kgm_head_actp = &($kgm_taskp->threads) 445 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 446 while $kgm_actp != $kgm_head_actp 447 showactint $kgm_actp 0 448 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 449 end 450 printf "\n" 451 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 452 end 453end 454document showallthreads 455Syntax: (gdb) showallthreads 456| Routine to print out info about all threads in the system. 457end 458 459define showcurrentthreads 460set $kgm_prp = (struct processor *)processor_list 461 while $kgm_prp != 0 462 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_num 463 if ($kgm_prp)->active_thread != 0 464 set $kgm_actp = ($kgm_prp)->active_thread 465 showtaskheader 466 showtaskint ($kgm_actp)->task 467 showactheader 468 showactint $kgm_actp 0 469 printf "\n" 470 end 471 set $kgm_prp = ($kgm_prp)->processor_list 472 end 473end 474document showcurrentthreads 475Syntax: (gdb) showcurrentthreads 476| Routine to print out info about the thread running on each cpu. 477end 478 479set $decode_wait_events = 0 480define showallstacks 481 set $kgm_head_taskp = &tasks 482 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 483 while $kgm_taskp != $kgm_head_taskp 484 showtaskheader 485 showtaskint $kgm_taskp 486 set $kgm_head_actp = &($kgm_taskp->threads) 487 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 488 while $kgm_actp != $kgm_head_actp 489 showactheader 490 if ($decode_wait_events > 0) 491 showactint $kgm_actp 1 492 else 493 showactint $kgm_actp 2 494 end 495 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 496 end 497 printf "\n" 498 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 499 end 500end 501 502document showallstacks 503Syntax: (gdb) showallstacks 504| Routine to print out the stack for each thread in the system. 505| If the variable $decode_wait_events is non-zero, the routine attempts to 506| interpret thread wait_events as kernel module offsets, which can add to 507| processing time. 508end 509 510define showcurrentstacks 511set $kgm_prp = processor_list 512 while $kgm_prp != 0 513 printf "Processor 0x%08x State %d (cpu_id %x)\n", $kgm_prp, ($kgm_prp)->state, ($kgm_prp)->cpu_num 514 if ($kgm_prp)->active_thread != 0 515 set $kgm_actp = ($kgm_prp)->active_thread 516 showtaskheader 517 showtaskint ($kgm_actp)->task 518 showactheader 519 showactint $kgm_actp 1 520 printf "\n" 521 end 522 set $kgm_prp = ($kgm_prp)->processor_list 523 end 524end 525 526document showcurrentstacks 527Syntax: (gdb) showcurrentstacks 528| Routine to print out the thread running on each cpu (incl. its stack) 529end 530 531define showwaiterheader 532 printf "waiters activation " 533 printf "thread pri state wait_queue wait_event\n" 534end 535 536define showwaitqwaiters 537 set $kgm_w_waitqp = (struct wait_queue *)$arg0 538 set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue) 539 set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_linksp->next 540 set $kgm_w_found = 0 541 while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp) 542 if ($kgm_w_wqe->wqe_type != &_wait_queue_link) 543 if !$kgm_w_found 544 set $kgm_w_found = 1 545 showwaiterheader 546 end 547 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe 548 showactint $kgm_w_shuttle 0 549 end 550 set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_wqe->wqe_links.next 551 end 552end 553 554define showwaitqwaitercount 555 set $kgm_wc_waitqp = (struct wait_queue *)$arg0 556 set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue) 557 set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_linksp->next 558 set $kgm_wc_count = 0 559 while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp) 560 if ($kgm_wc_wqe->wqe_type != &_wait_queue_link) 561 set $kgm_wc_count = $kgm_wc_count + 1 562 end 563 set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_wqe->wqe_links.next 564 end 565 printf "0x%08x ", $kgm_wc_count 566end 567 568define showwaitqmembercount 569 set $kgm_mc_waitqsetp = (struct wait_queue_set *)$arg0 570 set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks) 571 set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_setlinksp->next 572 set $kgm_mc_count = 0 573 while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp) 574 set $kgm_mc_count = $kgm_mc_count + 1 575 set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_wql->wql_setlinks.next 576 end 577 printf "0x%08x ", $kgm_mc_count 578end 579 580 581define showwaitqmemberheader 582 printf "set-members wait_queue interlock " 583 printf "pol type member_cnt waiter_cnt\n" 584end 585 586define showwaitqmemberint 587 set $kgm_m_waitqp = (struct wait_queue *)$arg0 588 printf " 0x%08x ", $kgm_m_waitqp 589 printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data 590 if ($kgm_m_waitqp->wq_fifo) 591 printf "Fifo " 592 else 593 printf "Prio " 594 end 595 if ($kgm_m_waitqp->wq_type == 0xf1d1) 596 printf "Set " 597 showwaitqmembercount $kgm_m_waitqp 598 else 599 printf "Que 0x00000000 " 600 end 601 showwaitqwaitercount $kgm_m_waitqp 602 printf "\n" 603end 604 605 606define showwaitqmemberofheader 607 printf "member-of wait_queue interlock " 608 printf "pol type member_cnt waiter_cnt\n" 609end 610 611define showwaitqmemberof 612 set $kgm_mo_waitqp = (struct wait_queue *)$arg0 613 set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue) 614 set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_linksp->next 615 set $kgm_mo_found = 0 616 while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp) 617 if ($kgm_mo_wqe->wqe_type == &_wait_queue_link) 618 if !$kgm_mo_found 619 set $kgm_mo_found = 1 620 showwaitqmemberofheader 621 end 622 set $kgm_mo_wqlp = (struct wait_queue_link *)$kgm_mo_wqe 623 set $kgm_mo_wqsetp = (struct wait_queue *)($kgm_mo_wqlp->wql_setqueue) 624 showwaitqmemberint $kgm_mo_wqsetp 625 end 626 set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_wqe->wqe_links.next 627 end 628end 629 630define showwaitqmembers 631 set $kgm_ms_waitqsetp = (struct wait_queue_set *)$arg0 632 set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks) 633 set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_setlinksp->next 634 set $kgm_ms_found = 0 635 while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp) 636 set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue 637 if !$kgm_ms_found 638 showwaitqmemberheader 639 set $kgm_ms_found = 1 640 end 641 showwaitqmemberint $kgm_ms_waitqp 642 set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_wql->wql_setlinks.next 643 end 644end 645 646define showwaitqheader 647 printf "wait_queue ref_count interlock " 648 printf "pol type member_cnt waiter_cnt\n" 649end 650 651define showwaitqint 652 set $kgm_waitqp = (struct wait_queue *)$arg0 653 printf "0x%08x ", $kgm_waitqp 654 if ($kgm_waitqp->wq_type == 0xf1d1) 655 printf "0x%08x ", ((struct wait_queue_set *)$kgm_waitqp)->wqs_refcount 656 else 657 printf "0x00000000 " 658 end 659 printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data 660 if ($kgm_waitqp->wq_fifo) 661 printf "Fifo " 662 else 663 printf "Prio " 664 end 665 if ($kgm_waitqp->wq_type == 0xf1d1) 666 printf "Set " 667 showwaitqmembercount $kgm_waitqp 668 else 669 printf "Que 0x00000000 " 670 end 671 showwaitqwaitercount $kgm_waitqp 672 printf "\n" 673end 674 675define showwaitq 676 set $kgm_waitq1p = (wait_queue_t)$arg0 677 showwaitqheader 678 showwaitqint $kgm_waitq1p 679 if ($kgm_waitq1p->wq_type == 0xf1d1) 680 showwaitqmembers $kgm_waitq1p 681 else 682 showwaitqmemberof $kgm_waitq1p 683 end 684 showwaitqwaiters $kgm_waitq1p 685end 686 687define showmapheader 688 printf "vm_map pmap vm_size " 689 printf "#ents rpage hint first_free\n" 690end 691 692define showvmeheader 693 printf " entry start " 694 printf " prot #page object offset\n" 695end 696 697define showvmint 698 set $kgm_mapp = (vm_map_t)$arg0 699 set $kgm_map = *$kgm_mapp 700 printf "0x%08x ", $arg0 701 printf "0x%08x ", $kgm_map.pmap 702 printf "0x%08x ", $kgm_map.size 703 printf "%3d ", $kgm_map.hdr.nentries 704 if $kgm_map.pmap 705 printf "%5d ", $kgm_map.pmap->stats.resident_count 706 else 707 printf "<n/a> " 708 end 709 printf "0x%08x ", $kgm_map.hint 710 printf "0x%08x\n", $kgm_map.first_free 711 if $arg1 != 0 712 showvmeheader 713 set $kgm_head_vmep = &($kgm_mapp->hdr.links) 714 set $kgm_vmep = $kgm_map.hdr.links.next 715 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep)) 716 set $kgm_vme = *$kgm_vmep 717 printf " 0x%08x ", $kgm_vmep 718 printf "0x%016llx ", $kgm_vme.links.start 719 printf "%1x", $kgm_vme.protection 720 printf "%1x", $kgm_vme.max_protection 721 if $kgm_vme.inheritance == 0x0 722 printf "S" 723 end 724 if $kgm_vme.inheritance == 0x1 725 printf "C" 726 end 727 if $kgm_vme.inheritance == 0x2 728 printf "-" 729 end 730 if $kgm_vme.inheritance == 0x3 731 printf "D" 732 end 733 if $kgm_vme.is_sub_map 734 printf "s " 735 else 736 if $kgm_vme.needs_copy 737 printf "n " 738 else 739 printf " " 740 end 741 end 742 printf "%5d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12 743 printf "0x%08x ", $kgm_vme.object.vm_object 744 printf "0x%016llx\n", $kgm_vme.offset 745 set $kgm_vmep = $kgm_vme.links.next 746 end 747 end 748 printf "\n" 749end 750 751 752define showmapvme 753 showmapheader 754 showvmint $arg0 1 755end 756document showmapvme 757Syntax: (gdb) showmapvme <vm_map> 758| Routine to print out a summary listing of all the entries in a vm_map 759end 760 761 762define showmap 763 showmapheader 764 showvmint $arg0 0 765end 766document showmap 767Syntax: (gdb) showmap <vm_map> 768| Routine to print out info about the specified vm_map 769end 770 771define showallvm 772 set $kgm_head_taskp = &tasks 773 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 774 while $kgm_taskp != $kgm_head_taskp 775 showtaskheader 776 showmapheader 777 showtaskint $kgm_taskp 778 showvmint $kgm_taskp->map 0 779 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 780 end 781end 782document showallvm 783Syntax: (gdb) showallvm 784| Routine to print a summary listing of all the vm maps 785end 786 787 788define showallvme 789 set $kgm_head_taskp = &tasks 790 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 791 while $kgm_taskp != $kgm_head_taskp 792 showtaskheader 793 showmapheader 794 showtaskint $kgm_taskp 795 showvmint $kgm_taskp->map 1 796 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 797 end 798end 799document showallvme 800Syntax: (gdb) showallvme 801| Routine to print a summary listing of all the vm map entries 802end 803 804 805define showipcheader 806 printf "ipc_space is_table table_next " 807 printf "flags tsize splaytree splaybase\n" 808end 809 810define showipceheader 811 printf " name object " 812 printf "rite urefs destname destination\n" 813end 814 815define showipceint 816 set $kgm_ie = *(ipc_entry_t)$arg0 817 printf " 0x%08x ", $arg1 818 printf "0x%08x ", $kgm_ie.ie_object 819 if $kgm_ie.ie_bits & 0x00100000 820 printf "Dead " 821 printf "%5d\n", $kgm_ie.ie_bits & 0xffff 822 else 823 if $kgm_ie.ie_bits & 0x00080000 824 printf "SET " 825 printf "%5d\n", $kgm_ie.ie_bits & 0xffff 826 else 827 if $kgm_ie.ie_bits & 0x00010000 828 if $kgm_ie.ie_bits & 0x00020000 829 printf " SR" 830 else 831 printf " S" 832 end 833 else 834 if $kgm_ie.ie_bits & 0x00020000 835 printf " R" 836 end 837 end 838 if $kgm_ie.ie_bits & 0x00040000 839 printf " O" 840 end 841 if $kgm_ie.index.request 842 printf "n" 843 else 844 printf " " 845 end 846 if $kgm_ie.ie_bits & 0x00800000 847 printf "c" 848 else 849 printf " " 850 end 851 printf "%5d ", $kgm_ie.ie_bits & 0xffff 852 showportdest $kgm_ie.ie_object 853 end 854 end 855end 856 857define showipcint 858 set $kgm_isp = (ipc_space_t)$arg0 859 set $kgm_is = *$kgm_isp 860 printf "0x%08x ", $arg0 861 printf "0x%08x ", $kgm_is.is_table 862 printf "0x%08x ", $kgm_is.is_table_next 863 if $kgm_is.is_growing != 0 864 printf "G" 865 else 866 printf " " 867 end 868 if $kgm_is.is_fast != 0 869 printf "F" 870 else 871 printf " " 872 end 873 if $kgm_is.is_active != 0 874 printf "A " 875 else 876 printf " " 877 end 878 printf "%5d ", $kgm_is.is_table_size 879 printf "0x%08x ", $kgm_is.is_tree_total 880 printf "0x%08x\n", &$kgm_isp->is_tree 881 if $arg1 != 0 882 showipceheader 883 set $kgm_iindex = 0 884 set $kgm_iep = $kgm_is.is_table 885 set $kgm_destspacep = (ipc_space_t)0 886 while ( $kgm_iindex < $kgm_is.is_table_size ) 887 set $kgm_ie = *$kgm_iep 888 if $kgm_ie.ie_bits & 0x001f0000 889 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24)) 890 showipceint $kgm_iep $kgm_name 891 end 892 set $kgm_iindex = $kgm_iindex + 1 893 set $kgm_iep = &($kgm_is.is_table[$kgm_iindex]) 894 end 895 if $kgm_is.is_tree_total 896 printf "Still need to write tree traversal\n" 897 end 898 end 899 printf "\n" 900end 901 902 903define showipc 904 set $kgm_isp = (ipc_space_t)$arg0 905 showipcheader 906 showipcint $kgm_isp 0 907end 908document showipc 909Syntax: (gdb) showipc <ipc_space> 910| Routine to print the status of the specified ipc space 911end 912 913define showrights 914 set $kgm_isp = (ipc_space_t)$arg0 915 showipcheader 916 showipcint $kgm_isp 1 917end 918document showrights 919Syntax: (gdb) showrights <ipc_space> 920| Routine to print a summary list of all the rights in a specified ipc space 921end 922 923 924define showtaskipc 925 set $kgm_taskp = (task_t)$arg0 926 showtaskheader 927 showipcheader 928 showtaskint $kgm_taskp 929 showipcint $kgm_taskp->itk_space 0 930end 931document showtaskipc 932Syntax: (gdb) showtaskipc <task> 933| Routine to print info about the ipc space for a task 934end 935 936 937define showtaskrights 938 set $kgm_taskp = (task_t)$arg0 939 showtaskheader 940 showipcheader 941 showtaskint $kgm_taskp 942 showipcint $kgm_taskp->itk_space 1 943end 944document showtaskrights 945Syntax: (gdb) showtaskrights <task> 946| Routine to print info about the ipc rights for a task 947end 948 949define showallipc 950 set $kgm_head_taskp = &tasks 951 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) 952 while $kgm_cur_taskp != $kgm_head_taskp 953 showtaskheader 954 showipcheader 955 showtaskint $kgm_cur_taskp 956 showipcint $kgm_cur_taskp->itk_space 0 957 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next) 958 end 959end 960document showallipc 961Syntax: (gdb) showallipc 962| Routine to print a summary listing of all the ipc spaces 963end 964 965 966define showallrights 967 set $kgm_head_taskp = &tasks 968 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) 969 while $kgm_cur_taskp != $kgm_head_taskp 970 showtaskheader 971 showipcheader 972 showtaskint $kgm_cur_taskp 973 showipcint $kgm_cur_taskp->itk_space 1 974 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next) 975 end 976end 977document showallrights 978Syntax: (gdb) showallrights 979| Routine to print a summary listing of all the ipc rights 980end 981 982 983define showtaskvm 984 set $kgm_taskp = (task_t)$arg0 985 showtaskheader 986 showmapheader 987 showtaskint $kgm_taskp 988 showvmint $kgm_taskp->map 0 989end 990document showtaskvm 991Syntax: (gdb) showtaskvm <task> 992| Routine to print out info about a task's vm_map 993end 994 995define showtaskvme 996 set $kgm_taskp = (task_t)$arg0 997 showtaskheader 998 showmapheader 999 showtaskint $kgm_taskp 1000 showvmint $kgm_taskp->map 1 1001end 1002document showtaskvme 1003Syntax: (gdb) showtaskvme <task> 1004| Routine to print out info about a task's vm_map_entries 1005end 1006 1007 1008define showtaskheader 1009 printf "task vm_map ipc_space #acts " 1010 showprocheader 1011end 1012 1013 1014define showtaskint 1015 set $kgm_task = *(struct task *)$arg0 1016 printf "0x%08x ", $arg0 1017 printf "0x%08x ", $kgm_task.map 1018 printf "0x%08x ", $kgm_task.itk_space 1019 printf "%3d ", $kgm_task.thread_count 1020 showprocint $kgm_task.bsd_info 1021end 1022 1023define showtask 1024 showtaskheader 1025 showtaskint $arg0 1026end 1027document showtask 1028Syntax (gdb) showtask <task> 1029| Routine to print out info about a task. 1030end 1031 1032 1033define showtaskthreads 1034 showtaskheader 1035 set $kgm_taskp = (struct task *)$arg0 1036 showtaskint $kgm_taskp 1037 showactheader 1038 set $kgm_head_actp = &($kgm_taskp->threads) 1039 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 1040 while $kgm_actp != $kgm_head_actp 1041 showactint $kgm_actp 0 1042 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 1043 end 1044end 1045document showtaskthreads 1046Syntax: (gdb) showtaskthreads <task> 1047| Routine to print info about the threads in a task. 1048end 1049 1050 1051define showtaskstacks 1052 showtaskheader 1053 set $kgm_taskp = (struct task *)$arg0 1054 showtaskint $kgm_taskp 1055 set $kgm_head_actp = &($kgm_taskp->threads) 1056 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 1057 while $kgm_actp != $kgm_head_actp 1058 showactheader 1059 showactint $kgm_actp 1 1060 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 1061 end 1062end 1063document showtaskstacks 1064Syntax: (gdb) showtaskstacks <task> 1065| Routine to print out the stack for each thread in a task. 1066end 1067 1068 1069define showalltasks 1070 showtaskheader 1071 set $kgm_head_taskp = &tasks 1072 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 1073 while $kgm_taskp != $kgm_head_taskp 1074 showtaskint $kgm_taskp 1075 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 1076 end 1077end 1078document showalltasks 1079Syntax: (gdb) showalltasks 1080| Routine to print a summary listing of all the tasks 1081end 1082 1083 1084define showprocheader 1085 printf " pid proc command\n" 1086end 1087 1088define showprocint 1089 set $kgm_procp = (struct proc *)$arg0 1090 if $kgm_procp != 0 1091 printf "%5d ", $kgm_procp->p_pid 1092 printf "0x%08x ", $kgm_procp 1093 printf "%s\n", $kgm_procp->p_comm 1094 else 1095 printf " *0* 0x00000000 --\n" 1096 end 1097end 1098 1099define showpid 1100 showtaskheader 1101 set $kgm_head_taskp = &tasks 1102 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 1103 while $kgm_taskp != $kgm_head_taskp 1104 set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info 1105 if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0)) 1106 showtaskint $kgm_taskp 1107 set $kgm_taskp = $kgm_head_taskp 1108 else 1109 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 1110 end 1111 end 1112end 1113document showpid 1114Syntax: (gdb) showpid <pid> 1115| Routine to print a single process by pid 1116end 1117 1118define showproc 1119 showtaskheader 1120 set $kgm_procp = (struct proc *)$arg0 1121 showtaskint $kgm_procp->task $arg1 $arg2 1122end 1123 1124 1125define kdb 1126 set switch_debugger=1 1127 continue 1128end 1129document kdb 1130| kdb - Switch to the inline kernel debugger 1131| 1132| usage: kdb 1133| 1134| The kdb macro allows you to invoke the inline kernel debugger. 1135end 1136 1137define showpsetheader 1138 printf "portset waitqueue recvname " 1139 printf "flags refs recvname process\n" 1140end 1141 1142define showportheader 1143 printf "port mqueue recvname " 1144 printf "flags refs recvname process\n" 1145end 1146 1147define showportmemberheader 1148 printf "members port recvname " 1149 printf "flags refs mqueue msgcount\n" 1150end 1151 1152define showkmsgheader 1153 printf "messages kmsg size " 1154 printf "disp msgid remote-port local-port\n" 1155end 1156 1157define showkmsgint 1158 printf " 0x%08x ", $arg0 1159 set $kgm_kmsgh = ((ipc_kmsg_t)$arg0)->ikm_header 1160 printf "0x%08x ", $kgm_kmsgh.msgh_size 1161 if (($kgm_kmsgh.msgh_bits & 0xff) == 19) 1162 printf "rC" 1163 else 1164 printf "rM" 1165 end 1166 if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 < 8)) 1167 printf "lC" 1168 else 1169 printf "lM" 1170 end 1171 if ($kgm_kmsgh.msgh_bits & 0xf0000000) 1172 printf "c" 1173 else 1174 printf "s" 1175 end 1176 printf "%5d ", $kgm_kmsgh.msgh_id 1177 printf "0x%08x ", $kgm_kmsgh.msgh_remote_port 1178 printf "0x%08x\n", $kgm_kmsgh.msgh_local_port 1179end 1180 1181 1182 1183define showkobject 1184 set $kgm_portp = (struct ipc_port *)$arg0 1185 printf "0x%08x kobject(", $kgm_portp->ip_kobject 1186 set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff) 1187 if ($kgm_kotype == 1) 1188 printf "THREAD" 1189 end 1190 if ($kgm_kotype == 2) 1191 printf "TASK" 1192 end 1193 if ($kgm_kotype == 3) 1194 printf "HOST" 1195 end 1196 if ($kgm_kotype == 4) 1197 printf "HOST_PRIV" 1198 end 1199 if ($kgm_kotype == 5) 1200 printf "PROCESSOR" 1201 end 1202 if ($kgm_kotype == 6) 1203 printf "PSET" 1204 end 1205 if ($kgm_kotype == 7) 1206 printf "PSET_NAME" 1207 end 1208 if ($kgm_kotype == 8) 1209 printf "TIMER" 1210 end 1211 if ($kgm_kotype == 9) 1212 printf "PAGER_REQ" 1213 end 1214 if ($kgm_kotype == 10) 1215 printf "DEVICE" 1216 end 1217 if ($kgm_kotype == 11) 1218 printf "XMM_OBJECT" 1219 end 1220 if ($kgm_kotype == 12) 1221 printf "XMM_PAGER" 1222 end 1223 if ($kgm_kotype == 13) 1224 printf "XMM_KERNEL" 1225 end 1226 if ($kgm_kotype == 14) 1227 printf "XMM_REPLY" 1228 end 1229 if ($kgm_kotype == 15) 1230 printf "NOTDEF 15" 1231 end 1232 if ($kgm_kotype == 16) 1233 printf "NOTDEF 16" 1234 end 1235 if ($kgm_kotype == 17) 1236 printf "HOST_SEC" 1237 end 1238 if ($kgm_kotype == 18) 1239 printf "LEDGER" 1240 end 1241 if ($kgm_kotype == 19) 1242 printf "MASTER_DEV" 1243 end 1244 if ($kgm_kotype == 20) 1245 printf "ACTIVATION" 1246 end 1247 if ($kgm_kotype == 21) 1248 printf "SUBSYSTEM" 1249 end 1250 if ($kgm_kotype == 22) 1251 printf "IO_DONE_QUE" 1252 end 1253 if ($kgm_kotype == 23) 1254 printf "SEMAPHORE" 1255 end 1256 if ($kgm_kotype == 24) 1257 printf "LOCK_SET" 1258 end 1259 if ($kgm_kotype == 25) 1260 printf "CLOCK" 1261 end 1262 if ($kgm_kotype == 26) 1263 printf "CLOCK_CTRL" 1264 end 1265 if ($kgm_kotype == 27) 1266 printf "IOKIT_SPARE" 1267 end 1268 if ($kgm_kotype == 28) 1269 printf "NAMED_MEM" 1270 end 1271 if ($kgm_kotype == 29) 1272 printf "IOKIT_CON" 1273 end 1274 if ($kgm_kotype == 30) 1275 printf "IOKIT_OBJ" 1276 end 1277 if ($kgm_kotype == 31) 1278 printf "UPL" 1279 end 1280 printf ")\n" 1281end 1282 1283define showportdestproc 1284 set $kgm_portp = (struct ipc_port *)$arg0 1285 set $kgm_spacep = $kgm_portp->data.receiver 1286# check against the previous cached value - this is slow 1287 if ($kgm_spacep != $kgm_destspacep) 1288 set $kgm_destprocp = (struct proc *)0 1289 set $kgm_head_taskp = &tasks 1290 set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next) 1291 while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp)) 1292 set $kgm_destspacep = $kgm_desttaskp->itk_space 1293 if ($kgm_destspacep == $kgm_spacep) 1294 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info 1295 else 1296 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->tasks.next) 1297 end 1298 end 1299 end 1300 if $kgm_destprocp != 0 1301 printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid 1302 else 1303 printf "task 0x%08x\n", $kgm_desttaskp 1304 end 1305end 1306 1307define showportdest 1308 set $kgm_portp = (struct ipc_port *)$arg0 1309 set $kgm_spacep = $kgm_portp->data.receiver 1310 if ($kgm_spacep == ipc_space_kernel) 1311 showkobject $kgm_portp 1312 else 1313 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1314 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1315 showportdestproc $kgm_portp 1316 else 1317 printf "0x%08x inactive-port\n", $kgm_portp 1318 end 1319 end 1320end 1321 1322define showportmember 1323 printf " 0x%08x ", $arg0 1324 set $kgm_portp = (struct ipc_port *)$arg0 1325 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1326 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1327 printf "A" 1328 else 1329 printf " " 1330 end 1331 if ($kgm_portp->ip_object.io_bits & 0x7fff0000) 1332 printf "Set " 1333 else 1334 printf "Port" 1335 end 1336 printf "%5d ", $kgm_portp->ip_object.io_references 1337 printf "0x%08x ", &($kgm_portp->ip_messages) 1338 printf "0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount 1339end 1340 1341define showportint 1342 printf "0x%08x ", $arg0 1343 set $kgm_portp = (struct ipc_port *)$arg0 1344 printf "0x%08x ", &($kgm_portp->ip_messages) 1345 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1346 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1347 printf "A" 1348 else 1349 printf "D" 1350 end 1351 printf "Port" 1352 printf "%5d ", $kgm_portp->ip_object.io_references 1353 set $kgm_destspacep = (struct ipc_space *)0 1354 showportdest $kgm_portp 1355 set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base 1356 if $arg1 && $kgm_kmsgp 1357 showkmsgheader 1358 showkmsgint $kgm_kmsgp 1359 set $kgm_kmsgheadp = $kgm_kmsgp 1360 set $kgm_kmsgp = $kgm_kmsgp->ikm_next 1361 while $kgm_kmsgp != $kgm_kmsgheadp 1362 showkmsgint $kgm_kmsgp 1363 set $kgm_kmsgp = $kgm_kmsgp->ikm_next 1364 end 1365 end 1366end 1367 1368define showpsetint 1369 printf "0x%08x ", $arg0 1370 set $kgm_psetp = (struct ipc_pset *)$arg0 1371 printf "0x%08x ", &($kgm_psetp->ips_messages) 1372 printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name 1373 if ($kgm_psetp->ips_object.io_bits & 0x80000000) 1374 printf "A" 1375 else 1376 printf "D" 1377 end 1378 printf "Set " 1379 printf "%5d ", $kgm_psetp->ips_object.io_references 1380 printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name 1381 set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.set_queue.wqs_setlinks) 1382 set $kgm_wql = (struct wait_queue_link *)$kgm_setlinksp->next 1383 set $kgm_found = 0 1384 while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp) 1385 set $kgm_portp = (struct ipc_port *)((int)($kgm_wql->wql_element->wqe_queue) - ((int)$kgm_portoff)) 1386 if !$kgm_found 1387 set $kgm_destspacep = (struct ipc_space *)0 1388 showportdestproc $kgm_portp 1389 showportmemberheader 1390 set $kgm_found = 1 1391 end 1392 showportmember $kgm_portp 0 1393 set $kgm_wql = (struct wait_queue_link *)$kgm_wql->wql_setlinks.next 1394 end 1395 if !$kgm_found 1396 printf "--n/e--\n" 1397 end 1398end 1399 1400define showpset 1401 showpsetheader 1402 showpsetint $arg0 1 1403end 1404 1405define showport 1406 showportheader 1407 showportint $arg0 1 1408end 1409 1410define showipcobject 1411 set $kgm_object = (ipc_object_t)$arg0 1412 if ($kgm_objectp->io_bits & 0x7fff0000) 1413 showpset $kgm_objectp 1414 else 1415 showport $kgm_objectp 1416 end 1417end 1418 1419define showmqueue 1420 set $kgm_mqueue = *(struct ipc_mqueue *)$arg0 1421 set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages) 1422 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages) 1423 if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d1) 1424 set $kgm_pset = (((int)$arg0) - ((int)$kgm_psetoff)) 1425 showpsetheader 1426 showpsetint $kgm_pset 1 1427 end 1428 if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d0) 1429 showportheader 1430 set $kgm_port = (((int)$arg0) - ((int)$kgm_portoff)) 1431 showportint $kgm_port 1 1432 end 1433end 1434 1435define zprint_one 1436set $kgm_zone = (struct zone *)$arg0 1437 1438printf "0x%08x ", $kgm_zone 1439printf "%8d ",$kgm_zone->count 1440printf "%8x ",$kgm_zone->cur_size 1441printf "%8x ",$kgm_zone->max_size 1442printf "%6d ",$kgm_zone->elem_size 1443printf "%8x ",$kgm_zone->alloc_size 1444printf "%s ",$kgm_zone->zone_name 1445 1446if ($kgm_zone->exhaustible) 1447 printf "H" 1448end 1449if ($kgm_zone->collectable) 1450 printf "C" 1451end 1452if ($kgm_zone->expandable) 1453 printf "X" 1454end 1455printf "\n" 1456end 1457 1458 1459define zprint 1460printf "ZONE COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n" 1461set $kgm_zone_ptr = (struct zone *)first_zone 1462while ($kgm_zone_ptr != 0) 1463 zprint_one $kgm_zone_ptr 1464 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone 1465end 1466printf "\n" 1467end 1468document zprint 1469Syntax: (gdb) zprint 1470| Routine to print a summary listing of all the kernel zones 1471end 1472 1473define showmtxgrp 1474set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0 1475 1476if ($kgm_mtxgrp->lck_grp_mtxcnt) 1477printf "0x%08x ", $kgm_mtxgrp 1478printf "%8d ",$kgm_mtxgrp->lck_grp_mtxcnt 1479printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt 1480printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt 1481printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt 1482printf "%s ",&$kgm_mtxgrp->lck_grp_name 1483printf "\n" 1484end 1485end 1486 1487 1488define showallmtx 1489printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" 1490set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue 1491set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next 1492while ($kgm_mtxgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue) 1493 showmtxgrp $kgm_mtxgrp_ptr 1494 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next 1495end 1496printf "\n" 1497end 1498document showallmtx 1499Syntax: (gdb) showallmtx 1500| Routine to print a summary listing of all mutexes 1501end 1502 1503define showrwlckgrp 1504set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0 1505 1506if ($kgm_rwlckgrp->lck_grp_rwcnt) 1507printf "0x%08x ", $kgm_rwlckgrp 1508printf "%8d ",$kgm_rwlckgrp->lck_grp_rwcnt 1509printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt 1510printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt 1511printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt 1512printf "%s ",&$kgm_rwlckgrp->lck_grp_name 1513printf "\n" 1514end 1515end 1516 1517 1518define showallrwlck 1519printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" 1520set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue 1521set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next 1522while ($kgm_rwlckgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue) 1523 showrwlckgrp $kgm_rwlckgrp_ptr 1524 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next 1525end 1526printf "\n" 1527end 1528document showallrwlck 1529Syntax: (gdb) showallrwlck 1530| Routine to print a summary listing of all read/writer locks 1531end 1532 1533set $kdp_act_counter = 0 1534 1535set $r0_save = 0 1536set $r1_save = 0 1537set $r2_save = 0 1538set $r3_save = 0 1539set $r4_save = 0 1540set $r5_save = 0 1541set $r6_save = 0 1542set $r7_save = 0 1543set $r8_save = 0 1544set $r9_save = 0 1545set $r10_save = 0 1546set $r11_save = 0 1547set $r12_save = 0 1548set $sp_save = 0 1549set $lr_save = 0 1550set $pc_save = 0 1551 1552define showcontext_int 1553 echo Context switched, current instruction pointer: 1554 output/a $pc 1555 echo \n 1556end 1557 1558define switchtoact 1559 set $newact = (struct thread *) $arg0 1560 select 0 1561 if ($newact->kernel_stack == 0) 1562 echo This activation does not have a stack.\n 1563 echo continuation: 1564 output/a (unsigned) $newact.continuation 1565 echo \n 1566 else 1567 if ($kgm_mtype == 18) 1568 if ($kdp_act_counter == 0) 1569 set $kdpstate = (struct savearea *) kdp.saved_state 1570 end 1571 set $kdp_act_counter = $kdp_act_counter + 1 1572 set (struct savearea *) kdp.saved_state=$newact->machine->pcb 1573 flushregs 1574 flushstack 1575 set $pc=$newact->machine->pcb.save_srr0 1576 update 1577 end 1578 if ($kgm_mtype == 7) 1579 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state 1580 if ($kdp_act_counter == 0) 1581 set $kdpstate = *($kdpstatep) 1582 end 1583 set $kdp_act_counter = $kdp_act_counter + 1 1584 1585 set $kgm_statep = (struct x86_kernel_state32 *) \ 1586 ($newact->kernel_stack + 0x4000 \ 1587 - sizeof(struct x86_kernel_state32)) 1588 set $kdpstatep->ebx = $kgm_statep->k_ebx 1589 set $kdpstatep->ebp = $kgm_statep->k_ebp 1590 set $kdpstatep->edi = $kgm_statep->k_edi 1591 set $kdpstatep->esi = $kgm_statep->k_esi 1592 set $kdpstatep->eip = $kgm_statep->k_eip 1593 flushregs 1594 flushstack 1595 set $pc = $kgm_statep->k_eip 1596 update 1597 end 1598 if ($kgm_mtype == 12) 1599 set $r0_save = $r0 1600 set $r1_save = $r1 1601 set $r2_save = $r2 1602 set $r3_save = $r3 1603 set $r4_save = $r4 1604 set $r5_save = $r5 1605 set $r6_save = $r6 1606 set $r7_save = $r7 1607 set $r8_save = $r8 1608 set $r9_save = $r9 1609 set $r10_save = $r10 1610 set $r11_save = $r11 1611 set $r12_save = $r12 1612 set $sp_save = $sp 1613 set $lr_save = $lr 1614 set $pc_save = $pc 1615 set $pc_ctx = load_reg+8 1616 set $kgm_statep = (struct arm_saved_state *)((struct thread*)$arg0)->machine.kstackptr 1617 set $r0 = $kgm_statep->r[0] 1618 set $r1 = $kgm_statep->r[1] 1619 set $r2 = $kgm_statep->r[2] 1620 set $r3 = $kgm_statep->r[3] 1621 set $r4 = $kgm_statep->r[4] 1622 set $r5 = $kgm_statep->r[5] 1623 set $r6 = $kgm_statep->r[6] 1624 set $r8 = $kgm_statep->r[8] 1625 set $r9 = $kgm_statep->r[9] 1626 set $r10 = $kgm_statep->r[10] 1627 set $r11 = $kgm_statep->r[11] 1628 set $r12 = $kgm_statep->r[12] 1629 set $sp = $kgm_statep->sp 1630 set $lr = $kgm_statep->lr 1631 set $pc = $pc_ctx 1632 set $r7 = $kgm_statep->r[7] 1633 flushregs 1634 flushstack 1635 end 1636 end 1637 showcontext_int 1638end 1639 1640document switchtoact 1641Syntax: switchtoact <address of activation> 1642| This command allows gdb to examine the execution context and call 1643| stack for the specified activation. For example, to view the backtrace 1644| for an activation issue "switchtoact <address>", followed by "bt". 1645| Before resuming execution, issue a "resetctx" command, to 1646| return to the original execution context. 1647end 1648 1649define switchtoctx 1650 select 0 1651 if ($kgm_mtype == 18) 1652 if ($kdp_act_counter == 0) 1653 set $kdpstate = (struct savearea *) kdp.saved_state 1654 end 1655 set $kdp_act_counter = $kdp_act_counter + 1 1656 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0 1657 flushregs 1658 flushstack 1659 set $pc=((struct savearea *) $arg0)->save_srr0 1660 update 1661 else 1662 if ($kgm_mtype == 12) 1663 set $r0_save = $r0 1664 set $r1_save = $r1 1665 set $r2_save = $r2 1666 set $r3_save = $r3 1667 set $r4_save = $r4 1668 set $r5_save = $r5 1669 set $r6_save = $r6 1670 set $r7_save = $r7 1671 set $r8_save = $r8 1672 set $r9_save = $r9 1673 set $r10_save = $r10 1674 set $r11_save = $r11 1675 set $r12_save = $r12 1676 set $sp_save = $sp 1677 set $lr_save = $lr 1678 set $pc_save = $pc 1679 set $kgm_statep = (struct arm_saved_state *)$arg0 1680 set $r0 = $kgm_statep->r[0] 1681 set $r1 = $kgm_statep->r[1] 1682 set $r2 = $kgm_statep->r[2] 1683 set $r3 = $kgm_statep->r[3] 1684 set $r4 = $kgm_statep->r[4] 1685 set $r5 = $kgm_statep->r[5] 1686 set $r6 = $kgm_statep->r[6] 1687 set $r8 = $kgm_statep->r[8] 1688 set $r9 = $kgm_statep->r[9] 1689 set $r10 = $kgm_statep->r[10] 1690 set $r11 = $kgm_statep->r[11] 1691 set $r12 = $kgm_statep->r[12] 1692 set $sp = $kgm_statep->sp 1693 set $lr = $kgm_statep->lr 1694 set $r7 = $kgm_statep->r[7] 1695 set $pc = $kgm_statep->pc 1696 flushregs 1697 flushstack 1698 update 1699 else 1700 echo switchtoctx not implemented for this architecture.\n 1701 end 1702end 1703 1704document switchtoctx 1705Syntax: switchtoctx <address of pcb> 1706| This command allows gdb to examine an execution context and dump the 1707| backtrace for this execution context. 1708| Before resuming execution, issue a "resetctx" command, to 1709| return to the original execution context. 1710end 1711 1712define resetctx 1713 select 0 1714 if ($kdp_act_counter != 0) 1715 if ($kgm_mtype == 18) 1716 set (struct savearea *)kdp.saved_state=$kdpstate 1717 flushregs 1718 flushstack 1719 set $pc=((struct savearea *) kdp.saved_state)->save_srr0 1720 update 1721 set $kdp_act_counter = 0 1722 end 1723 if ($kgm_mtype == 7) 1724 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state 1725 set *($kdpstatep)=$kdpstate 1726 flushregs 1727 flushstack 1728 set $pc=$kdpstatep->eip 1729 update 1730 set $kdp_act_counter = 0 1731 end 1732 if ($kgm_mtype == 12) 1733 set $r0 = $r0_save 1734 flushregs 1735 set $r1 = $r1_save 1736 flushregs 1737 set $r2 = $r2_save 1738 flushregs 1739 set $r3 = $r3_save 1740 flushregs 1741 set $r4 = $r4_save 1742 flushregs 1743 set $r5 = $r5_save 1744 flushregs 1745 set $r6 = $r6_save 1746 flushregs 1747 set $r8 = $r8_save 1748 flushregs 1749 set $r9 = $r9_save 1750 flushregs 1751 set $r10 = $r10_save 1752 flushregs 1753 set $r11 = $r11_save 1754 flushregs 1755 set $r12 = $r12_save 1756 flushregs 1757 set $sp = $sp_save 1758 flushregs 1759 set $lr = $lr_save 1760 flushregs 1761 set $pc = $pc_save 1762 flushregs 1763 set $r7 = $r7_save 1764 flushregs 1765 end 1766 showcontext_int 1767 end 1768end 1769 1770document resetctx 1771| Syntax: resetctx 1772| Returns to the original execution context. This command should be 1773| issued if you wish to resume execution after using the "switchtoact" 1774| or "switchtoctx" commands. 1775end 1776 1777# This is a pre-hook for the continue command, to prevent inadvertent attempts 1778# to resume from the context switched to for examination. 1779define hook-continue 1780 resetctx 1781end 1782 1783# This is a pre-hook for the detach command, to prevent inadvertent attempts 1784# to resume from the context switched to for examination. 1785define hook-detach 1786 resetctx 1787end 1788 1789define resume_on 1790 set noresume_on_disconnect = 0 1791end 1792 1793document resume_on 1794| Syntax: resume_on 1795| The target system will resume when detaching or exiting from gdb. 1796| This is the default behavior. 1797end 1798 1799define resume_off 1800 set noresume_on_disconnect = 1 1801end 1802 1803document resume_off 1804| Syntax: resume_off 1805| The target system won't resume after detaching from gdb and 1806| can be attached with a new gdb session 1807end 1808 1809define paniclog 1810 set $kgm_panic_bufptr = debug_buf 1811 set $kgm_panic_bufptr_max = debug_buf_ptr 1812 while $kgm_panic_bufptr < $kgm_panic_bufptr_max 1813 if *(char *)$kgm_panic_bufptr == 10 1814 printf "\n" 1815 else 1816 printf "%c", *$kgm_panic_bufptr 1817 end 1818 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1 1819 end 1820end 1821 1822document paniclog 1823| Syntax: paniclog 1824| Display the panic log information 1825| 1826end 1827 1828define dumpcallqueue 1829 set $kgm_callhead = (queue_t)&$arg0 1830 set $kgm_call = (struct call_entry *)$kgm_callhead.next 1831 set $kgm_i = 0 1832 while $kgm_call != $kgm_callhead 1833 printf "0x%08x ", $kgm_call 1834 printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1 1835 output $kgm_call->state 1836 printf "\t" 1837 output $kgm_call->deadline 1838 printf "\t" 1839 output $kgm_call->func 1840 printf "\n" 1841 set $kgm_i = $kgm_i + 1 1842 set $kgm_call = (struct call_entry *)$kgm_call->q_link.next 1843 end 1844 printf "%d entries\n", $kgm_i 1845end 1846 1847document dumpcallqueue 1848| Syntax: dumpcallqueue <queue head> 1849| Displays the contents of the specified call_entry queue. 1850end 1851 1852define showtaskacts 1853showtaskthreads $arg0 1854end 1855document showtaskacts 1856| See help showtaskthreads. 1857end 1858 1859define showallacts 1860showallthreads 1861end 1862document showallacts 1863| See help showallthreads. 1864end 1865 1866 1867define resetstacks 1868 _kgm_flush_loop 1869 set kdp_pmap = 0 1870 _kgm_flush_loop 1871 resetctx 1872 _kgm_flush_loop 1873 _kgm_update_loop 1874 resetctx 1875 _kgm_update_loop 1876end 1877 1878document resetstacks 1879| Syntax: resetstacks 1880| Internal kgmacro routine used by the "showuserstack" macro 1881| to reset the target pmap to the kernel pmap. 1882end 1883 1884#Barely effective hacks to work around bugs in the "flush" and "update" 1885#gdb commands in Tiger (up to 219); these aren't necessary with Panther 1886#gdb, but do no harm. 1887define _kgm_flush_loop 1888 set $kgm_flush_loop_ctr = 0 1889 while ($kgm_flush_loop_ctr < 30) 1890 flushregs 1891 flushstack 1892 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1 1893 end 1894end 1895 1896define _kgm_update_loop 1897 set $kgm_update_loop_ctr = 0 1898 while ($kgm_update_loop_ctr < 30) 1899 update 1900 set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1 1901 end 1902end 1903 1904#This is necessary since gdb often doesn't do backtraces on x86 correctly 1905#in the absence of symbols.The code below in showuserstack and 1906#showx86backtrace also contains several workarouds for the gdb bug where 1907#gdb stops macro evaluation because of spurious "Cannot read memory" 1908#errors on x86. These errors appear on ppc as well, but they don't 1909#always stop macro evaluation. 1910 1911set $kgm_cur_ebp = 0 1912set $kgm_cur_eip = 0 1913 1914define showx86backtrace 1915 if ($kgm_cur_ebp == 0) 1916 set $kgm_cur_ebp = $ebp 1917 end 1918 if ($kgm_cur_eip == 0) 1919 set $kgm_cur_eip = $eip 1920 end 1921 printf "0: EBP: 0x%08x EIP: 0x%08x\n", $kgm_cur_ebp, $kgm_cur_eip 1922 x/i $kgm_cur_eip 1923 set $kgm_prev_ebp = *((uint32_t *) $kgm_cur_ebp) 1924 set $kgm_prev_eip = *((uint32_t *) ($kgm_cur_ebp + 4)) 1925 set $kgm_cur_ebp = 0 1926 set $kgm_cur_eip = 0 1927 set $kgm_frameno = 1 1928 while $kgm_prev_ebp != 0 1929 printf "%d: saved EBP: 0x%08x saved EIP: 0x%08x\n", $kgm_frameno, $kgm_prev_ebp, $kgm_prev_eip 1930 x/i $kgm_prev_eip 1931 set $kgm_prev_eip = *((uint32_t *) ($kgm_prev_ebp + 4)) 1932 set $kgm_prev_ebp = *((uint32_t *) $kgm_prev_ebp) 1933 set $kgm_frameno = $kgm_frameno + 1 1934 end 1935 set kdp_pmap = 0 1936end 1937 1938define showuserstack 1939 select 0 1940 if ($kgm_mtype == 18) 1941 if ($kdp_act_counter == 0) 1942 set $kdpstate = (struct savearea *) kdp.saved_state 1943 end 1944 set $kdp_act_counter = $kdp_act_counter + 1 1945 set $newact = (struct thread *) $arg0 1946 _kgm_flush_loop 1947 set $checkpc = $newact->machine->upcb.save_srr0 1948 if ($checkpc == 0) 1949 echo This activation does not appear to have 1950 echo \20 a valid user context.\n 1951 else 1952 set (struct savearea *) kdp.saved_state=$newact->machine->upcb 1953 set $pc = $checkpc 1954#flush and update seem to be executed lazily by gdb on Tiger, hence the 1955#repeated invocations - see 3743135 1956 _kgm_flush_loop 1957# This works because the new pmap is used only for reads 1958 set kdp_pmap = $newact->task->map->pmap 1959 _kgm_flush_loop 1960 _kgm_update_loop 1961 bt 1962 resetstacks 1963 _kgm_flush_loop 1964 _kgm_update_loop 1965 resetstacks 1966 _kgm_flush_loop 1967 _kgm_update_loop 1968 end 1969 else 1970 if ($kgm_mtype == 7) 1971 set $newact = (struct thread *) $arg0 1972#This needs to identify 64-bit processes as well 1973 set $newiss = (x86_saved_state32_t) ($newact->machine.pcb->iss.uss.ss_32) 1974 set $checkpc = $newiss.eip 1975 if ($checkpc == 0) 1976 echo This activation does not appear to have 1977 echo \20 a valid user context.\n 1978 else 1979 set $kgm_cur_ebp = $newiss.ebp 1980 set $kgm_cur_eip = $checkpc 1981 printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread (0x%08x); you can also examine memory locations in this address space (pmap 0x%08x) 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", $arg0, $newact->task->map->pmap 1982 set kdp_pmap = $newact->task->map->pmap 1983 _kgm_flush_loop 1984 _kgm_update_loop 1985 end 1986 else 1987 echo showuserstack not supported on this architecture\n 1988 end 1989 end 1990end 1991document showuserstack 1992Syntax: showuserstack <address of thread activation> 1993|This command displays a numeric backtrace for the user space stack of 1994|the given thread activation. It may, of course, fail to display a 1995|complete backtrace if portions of the user stack are not mapped in. 1996|Symbolic backtraces can be obtained either by running gdb on the 1997|user space binary, or a tool such as "symbolicate". 1998|Note that while this command works on Panther's gdb, an issue 1999|with Tiger gdb (3743135) appears to hamper the evaluation of this 2000|macro in some cases. 2001end 2002 2003#Stopgap until gdb can generate the HOSTREBOOT packet 2004define kdp-reboot 2005#Alternatively, set *(*(unsigned **) 0x2498) = 1 (or 0x5498 on PPC) 2006 set flag_kdp_trigger_reboot = 1 2007 continue 2008end 2009 2010document kdp-reboot 2011Syntax: kdp-reboot 2012|Reboot the remote target machine; not guaranteed to succeed. Requires symbols 2013|until gdb support for the HOSTREBOOT packet is implemented. 2014end 2015 2016define sendcore 2017 set kdp_trigger_core_dump = 1 2018 set kdp_flag |= 0x40 2019 set panicd_ip_str = "$arg0" 2020 set panicd_specified = 1 2021 set disable_debug_output = 0 2022 set disableConsoleOutput = 0 2023 set logPanicDataToScreen = 1 2024 set reattach_wait = 1 2025 resume_off 2026end 2027 2028document sendcore 2029Syntax: sendcore <IP address> 2030|Configure the kernel to transmit a kernel coredump to a server (kdumpd) 2031|at the specified IP address. This is useful when the remote target has 2032|not been previously configured to transmit coredumps, and you wish to 2033|preserve kernel state for later examination. NOTE: You must issue a "continue" 2034|command after using this macro to trigger the kernel coredump. The kernel 2035|will resume waiting in the debugger after completion of the coredump. You 2036|may disable coredumps by executing the "disablecore" macro. 2037end 2038 2039define disablecore 2040 set kdp_trigger_core_dump = 0 2041 set kdp_flag |= 0x40 2042 set kdp_flag &= ~0x10 2043 set panicd_specified = 0 2044end 2045 2046document disablecore 2047Syntax: disablecore 2048|Reconfigures the kernel so that it no longer transmits kernel coredumps. This 2049|complements the "sendcore" macro, but it may be used if the kernel has been 2050|configured to transmit coredumps through boot-args as well. 2051end 2052 2053define switchtocorethread 2054 set $newact = (struct thread *) $arg0 2055 select 0 2056 if ($newact->kernel_stack == 0) 2057 echo This thread does not have a stack.\n 2058 echo continuation: 2059 output/a (unsigned) $newact.continuation 2060 echo \n 2061 else 2062 if ($kgm_mtype == 18) 2063 loadcontext $newact->machine->pcb 2064 flushstack 2065 set $pc = $newact->machine->pcb.save_srr0 2066 else 2067 if ($kgm_mtype == 7) 2068 set $kgm_cstatep = (struct x86_kernel_state32 *) \ 2069 ($newact->kernel_stack + 0x4000 \ 2070 - sizeof(struct x86_kernel_state32)) 2071 loadcontext $kgm_cstatep 2072 flushstack 2073 else 2074 echo switchtocorethread not supported on this architecture\n 2075 end 2076 end 2077 showcontext_int 2078 end 2079end 2080 2081document switchtocorethread 2082Syntax: switchtocorethread <address of activation> 2083| The corefile equivalent of "switchtoact". When debugging a kernel coredump 2084| file, this command can be used to examine the execution context and stack 2085| trace for a given thread activation. For example, to view the backtrace 2086| for a thread issue "switchtocorethread <address>", followed by "bt". 2087| Before resuming execution, issue a "resetcorectx" command, to 2088| return to the original execution context. Note that this command 2089| requires gdb support, as documented in Radar 3401283. 2090end 2091 2092define loadcontext 2093 select 0 2094 if ($kgm_mtype == 18) 2095 set $kgm_contextp = (struct savearea *) $arg0 2096 set $pc = $kgm_contextp.save_srr0 2097 set $r1 = $kgm_contextp.save_r1 2098 set $lr = $kgm_contextp.save_lr 2099 2100 set $r2 = $kgm_contextp.save_r2 2101 set $r3 = $kgm_contextp.save_r3 2102 set $r4 = $kgm_contextp.save_r4 2103 set $r5 = $kgm_contextp.save_r5 2104 set $r6 = $kgm_contextp.save_r6 2105 set $r7 = $kgm_contextp.save_r7 2106 set $r8 = $kgm_contextp.save_r8 2107 set $r9 = $kgm_contextp.save_r9 2108 set $r10 = $kgm_contextp.save_r10 2109 set $r11 = $kgm_contextp.save_r11 2110 set $r12 = $kgm_contextp.save_r12 2111 set $r13 = $kgm_contextp.save_r13 2112 set $r14 = $kgm_contextp.save_r14 2113 set $r15 = $kgm_contextp.save_r15 2114 set $r16 = $kgm_contextp.save_r16 2115 set $r17 = $kgm_contextp.save_r17 2116 set $r18 = $kgm_contextp.save_r18 2117 set $r19 = $kgm_contextp.save_r19 2118 set $r20 = $kgm_contextp.save_r20 2119 set $r21 = $kgm_contextp.save_r21 2120 set $r22 = $kgm_contextp.save_r22 2121 set $r23 = $kgm_contextp.save_r23 2122 set $r24 = $kgm_contextp.save_r24 2123 set $r25 = $kgm_contextp.save_r25 2124 set $r26 = $kgm_contextp.save_r26 2125 set $r27 = $kgm_contextp.save_r27 2126 set $r28 = $kgm_contextp.save_r28 2127 set $r29 = $kgm_contextp.save_r29 2128 set $r30 = $kgm_contextp.save_r30 2129 set $r31 = $kgm_contextp.save_r31 2130 2131 set $cr = $kgm_contextp.save_cr 2132 set $ctr = $kgm_contextp.save_ctr 2133 else 2134 if ($kgm_mtype == 7) 2135 set $kgm_contextp = (struct x86_kernel_state32 *) $arg0 2136 set $ebx = $kgm_contextp->k_ebx 2137 set $ebp = $kgm_contextp->k_ebp 2138 set $edi = $kgm_contextp->k_edi 2139 set $esi = $kgm_contextp->k_esi 2140 set $eip = $kgm_contextp->k_eip 2141 set $pc = $kgm_contextp->k_eip 2142 else 2143 echo loadcontext not supported on this architecture\n 2144 end 2145 end 2146end 2147 2148define resetcorectx 2149 select 0 2150 if ($kgm_mtype == 18) 2151 set $kgm_corecontext = (struct savearea *) kdp.saved_state 2152 loadcontext $kgm_corecontext 2153 else 2154 if ($kgm_mtype == 7) 2155 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state 2156 set $ebx = $kdpstatep->ebx 2157 set $ebp = $kdpstatep->ebp 2158 set $edi = $kdpstatep->edi 2159 set $esi = $kdpstatep->esi 2160 set $eip = $kdpstatep->eip 2161 set $eax = $kdpstatep->eax 2162 set $ecx = $kdpstatep->ecx 2163 set $edx = $kdpstatep->edx 2164 flushregs 2165 flushstack 2166 set $pc = $kdpstatep->eip 2167 update 2168 else 2169 echo resetcorectx not supported on this architecture\n 2170 end 2171 end 2172 showcontext_int 2173end 2174 2175document resetcorectx 2176Syntax: resetcorectx 2177| The corefile equivalent of "resetctx". Returns to the original 2178| execution context (that of the active thread at the time of the NMI or 2179| panic). This command should be issued if you wish to resume 2180| execution after using the "switchtocorethread" command. 2181end 2182 2183#Helper function for "showallgdbstacks" 2184 2185define showgdbthread 2186 printf " 0x%08x ", $arg0 2187 set $kgm_thread = *(struct thread *)$arg0 2188 printf "0x%08x ", $arg0 2189 printf "%3d ", $kgm_thread.sched_pri 2190 set $kgm_state = $kgm_thread.state 2191 if $kgm_state & 0x80 2192 printf "I" 2193 end 2194 if $kgm_state & 0x40 2195 printf "P" 2196 end 2197 if $kgm_state & 0x20 2198 printf "A" 2199 end 2200 if $kgm_state & 0x10 2201 printf "H" 2202 end 2203 if $kgm_state & 0x08 2204 printf "U" 2205 end 2206 if $kgm_state & 0x04 2207 printf "R" 2208 end 2209 if $kgm_state & 0x02 2210 printf "S" 2211 end 2212 if $kgm_state & 0x01 2213 printf "W\t" 2214 printf "0x%08x ", $kgm_thread.wait_queue 2215 output /a (unsigned) $kgm_thread.wait_event 2216 if ($kgm_thread.uthread != 0) 2217 set $kgm_uthread = (struct uthread *)$kgm_thread.uthread 2218 if ($kgm_uthread->uu_wmesg != 0) 2219 printf " \"%s\"", $kgm_uthread->uu_wmesg 2220 end 2221 end 2222 end 2223 if $arg1 != 0 2224 if ($kgm_thread.kernel_stack != 0) 2225 if ($kgm_thread.reserved_stack != 0) 2226 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack 2227 end 2228 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack 2229 if ($kgm_mtype == 18) 2230 set $mysp = $kgm_thread.machine.pcb->save_r1 2231 end 2232 if ($kgm_mtype == 7) 2233 set $kgm_statep = (struct x86_kernel_state32 *) \ 2234 ($kgm_thread->kernel_stack + 0x4000 \ 2235 - sizeof(struct x86_kernel_state32)) 2236 set $mysp = $kgm_statep->k_ebp 2237 end 2238 if ($kgm_mtype == 12) 2239 if ($arg0 == $r9) 2240 set $mysp = $r7 2241 else 2242 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr 2243 set $mysp = $kgm_statep->r[7] 2244 end 2245 end 2246 set $prevsp = 0 2247 printf "\n\t\tstacktop=0x%08x", $mysp 2248 if ($arg2 == 0) 2249 switchtoact $arg0 2250 else 2251 switchtocorethread $arg0 2252 end 2253 bt 2254 else 2255 printf "\n\t\t\tcontinuation=" 2256 output /a (unsigned) $kgm_thread.continuation 2257 end 2258 printf "\n" 2259 else 2260 printf "\n" 2261 end 2262end 2263 2264#Use of this macro is currently (8/04) blocked by the fact that gdb 2265#stops evaluating macros when encountering an error, such as a failure 2266#to read memory from a certain location. Until this issue (described in 2267#3758949) is addressed, evaluation of this macro may stop upon 2268#encountering such an error. 2269 2270define showallgdbstacks 2271 set $kgm_head_taskp = &tasks 2272 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 2273 while $kgm_taskp != $kgm_head_taskp 2274 showtaskheader 2275 showtaskint $kgm_taskp 2276 set $kgm_head_actp = &($kgm_taskp->threads) 2277 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 2278 while $kgm_actp != $kgm_head_actp 2279 showactheader 2280 showgdbthread $kgm_actp 1 0 2281 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 2282 end 2283 printf "\n" 2284 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 2285 end 2286 resetctx 2287end 2288 2289document showallgdbstacks 2290Syntax: showallgdbstacks 2291| An alternative to "showallstacks". Iterates through the task list and 2292| displays a gdb generated backtrace for each kernel thread. It is 2293| advantageous in that it is much faster than "showallstacks", and 2294| decodes function call arguments and displays source level traces, but 2295| it has the drawback that it doesn't determine if frames belong to 2296| functions from kernel extensions, as with "showallstacks". 2297| This command may terminate prematurely because of a gdb bug 2298| (Radar 3758949), which stops macro evaluation on memory read 2299| errors. 2300end 2301 2302define showallgdbcorestacks 2303 select 0 2304 set $kgm_head_taskp = &tasks 2305 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 2306 while $kgm_taskp != $kgm_head_taskp 2307 showtaskheader 2308 showtaskint $kgm_taskp 2309 set $kgm_head_actp = &($kgm_taskp->threads) 2310 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 2311 while $kgm_actp != $kgm_head_actp 2312 showactheader 2313 showgdbthread $kgm_actp 1 1 2314 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 2315 end 2316 printf "\n" 2317 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next) 2318 end 2319 resetcorectx 2320end 2321 2322 2323document showallgdbcorestacks 2324Syntax: showallgdbcorestacks 2325|Corefile version of "showallgdbstacks" 2326end 2327 2328 2329define switchtouserthread 2330 select 0 2331 if ($kgm_mtype == 18) 2332 if ($kdp_act_counter == 0) 2333 set $kdpstate = (struct savearea *) kdp.saved_state 2334 end 2335 set $kdp_act_counter = $kdp_act_counter + 1 2336 set $newact = (struct thread *) $arg0 2337 _kgm_flush_loop 2338 set $checkpc = $newact->machine->upcb.save_srr0 2339 if ($checkpc == 0) 2340 echo This activation does not appear to have 2341 echo \20 a valid user context.\n 2342 else 2343 set (struct savearea *) kdp.saved_state=$newact->machine->upcb 2344 set $pc = $checkpc 2345#flush and update seem to be executed lazily by gdb on Tiger, hence the 2346#repeated invocations - see 3743135 2347 _kgm_flush_loop 2348# This works because the new pmap is used only for reads 2349 set kdp_pmap = $newact->task->map->pmap 2350 _kgm_flush_loop 2351 _kgm_update_loop 2352 end 2353 else 2354 echo switchtouserthread not implemented for this architecture.\n 2355 end 2356end 2357 2358document switchtouserthread 2359Syntax: switchtouserthread <address of thread> 2360| Analogous to switchtoact, but switches to the user context of a 2361| specified thread address. Similar to the "showuserstack" 2362| command, but this command does not return gdb to the kernel context 2363| immediately. This is to assist with the following (rather risky) 2364| manoeuvre - upon switching to the user context and virtual address 2365| space, the user may choose to call remove-symbol-file on the 2366| mach_kernel symbol file, and then add-symbol-file on the user space 2367| binary's symfile. gdb can then generate symbolic backtraces 2368| for the user space thread. To return to the 2369| kernel context and virtual address space, the process must be 2370| reversed, i.e. call remove-symbol-file on the user space symbols, and 2371| then add-symbol-file on the appropriate mach_kernel, and issue the 2372| "resetstacks" command. Note that gdb may not react kindly to all these 2373| symbol file switches. The same restrictions that apply to "showuserstack" 2374| apply here - pages that have been paged out cannot be read while in the 2375| debugger context, so backtraces may terminate early. 2376| If the virtual addresses in the stack trace do not conflict with those 2377| of symbols in the kernel's address space, it may be sufficient to 2378| just do an add-symbol-file on the user space binary's symbol file. 2379| Note that while this command works on Panther's gdb, an issue 2380| with Tiger gdb (3743135) appears to hamper the evaluation of this 2381| macro in some cases. 2382end 2383 2384define showmetaclass 2385 set $kgm_metaclassp = (OSMetaClass *)$arg0 2386 printf "%-5d", $kgm_metaclassp->instanceCount 2387 printf "x %5d bytes", $kgm_metaclassp->classSize 2388 printf " %s\n", $kgm_metaclassp->className->string 2389end 2390 2391define showstring 2392 printf "\"%s\"", ((OSString *)$arg0)->string 2393end 2394 2395define shownumber 2396 printf "%lld", ((OSNumber *)$arg0)->value 2397end 2398 2399define showboolean 2400 if ($arg0 == gOSBooleanFalse) 2401 printf "No" 2402 else 2403 printf "Yes" 2404 end 2405end 2406 2407define showdata 2408 set $kgm_data = (OSData *)$arg0 2409 2410 printf "<" 2411 set $kgm_datap = (const unsigned char *) $kgm_data->data 2412 2413 set $kgm_printstr = 0 2414 if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3)) 2415 set $kgm_bytes = *(unsigned int *) $kgm_datap 2416 if (0xffff0000 & $kgm_bytes) 2417 set $kgm_idx = 0 2418 set $kgm_printstr = 1 2419 while ($kgm_idx++ < 4) 2420 set $kgm_bytes = $kgm_bytes >> 8 2421 set $kgm_char = 0xff & $kgm_bytes 2422 if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e))) 2423 set $kgm_printstr = 0 2424 end 2425 end 2426 end 2427 end 2428 2429 set $kgm_idx = 0 2430 if ($kgm_printstr) 2431 set $kgm_quoted = 0 2432 while ($kgm_idx < $kgm_data->length) 2433 set $kgm_char = $kgm_datap[$kgm_idx++] 2434 if ($kgm_char) 2435 if (0 == $kgm_quoted) 2436 set $kgm_quoted = 1 2437 if ($kgm_idx > 1) 2438 printf ",\"" 2439 else 2440 printf "\"" 2441 end 2442 end 2443 printf "%c", $kgm_char 2444 else 2445 if ($kgm_quoted) 2446 set $kgm_quoted = 0 2447 printf "\"" 2448 end 2449 end 2450 end 2451 if ($kgm_quoted) 2452 printf "\"" 2453 end 2454 else 2455 if (0 == (3 & (unsigned int)$kgm_datap)) 2456 while (($kgm_idx + 3) <= $kgm_data->length) 2457 printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx] 2458 set $kgm_idx = $kgm_idx + 4 2459 end 2460 end 2461 while ($kgm_idx < $kgm_data->length) 2462 printf "%02x", $kgm_datap[$kgm_idx++] 2463 end 2464 end 2465 printf ">" 2466end 2467 2468define showdictionaryint 2469 set $kgm$arg0_dict = (OSDictionary *)$arg1 2470 2471 printf "{" 2472 set $kgm$arg0_idx = 0 2473 while ($kgm$arg0_idx < $kgm$arg0_dict->count) 2474 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key 2475 showobjectint _$arg0 $kgm_obj 2476 printf "=" 2477 set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value 2478 showobjectint _$arg0 $kgm_obj 2479 if ($kgm$arg0_idx < $kgm$arg0_dict->count) 2480 printf "," 2481 end 2482 end 2483 printf "}" 2484end 2485 2486define indent 2487 set $kgm_idx = 0 2488 while ($kgm_idx < $arg0) 2489 if ($arg1 & (1 << $kgm_idx++)) 2490 printf "| " 2491 else 2492 printf " " 2493 end 2494 end 2495end 2496 2497define showregdictionary 2498 indent $kgm_reg_depth+2 $arg1 2499 printf "{\n" 2500 2501 set $kgm_reg_idx = 0 2502 while ($kgm_reg_idx < $arg0->count) 2503 indent $kgm_reg_depth+2 $arg1 2504 printf " " 2505 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key 2506 showobjectint _ $kgm_obj 2507 printf " = " 2508 2509 set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value 2510 showobjectint _ $kgm_obj 2511 printf "\n" 2512 end 2513 indent $kgm_reg_depth+2 $arg1 2514 printf "}\n" 2515end 2516 2517 2518define showarraysetint 2519 set $kgm$arg0_array = (OSArray *)$arg1 2520 2521 set $kgm$arg0_idx = 0 2522 while ($kgm$arg0_idx < $kgm$arg0_array->count) 2523 set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++] 2524 showobjectint _$arg0 $kgm_obj 2525 if ($kgm$arg0_idx < $kgm$arg0_array->count) 2526 printf "," 2527 end 2528 end 2529end 2530 2531define showarrayint 2532 printf "(" 2533 showarraysetint $arg0 $arg1 2534 printf ")" 2535end 2536 2537define showsetint 2538 set $kgm_array = ((OSSet *)$arg1)->members 2539 printf "[" 2540 showarraysetint $arg0 $kgm_array 2541 printf "]" 2542end 2543 2544 2545define showobjectint 2546 set $kgm_obj = (OSObject *) $arg1 2547 set $kgm_vt = *((void **) $arg1) 2548 2549 if ($kgm_mtype == 12) 2550 set $kgm_vt = $kgm_vt - 2 * sizeof(void *) 2551 end 2552 2553 if ($kgm_show_object_addrs) 2554 printf "`object %p, vt ", $arg1 2555 output /a (unsigned) $kgm_vt 2556 if ($kgm_show_object_retain) 2557 printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16 2558 end 2559 printf "` " 2560 end 2561 2562 if ($kgm_vt == _ZTV8OSString) 2563 showstring $arg1 2564 else 2565 if ($kgm_vt == _ZTV8OSSymbol) 2566 showstring $arg1 2567 else 2568 if ($kgm_vt == _ZTV8OSNumber) 2569 shownumber $arg1 2570 else 2571 if ($kgm_vt == _ZTV6OSData) 2572 showdata $arg1 2573 else 2574 if ($kgm_vt == _ZTV9OSBoolean) 2575 showboolean $arg1 2576 else 2577 if ($kgm_vt == _ZTV12OSDictionary) 2578 showdictionaryint _$arg0 $arg1 2579 else 2580 if ($kgm_vt == _ZTV7OSArray) 2581 showarrayint _$arg0 $arg1 2582 else 2583 if ($kgm_vt == _ZTV5OSSet) 2584 showsetint _$arg0 $arg1 2585 else 2586 if ($kgm_show_object_addrs == 0) 2587 printf "`object %p, vt ", $arg1 2588 output /a (unsigned) $kgm_vt 2589 printf "`" 2590 end 2591 end 2592 end 2593 end 2594 end 2595 end 2596 end 2597 end 2598 end 2599end 2600 2601define showobject 2602 set $kgm_save = $kgm_show_object_addrs 2603 set $kgm_show_object_addrs = 1 2604 set $kgm_show_object_retain = 1 2605 showobjectint _ $arg0 2606 set $kgm_show_object_addrs = $kgm_save 2607 set $kgm_show_object_retain = 0 2608 printf "\n" 2609end 2610document showobject 2611Syntax: (gdb) showobject <object address> 2612| Show info about an OSObject - its vtable ptr and retain count. 2613| If the object is a simple container class, more info will be shown. 2614end 2615 2616define dictget 2617 set $kgm_dictp = (OSDictionary *)$arg0 2618 set $kgm_keyp = (const OSSymbol *)$arg1 2619 set $kgm_idx = 0 2620 set $kgm_result = 0 2621 while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0)) 2622 if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key) 2623 set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value 2624 end 2625 set $kgm_idx = $kgm_idx + 1 2626 end 2627end 2628 2629 2630define showregistryentryrecurse 2631 set $kgm_re = (IOService *)$arg1 2632 set $kgm$arg0_stack = (unsigned long long) $arg2 2633 2634 if ($arg3) 2635 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth) 2636 else 2637 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth) 2638 end 2639 2640 dictget $kgm_re->fRegistryTable $kgm_childkey 2641 set $kgm$arg0_child_array = (OSArray *) $kgm_result 2642 2643 if ($kgm$arg0_child_array) 2644 set $kgm$arg0_child_count = $kgm$arg0_child_array->count 2645 else 2646 set $kgm$arg0_child_count = 0 2647 end 2648 2649 if ($kgm$arg0_child_count) 2650 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth) 2651 else 2652 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth) 2653 end 2654 2655 indent $kgm_reg_depth $kgm$arg0_stack 2656 printf "+-o " 2657 2658 dictget $kgm_re->fRegistryTable $kgm_namekey 2659 if ($kgm_result == 0) 2660 dictget $kgm_re->fRegistryTable gIONameKey 2661 end 2662 if ($kgm_result == 0) 2663 dictget $kgm_re->fPropertyTable gIOClassKey 2664 end 2665 2666 if ($kgm_result != 0) 2667 printf "%s", ((OSString *)$kgm_result)->string 2668 else 2669 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name) 2670 printf "%s", ((IOService*)$kgm_re)->pwrMgt->Name 2671 else 2672# printf ", guessclass " 2673# guessclass $kgm_re 2674 printf "??" 2675 end 2676 end 2677 2678 2679 printf " <object %p, ", $kgm_re 2680 printf "vtable " 2681 set $kgm_vt = (unsigned) *(void**) $kgm_re 2682 if ($kgm_mtype == 12) 2683 set $kgm_vt = $kgm_vt - 2 * sizeof(void *) 2684 end 2685 output /a $kgm_vt 2686 2687 if ($kgm_vt != _ZTV15IORegistryEntry) 2688 printf ", " 2689 set $kgm_state = $kgm_re->__state[0] 2690 # kIOServiceRegisteredState 2691 if (0 == ($kgm_state & 2)) 2692 printf "!" 2693 end 2694 printf "registered, " 2695 # kIOServiceMatchedState 2696 if (0 == ($kgm_state & 4)) 2697 printf "!" 2698 end 2699 printf "matched, " 2700 # kIOServiceInactiveState 2701 if ($kgm_state & 1) 2702 printf "in" 2703 end 2704 printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount) 2705 end 2706 printf ">\n" 2707 2708 if ($kgm_show_props) 2709 set $kgm_props = $kgm_re->fPropertyTable 2710 showregdictionary $kgm_props $kgm$arg0_stack 2711 end 2712 2713 # recurse 2714 if ($kgm$arg0_child_count != 0) 2715 2716 set $kgm_reg_depth = $kgm_reg_depth + 1 2717 set $kgm$arg0_child_idx = 0 2718 2719 while ($kgm$arg0_child_idx < $kgm$arg0_child_count) 2720 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++] 2721 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count) 2722 showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib 2723 end 2724 2725 set $kgm_reg_depth = $kgm_reg_depth - 1 2726 end 2727end 2728 2729define showregistryentryint 2730 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane[2] 2731 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane[4] 2732 2733 showregistryentryrecurse _ $arg0 0 0 2734end 2735 2736define showregistry 2737 set $kgm_reg_depth = 0 2738 set $kgm_show_props = 0 2739 showregistryentryint gRegistryRoot 2740end 2741document showregistry 2742Syntax: (gdb) showregistry 2743| Show info about all registry entries in the current plane. 2744end 2745 2746define showregistryprops 2747 set $kgm_reg_depth = 0 2748 set $kgm_show_props = 1 2749 showregistryentryint gRegistryRoot 2750end 2751document showregistryprops 2752Syntax: (gdb) showregistryprops 2753| Show info about all registry entries in the current plane, and their properties. 2754| set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display 2755| more verbose information 2756end 2757 2758define showregistryentry 2759 set $kgm_reg_depth = 0 2760 set $kgm_show_props = 1 2761 showregistryentryint $arg0 2762end 2763document showregistryentry 2764Syntax: (gdb) showregistryentry <object address> 2765| Show info about a registry entry; its properties and descendants in the current plane. 2766end 2767 2768define setregistryplane 2769 if ($arg0) 2770 set $kgm_reg_plane = (void **) $arg0 2771 else 2772 showobjectint _ gIORegistryPlanes 2773 printf "\n" 2774 end 2775end 2776document setregistryplane 2777Syntax: (gdb) setregistryplane <plane object address> 2778| Set the plane to be used for the iokit registry macros. An argument of zero will 2779| display known planes. 2780end 2781 2782define guessclass 2783 set $kgm_classidx = 0 2784 set $kgm_lookvt = *((void **) $arg0) 2785 set $kgm_bestvt = (void *) 0 2786 set $kgm_bestidx = 0 2787 2788 while $kgm_classidx < sAllClassesDict->count 2789 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value 2790 2791 set $kgm_vt = *((void **) $kgm_meta) 2792 2793 if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt)) 2794 set $kgm_bestvt = $kgm_vt 2795 set $kgm_bestidx = $kgm_classidx 2796 end 2797 set $kgm_classidx = $kgm_classidx + 1 2798 end 2799 printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string 2800end 2801 2802define showallclasses 2803 set $kgm_classidx = 0 2804 while $kgm_classidx < sAllClassesDict->count 2805 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value 2806 showmetaclass $kgm_meta 2807 end 2808end 2809 2810document showallclasses 2811Syntax: (gdb) showallclasses 2812| Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details. 2813end 2814 2815define showioalloc 2816 printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024 2817 printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024 2818 printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024 2819 printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024 2820end 2821 2822document showioalloc 2823Syntax: (gdb) showioalloc 2824| Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details. 2825end 2826 2827define showosobjecttracking 2828 set $kgm_next = (OSObjectTracking *) gOSObjectTrackList.next 2829 while $kgm_next != &gOSObjectTrackList 2830 set $obj = (OSObject *) ($kgm_next+1) 2831 showobject $obj 2832 set $kgm_idx = 0 2833 while $kgm_idx < (sizeof($kgm_next->bt) / sizeof($kgm_next->bt[0])) 2834 if ((unsigned) $kgm_next->bt[$kgm_idx] > (unsigned) sectPRELINKB) 2835 showkmodaddr $kgm_next->bt[$kgm_idx] 2836 printf "\n" 2837 else 2838 if ((unsigned) $kgm_next->bt[$kgm_idx] > 0) 2839 output /a (unsigned) $kgm_next->bt[$kgm_idx] 2840 printf "\n" 2841 end 2842 end 2843 set $kgm_idx = $kgm_idx + 1 2844 end 2845 printf "\n" 2846 set $kgm_next = (OSObjectTracking *) $kgm_next->link.next 2847 end 2848end 2849 2850document showosobjecttracking 2851Syntax: (gdb) showosobjecttracking 2852| Show the list of tracked OSObject allocations with backtraces. 2853| Boot with the kOSTraceObjectAlloc (0x00400000) io debug flag set. 2854| Set gOSObjectTrackThread to 1 or a thread_t to capture new OSObjects allocated by a thread or all threads. 2855end 2856 2857define readphys 2858 set kdp_trans_off = 1 2859 x/x $arg0 2860 set kdp_trans_off = 0 2861end 2862 2863define readphys64 2864 if ($kgm_mtype == 18) 2865 set kdp_src_high32 = ((uint32_t) ($arg0)) >> 32 2866 x/x (uint32_t) (($arg0) & 0x00000000ffffffffUL) 2867 set kdp_src_high32 = 0 2868 else 2869 echo readphys64 not available on this architecture.\n 2870 end 2871end 2872 2873document readphys 2874| The argument is interpreted as a physical address, and the word addressed is 2875| displayed. While this fails if no physical page exists at the given address, 2876| it must be used with caution. 2877end 2878 2879document readphys64 2880| The argument is interpreted as a 64-bit physical address, and the word 2881| addressed is displayed. While this fails if no physical page exists at the 2882| given address, it must be used with caution. 2883end 2884 2885define addkextsyms 2886 shell ls $arg0/* | xargs -n 1 echo add-symbol-file > /tmp/gdb-syms 2887 source /tmp/gdb-syms 2888 set $kgm_show_kmod_syms = 1 2889end 2890 2891document addkextsyms 2892| Takes a directory of symbols for kexts generated with kextcache -y and loads them 2893| into gdb. 2894| (gdb) addkextsyms /path/to/symboldir 2895end 2896 2897define showprocfiles 2898 if ($argc == 1) 2899 _showprocheader 2900 _showprocfiles $arg0 2901 else 2902 printf "| Usage:\n|\n" 2903 help showprocfiles 2904 end 2905end 2906document showprocfiles 2907Syntax: (gdb) showprocfiles <proc_t> 2908| Given a proc_t pointer, display the list of open file descriptors for the 2909| referenced process. 2910end 2911 2912define _showprocheader 2913 printf "fd fileglob fg flags fg type fg data info\n" 2914 printf "----- ---------- ---------- -------- ---------- -------------------\n" 2915end 2916 2917define _showprocfiles 2918 set $kgm_spf_filedesc = ((proc_t)$arg0)->p_fd 2919 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile 2920 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles 2921 set $kgm_spf_count = 0 2922 while ($kgm_spf_count <= $kgm_spf_last) 2923 if ($kgm_spf_ofiles[$kgm_spf_count] == 0) 2924 # DEBUG: For files that were open, but are now closed 2925 # printf "%-5d FILEPROC_NULL\n", $kgm_spf_count 2926 else 2927 # display fd #, fileglob address, fileglob flags 2928 set $kgm_spf_flags = $kgm_spf_ofiles[$kgm_spf_count].f_flags 2929 set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob 2930 printf "%-5d 0x%08x 0x%08x ", $kgm_spf_count, $kgm_spf_fg, $kgm_spf_flags 2931 # decode fileglob type 2932 set $kgm_spf_fgt = $kgm_spf_fg->fg_type 2933 if ($kgm_spf_fgt == 1) 2934 printf "VNODE " 2935 end 2936 if ($kgm_spf_fgt == 2) 2937 printf "SOCKET " 2938 end 2939 if ($kgm_spf_fgt == 3) 2940 printf "PSXSHM " 2941 end 2942 if ($kgm_spf_fgt == 4) 2943 printf "PSXSEM " 2944 end 2945 if ($kgm_spf_fgt == 5) 2946 printf "KQUEUE " 2947 end 2948 if ($kgm_spf_fgt == 6) 2949 printf "PIPE " 2950 end 2951 if ($kgm_spf_fgt == 7) 2952 printf "FSEVENTS" 2953 end 2954 if ($kgm_spf_fgt < 1 || $kgm_spf_fgt > 7) 2955 printf "?: %-5d", $kgm_spf_fgt 2956 end 2957 2958 # display fileglob data address and decode interesting fact(s) 2959 # about data, if we know any 2960 set $kgm_spf_fgd = $kgm_spf_fg->fg_data 2961 printf " 0x%08x ", $kgm_spf_fgd 2962 if ($kgm_spf_fgt == 1) 2963 set $kgm_spf_name = ((struct vnode *)$kgm_spf_fgd)->v_name 2964 if ($kgm_spf_name == 0) 2965 printf "(null)" 2966 else 2967 printf "%s", $kgm_spf_name 2968 end 2969 end 2970 printf "\n" 2971 end 2972 set $kgm_spf_count = $kgm_spf_count + 1 2973 end 2974end 2975 2976# 2977# Show all the advisory file locks held by a process for each of the vnode 2978# type files that it has open; do this by walking the per process open file 2979# table and looking at any vnode type fileglob that has a non-NULL lock list 2980# associated with it. 2981# 2982define showproclocks 2983 if ($argc == 1) 2984 _showproclocks $arg0 2985 else 2986 printf "| Usage:\n|\n" 2987 help showproclocks 2988 end 2989end 2990document showproclocks 2991Syntax: (gdb) showproclocks <proc_t> 2992| Given a proc_t pointer, display the list of advisory file locks held by the 2993| referenced process. 2994end 2995 2996define _showproclocks 2997 set $kgm_spl_filedesc = ((proc_t)$arg0)->p_fd 2998 set $kgm_spl_last = $kgm_spl_filedesc->fd_lastfile 2999 set $kgm_spl_ofiles = $kgm_spl_filedesc->fd_ofiles 3000 set $kgm_spl_count = 0 3001 set $kgm_spl_seen = 0 3002 while ($kgm_spl_count <= $kgm_spl_last) 3003 if ($kgm_spl_ofiles[$kgm_spl_count] == 0) 3004 # DEBUG: For files that were open, but are now closed 3005 # printf "%-5d FILEPROC_NULL\n", $kgm_spl_count 3006 else 3007 set $kgm_spl_fg = $kgm_spl_ofiles[$kgm_spl_count].f_fglob 3008 # decode fileglob type 3009 set $kgm_spl_fgt = $kgm_spl_fg->fg_type 3010 if ($kgm_spl_fgt == 1) 3011 set $kgm_spl_fgd = $kgm_spl_fg->fg_data 3012 set $kgm_spl_name = ((struct vnode *)$kgm_spl_fgd)->v_name 3013 set $kgm_spl_vnode = ((vnode_t)$kgm_spl_fgd) 3014 set $kgm_spl_lockiter = $kgm_spl_vnode->v_lockf 3015 if ($kgm_spl_lockiter != 0) 3016 if ($kgm_spl_seen == 0) 3017 _showvnodelockheader 3018 end 3019 set $kgm_spl_seen = $kgm_spl_seen + 1 3020 printf "( fd %d, name ", $kgm_spl_count 3021 if ($kgm_spl_name == 0) 3022 printf "(null) )" 3023 else 3024 printf "%s )\n", $kgm_spl_name 3025 end 3026 _showvnodelocks $kgm_spl_fgd 3027 end 3028 end 3029 end 3030 set $kgm_spl_count = $kgm_spf_count + 1 3031 end 3032 printf "%d total locks for 0x%08x\n", $kgm_spl_seen, $arg0 3033end 3034 3035define showprocinfo 3036 set $kgm_spi_proc = (proc_t)$arg0 3037 printf "Process 0x%08x\n", $kgm_spi_proc 3038 printf " name %s\n", $kgm_spi_proc->p_comm 3039 printf " pid:%.8d", $kgm_spi_proc->p_pid 3040 printf " task:0x%.8x", $kgm_spi_proc->task 3041 printf " p_stat:%.1d", $kgm_spi_proc->p_stat 3042 printf " parent pid:%.8d", $kgm_spi_proc->p_ppid 3043 # decode part of credential 3044 set $kgm_spi_cred = $kgm_spi_proc->p_ucred 3045 if ($kgm_spi_cred != 0) 3046 printf "Cred: euid %d ruid %d svuid %d\n", $kgm_spi_cred->cr_uid, $kgm_spi_cred->cr_ruid, $kgm_spi_cred->cr_svuid 3047 else 3048 printf "Cred: (null)\n" 3049 end 3050 # decode flags 3051 set $kgm_spi_flag = $kgm_spi_proc->p_flag 3052 printf "Flags: 0x%08x\n", $kgm_spi_flag 3053 if ($kgm_spi_flag & 0x00000001) 3054 printf " 0x00000001 - may hold advisory locks\n" 3055 end 3056 if ($kgm_spi_flag & 0x00000002) 3057 printf " 0x00000002 - has a controlling tty\n" 3058 end 3059 if ($kgm_spi_flag & 0x00000004) 3060 printf " 0x00000004 - process is 64 bit\n" 3061 else 3062 printf " !0x00000004 - process is 32 bit\n" 3063 end 3064 if ($kgm_spi_flag & 0x00000008) 3065 printf " 0x00000008 - no SIGCHLD on child stop\n" 3066 end 3067 if ($kgm_spi_flag & 0x00000010) 3068 printf " 0x00000010 - waiting for child exec/exit\n" 3069 end 3070 if ($kgm_spi_flag & 0x00000020) 3071 printf " 0x00000020 - has started profiling\n" 3072 end 3073 if ($kgm_spi_flag & 0x00000040) 3074 printf " 0x00000040 - in select; wakeup/waiting danger\n" 3075 end 3076 if ($kgm_spi_flag & 0x00000080) 3077 printf " 0x00000080 - was stopped and continued\n" 3078 end 3079 if ($kgm_spi_flag & 0x00000100) 3080 printf " 0x00000100 - has set privileges since exec\n" 3081 end 3082 if ($kgm_spi_flag & 0x00000200) 3083 printf " 0x00000200 - system process: no signals, stats, or swap\n" 3084 end 3085 if ($kgm_spi_flag & 0x00000400) 3086 printf " 0x00000400 - timing out during a sleep\n" 3087 end 3088 if ($kgm_spi_flag & 0x00000800) 3089 printf " 0x00000800 - debugged process being traced\n" 3090 end 3091 if ($kgm_spi_flag & 0x00001000) 3092 printf " 0x00001000 - debugging process has waited for child\n" 3093 end 3094 if ($kgm_spi_flag & 0x00002000) 3095 printf " 0x00002000 - exit in progress\n" 3096 end 3097 if ($kgm_spi_flag & 0x00004000) 3098 printf " 0x00004000 - process has called exec\n" 3099 end 3100 if ($kgm_spi_flag & 0x00008000) 3101 printf " 0x00008000 - owe process an addupc() XXX\n" 3102 end 3103 if ($kgm_spi_flag & 0x00010000) 3104 printf " 0x00010000 - affinity for Rosetta children\n" 3105 end 3106 if ($kgm_spi_flag & 0x00020000) 3107 printf " 0x00020000 - wants to run Rosetta\n" 3108 end 3109 if ($kgm_spi_flag & 0x00040000) 3110 printf " 0x00040000 - has wait() in progress\n" 3111 end 3112 if ($kgm_spi_flag & 0x00080000) 3113 printf " 0x00080000 - kdebug tracing on for this process\n" 3114 end 3115 if ($kgm_spi_flag & 0x00100000) 3116 printf " 0x00100000 - blocked due to SIGTTOU or SIGTTIN\n" 3117 end 3118 if ($kgm_spi_flag & 0x00200000) 3119 printf " 0x00200000 - has called reboot()\n" 3120 end 3121 if ($kgm_spi_flag & 0x00400000) 3122 printf " 0x00400000 - is TBE state\n" 3123 end 3124 if ($kgm_spi_flag & 0x00800000) 3125 printf " 0x00800000 - signal exceptions\n" 3126 end 3127 if ($kgm_spi_flag & 0x01000000) 3128 printf " 0x01000000 - being branch traced\n" 3129 end 3130 if ($kgm_spi_flag & 0x02000000) 3131 printf " 0x02000000 - has vfork() children\n" 3132 end 3133 if ($kgm_spi_flag & 0x04000000) 3134 printf " 0x04000000 - not allowed to attach\n" 3135 end 3136 if ($kgm_spi_flag & 0x08000000) 3137 printf " 0x08000000 - vfork() in progress\n" 3138 end 3139 if ($kgm_spi_flag & 0x10000000) 3140 printf " 0x10000000 - no shared libraries\n" 3141 end 3142 if ($kgm_spi_flag & 0x20000000) 3143 printf " 0x20000000 - force quota for root\n" 3144 end 3145 if ($kgm_spi_flag & 0x40000000) 3146 printf " 0x40000000 - no zombies when children exit\n" 3147 end 3148 if ($kgm_spi_flag & 0x80000000) 3149 printf " 0x80000000 - don't hang on remote FS ops\n" 3150 end 3151 # decode state 3152 set $kgm_spi_state = $kgm_spi_proc->p_stat 3153 printf "State: " 3154 if ($kgm_spi_state == 1) 3155 printf "Idle\n" 3156 end 3157 if ($kgm_spi_state == 2) 3158 printf "Run\n" 3159 end 3160 if ($kgm_spi_state == 3) 3161 printf "Sleep\n" 3162 end 3163 if ($kgm_spi_state == 4) 3164 printf "Stop\n" 3165 end 3166 if ($kgm_spi_state == 5) 3167 printf "Zombie\n" 3168 end 3169 if ($kgm_spi_state == 6) 3170 printf "Reaping\n" 3171 end 3172 if ($kgm_spi_state < 1 || $kgm_spi_state > 6) 3173 printf "(Unknown)\n" 3174 end 3175end 3176 3177document showprocinfo 3178Syntax: (gdb) showprocinfo <proc_t> 3179| Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields. 3180end 3181 3182# 3183# dump the zombprocs 3184# 3185define zombproc 3186 set $basep = (struct proc *)zombproc->lh_first 3187 set $pp = $basep 3188 while $pp 3189 showprocinfo $pp 3190 set $pp = $pp->p_list.le_next 3191 end 3192end 3193 3194document zombproc 3195Syntax: (gdb) zombproc 3196| Routine to print out all procs in the zombie list 3197end 3198 3199# 3200# dump the zombstacks 3201# 3202define zombstacks 3203 set $basep = (struct proc *)zombproc->lh_first 3204 set $pp = $basep 3205 while $pp 3206 if $pp->p_stat != 5 3207 showtaskstacks $pp->task 3208 end 3209 set $pp = $pp->p_list.le_next 3210 end 3211end 3212 3213document zombstacks 3214Syntax: (gdb) zombstacks 3215| Routine to print out all stacks of tasks that are exiting 3216end 3217 3218 3219# 3220# dump the allprocs 3221# 3222define allproc 3223 set $basep = (struct proc *)allproc->lh_first 3224 set $pp = $basep 3225 while $pp 3226 showprocinfo $pp 3227 set $pp = $pp->p_list.le_next 3228 end 3229end 3230 3231document allproc 3232Syntax: (gdb) allproc 3233| Routine to print out all process in the system 3234| which are not in the zombie list 3235end 3236 3237 3238 3239define print_vnode 3240 set $vp = (struct vnode *)$arg0 3241 printf " " 3242 printf " vp 0x%.8x", $vp 3243 printf " use %d", $vp->v_usecount 3244 printf " io %d", $vp->v_iocount 3245 printf " kuse %d", $vp->v_kusecount 3246 printf " type %d", $vp->v_type 3247 printf " flg 0x%.8x", $vp->v_flag 3248 printf " lflg 0x%.8x", $vp->v_lflag 3249 printf " par 0x%.8x", $vp->v_parent 3250 set $_name = (char *)$vp->v_name 3251 if ($_name != 0) 3252 printf " %s", $_name 3253 end 3254 if ($vp->v_type == VREG) && ($vp->v_un.vu_ubcinfo != 0) 3255 printf " mapped %d", ($vp->v_un.vu_ubcinfo.ui_flags & 0x08) ? 1 : 0 3256 end 3257 printf "\n" 3258end 3259 3260document print_vnode 3261Syntax: (gdb) print_vnode <vnode> 3262| Prints out the fields of a vnode struct 3263end 3264 3265define showprocvnodes 3266 set $pp = (struct proc *)$arg0 3267 set $fdp = (struct filedesc *)$pp->p_fd 3268 set $cvp = $fdp->fd_cdir 3269 set $rvp = $fdp->fd_rdir 3270 if $cvp 3271 printf "Current Working Directory \n" 3272 print_vnode $cvp 3273 printf "\n" 3274 end 3275 if $rvp 3276 printf "Current Root Directory \n" 3277 print_vnode $rvp 3278 printf "\n" 3279 end 3280 set $count = 0 3281 set $fpp = (struct fileproc **)($fdp->fd_ofiles) 3282 set $fpo = (char)($fdp->fd_ofileflags[0]) 3283 while $count < $fdp->fd_nfiles 3284 #printf"fpp %x ", *$fpp 3285 if *$fpp 3286 set $fg =(struct fileglob *)((**$fpp)->f_fglob) 3287 if $fg && (($fg)->fg_type == 1) 3288 if $fdp->fd_ofileflags[$count] & 4 3289 printf "U: " 3290 else 3291 printf " " 3292 end 3293 printf "fd = %d ", $count 3294 print_vnode $fg->fg_data 3295 end 3296 end 3297 set $fpp = $fpp + 1 3298 set $count = $count + 1 3299 end 3300end 3301 3302document showprocvnodes 3303Syntax: (gdb) showprocvnodes <proc_address> 3304| Routine to print out all the open fds 3305| which are vnodes in a process 3306end 3307 3308define showallprocvnodes 3309 set $basep = (struct proc *)allproc->lh_first 3310 set $pp = $basep 3311 while $pp 3312 printf "============================================ \n" 3313 showprocinfo $pp 3314 showprocvnodes $pp 3315 set $pp = $pp->p_list.le_next 3316 end 3317end 3318 3319document showallprocvnodes 3320Syntax: (gdb) showallprocvnodes 3321| Routine to print out all the open fds 3322| which are vnodes 3323end 3324 3325 3326# 3327# dump the childrent of a proc 3328# 3329define showinitchild 3330 set $basep = (struct proc *)initproc->p_children.lh_first 3331 set $pp = $basep 3332 while $pp 3333 showprocinfo $pp 3334 set $pp = $pp->p_sibling.le_next 3335 end 3336end 3337 3338document showinitchild 3339Syntax: (gdb) showinitchild 3340| Routine to print out all processes in the system 3341| which are children of init process 3342end 3343 3344 3345define showmountallvnodes 3346 set $mp = (struct mount *)$arg0 3347 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first 3348 set $vp = $basevp 3349 printf "____________________ Vnode list Queue ---------------\n" 3350 while $vp 3351 print_vnode $vp 3352 set $vp = $vp->v_mntvnodes->tqe_next 3353 end 3354 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first 3355 set $vp = $basevp 3356 printf "____________________ Worker Queue ---------------\n" 3357 while $vp 3358 print_vnode $vp 3359 set $vp = $vp->v_mntvnodes->tqe_next 3360 end 3361 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first 3362 set $vp = $basevp 3363 printf "____________________ New vnodes Queue ---------------\n" 3364 while $vp 3365 print_vnode $vp 3366 set $vp = $vp->v_mntvnodes->tqe_next 3367 end 3368end 3369document showmountallvnodes 3370Syntax: showmountallvnodes <struct mount *> 3371| Print the vnode inactive list 3372end 3373 3374 3375define showmountvnodes 3376 set $mp = (struct mount *)$arg0 3377 set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first 3378 set $vp = $basevp 3379 printf "____________________ Vnode list Queue ---------------\n" 3380 while $vp 3381 print_vnode $vp 3382 set $vp = $vp->v_mntvnodes->tqe_next 3383 end 3384end 3385document showmountvnodes 3386Syntax: showmountvnodes <struct mount *> 3387| Print the vnode list 3388end 3389 3390 3391 3392define showworkqvnodes 3393 set $mp = (struct mount *)$arg0 3394 set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first 3395 set $vp = $basevp 3396 printf "____________________ Worker Queue ---------------\n" 3397 while $vp 3398 print_vnode $vp 3399 set $vp = $vp->v_mntvnodes->tqe_next 3400 end 3401end 3402document showworkqvnodes 3403Syntax: showworkqvnodes <struct mount *> 3404| Print the vnode worker list 3405end 3406 3407 3408define shownewvnodes 3409 set $mp = (struct mount *)$arg0 3410 set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first 3411 set $vp = $basevp 3412 printf "____________________ New vnodes Queue ---------------\n" 3413 while $vp 3414 print_vnode $vp 3415 set $vp = $vp->v_mntvnodes->tqe_next 3416 end 3417end 3418 3419document shownewvnodes 3420Syntax: shownewvnodes <struct mount *> 3421| Print the new vnode list 3422end 3423 3424 3425# 3426# print mount point info 3427define print_mount 3428 set $mp = (struct mount *)$arg0 3429 printf " " 3430 printf " mp 0x%.8x", $mp 3431 printf " flag %x", $mp->mnt_flag 3432 printf " kern_flag %x", $mp->mnt_kern_flag 3433 printf " lflag %x", $mp->mnt_lflag 3434 printf " type: %s", $mp->mnt_vfsstat.f_fstypename 3435 printf " mnton: %s", $mp->mnt_vfsstat.f_mntonname 3436 printf " mntfrom: %s", $mp->mnt_vfsstat.f_mntfromname 3437 printf "\n" 3438end 3439 3440define showallmounts 3441 set $mp=(struct mount *)mountlist.tqh_first 3442 while $mp 3443 print_mount $mp 3444 set $mp = $mp->mnt_list.tqe_next 3445 end 3446end 3447 3448document showallmounts 3449Syntax: showallmounts 3450| Print all mount points 3451end 3452 3453define pcprint 3454 set $pc = $arg0 3455 if ((unsigned int)$pc <= (unsigned int) $kgm_fkmodmax) && \ 3456 ((unsigned int)$pc >= (unsigned int)$kgm_fkmodmin) 3457 showkmodaddr $pc 3458 else 3459 output/a $pc 3460 end 3461end 3462 3463define mbuf_walkpkt 3464 set $mp = (struct mbuf *)$arg0 3465 set $cnt = 1 3466 set $tot = 0 3467 while $mp 3468 printf "%4d: 0x%08x [len %4d, type %2d, ", $cnt, $mp, \ 3469 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type 3470 if mclaudit != 0 3471 mbuf_buf2mca $mp 3472 printf ", " 3473 end 3474 set $tot = $tot + $mp->m_hdr.mh_len 3475 printf "total %d]\n", $tot 3476 set $mp = $mp->m_hdr.mh_nextpkt 3477 set $cnt = $cnt + 1 3478 end 3479end 3480 3481document mbuf_walkpkt 3482Syntax: (gdb) mbuf_walkpkt <addr> 3483| Given an mbuf address, walk its m_nextpkt pointer 3484end 3485 3486define mbuf_walk 3487 set $mp = (struct mbuf *)$arg0 3488 set $cnt = 1 3489 set $tot = 0 3490 while $mp 3491 printf "%4d: 0x%08x [len %4d, type %2d, ", $cnt, $mp, \ 3492 $mp->m_hdr.mh_len, $mp->m_hdr.mh_type 3493 if mclaudit != 0 3494 mbuf_buf2mca $mp 3495 printf ", " 3496 end 3497 set $tot = $tot + $mp->m_hdr.mh_len 3498 printf "total %d]\n", $tot 3499 set $mp = $mp->m_hdr.mh_next 3500 set $cnt = $cnt + 1 3501 end 3502end 3503 3504document mbuf_walk 3505Syntax: (gdb) mbuf_walk <addr> 3506| Given an mbuf address, walk its m_next pointer 3507end 3508 3509define mbuf_buf2slab 3510 set $addr = $arg0 3511 set $gix = ((char *)$addr - (char *)mbutl) >> 20 3512 set $ix = ((char *)$addr - (char *)mbutl) >> 11 3513 set $slab = &slabstbl[$gix].slg_slab[$ix] 3514 printf "0x%08x", $slab 3515end 3516 3517document mbuf_buf2slab 3518| Given an mbuf object, find its corresponding slab address. 3519end 3520 3521define mbuf_buf2mca 3522 set $addr = $arg0 3523 set $ix = ((char *)$addr - (char *)mbutl) >> 11 3524 set $clbase = ((union mcluster *)(mbutl + $ix)) 3525 set $mclidx = (((char *)$addr - (char *)$clbase) >> 8) 3526 set $mca = mclaudit[$ix].cl_audit[$mclidx] 3527 printf "mca: 0x%08x", $mca 3528end 3529 3530document mbuf_buf2mca 3531Syntax: (gdb) mbuf_buf2mca <addr> 3532| Given an mbuf object, find its buffer audit structure address. 3533| This requires mbuf buffer auditing to be turned on, by setting 3534| the appropriate flags to the "mbuf_debug" boot-args parameter. 3535end 3536 3537define mbuf_showmca 3538 set language c 3539 set $mca = (mcache_audit_t *)$arg0 3540 set $cp = (mcache_t *)$mca->mca_cache 3541 printf "object type:\t\t" 3542 mbuf_mca_ctype $mca 1 3543 printf "\ncontrolling mcache:\t%p (%s)\n", $mca->mca_cache, $cp->mc_name 3544 if $mca->mca_uflags & $MB_SCVALID 3545 set $ix = ((char *)$mca->mca_addr - (char *)mbutl) >> 11 3546 set $clbase = ((union mcluster *)(mbutl + $ix)) 3547 set $mclidx = (((char *)$mca->mca_addr - (char *)$clbase) >> 8) 3548 printf "mbuf obj:\t\t%p\n", $mca->mca_addr 3549 printf "mbuf index:\t\t%d (out of 8) in cluster base %p\n", \ 3550 $mclidx + 1, $clbase 3551 if $mca->mca_uptr != 0 3552 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr 3553 printf "paired cluster obj:\t%p (mca %p)\n", \ 3554 $peer_mca->mca_addr, $peer_mca 3555 end 3556 printf "saved contents:\t\t%p (%d bytes)\n", \ 3557 $mca->mca_contents, $mca->mca_contents_size 3558 else 3559 printf "cluster obj:\t\t%p\n", $mca->mca_addr 3560 if $mca->mca_uptr != 0 3561 set $peer_mca = (mcache_audit_t *)$mca->mca_uptr 3562 printf "paired mbuf obj:\t%p (mca %p)\n", \ 3563 $peer_mca->mca_addr, $peer_mca 3564 end 3565 end 3566 printf "recent transaction for this buffer (thread %p):\n", \ 3567 $mca->mca_thread 3568 set $cnt = 0 3569 while $cnt < $mca->mca_depth 3570 set $pc = $mca->mca_stack[$cnt] 3571 printf "%4d: ", $cnt + 1 3572 pcprint $pc 3573 printf "\n" 3574 set $cnt = $cnt + 1 3575 end 3576 if $mca->mca_pdepth > 0 3577 printf "previous transaction for this buffer (thread %p):\n", \ 3578 $mca->mca_pthread 3579 end 3580 set $cnt = 0 3581 while $cnt < $mca->mca_pdepth 3582 set $pc = $mca->mca_pstack[$cnt] 3583 printf "%4d: ", $cnt + 1 3584 pcprint $pc 3585 printf "\n" 3586 set $cnt = $cnt + 1 3587 end 3588 set language auto 3589end 3590 3591document mbuf_showmca 3592Syntax: (gdb) mbuf_showmca <addr> 3593| Given an mbuf/cluster buffer audit structure address, print the audit 3594| records including the stack trace of the last buffer transaction. 3595end 3596 3597set $MCF_NOCPUCACHE = 0x10 3598 3599define mcache_stat 3600 set $head = (mcache_t *)mcache_head 3601 set $mc = $head 3602 printf "cache cache cache buf buf backing (# of retries) bufs\n" 3603 printf "name state addr size align zone wait nowait failed incache\n" 3604 printf "------------------------- -------- ---------- ------ ----- ---------- -------------------------- --------\n" 3605 while $mc != 0 3606 set $bktsize = $mc->mc_cpu.cc_bktsize 3607 printf "%-25s ", $mc->mc_name 3608 if ($mc->mc_flags & $MCF_NOCPUCACHE) 3609 printf "disabled" 3610 else 3611 if $mc->mc_purge_cnt > 0 3612 printf " purging" 3613 else 3614 if $bktsize == 0 3615 printf " offline" 3616 else 3617 printf " online" 3618 end 3619 end 3620 end 3621 printf " 0x%08x %6d %5d ",$mc, \ 3622 $mc->mc_bufsize, $mc->mc_align 3623 if $mc->mc_slab_zone != 0 3624 printf "0x%08x", $mc->mc_slab_zone 3625 else 3626 printf " custom" 3627 end 3628 set $tot = 0 3629 set $tot += $mc->mc_full.bl_total * $bktsize 3630 set $ccp = (mcache_cpu_t *)$mc->mc_cpu 3631 set $n = 0 3632 while $n < ncpu 3633 if $ccp->cc_objs > 0 3634 set $tot += $ccp->cc_objs 3635 end 3636 if $ccp->cc_pobjs > 0 3637 set $tot += $ccp->cc_pobjs 3638 end 3639 set $n += 1 3640 set $ccp += 1 3641 end 3642 printf " %8d %8d %8d %8d", $mc->mc_wretry_cnt, \ 3643 $mc->mc_nwretry_cnt, $mc->mc_nwfail_cnt, $tot 3644 printf "\n" 3645 set $mc = (mcache_t *)$mc->mc_list.le_next 3646 end 3647end 3648 3649document mcache_stat 3650Syntax: (gdb) mcache_stat 3651| Print all mcaches in the system. 3652end 3653 3654define mcache_showzone 3655 set $mc = (mcache_t *)$arg0 3656 if $mc->mc_slab_zone != 0 3657 printf "%p", $mc->mc_slab_zone 3658 else 3659 printf " custom" 3660end 3661 3662document mcache_showzone 3663Syntax: (gdb) mcache_showzone <mcache_addr> 3664| Print the type of backend (custom or zone) of a mcache. 3665end 3666 3667define mcache_walkobj 3668 set $p = (mcache_obj_t *)$arg0 3669 set $cnt = 1 3670 set $tot = 0 3671 while $p 3672 printf "%4d: 0x%08x\n", $cnt, $p, 3673 set $p = $p->obj_next 3674 set $cnt = $cnt + 1 3675 end 3676end 3677 3678document mcache_walkobj 3679Syntax: (gdb) mcache_walkobj <addr> 3680| Given a mcache object address, walk its obj_next pointer 3681end 3682 3683define mcache_showcache 3684 set $cp = (mcache_t *)$arg0 3685 set $ccp = (mcache_cpu_t *)$cp->mc_cpu 3686 set $bktsize = $cp->mc_cpu.cc_bktsize 3687 set $cnt = 0 3688 set $tot = 0 3689 printf "Showing cache '%s':\n\n", $cp->mc_name 3690 printf " CPU cc_objs cc_pobjs total\n" 3691 printf "---- -------- -------- --------\n" 3692 while $cnt < ncpu 3693 set $objs = $ccp->cc_objs 3694 if $objs <= 0 3695 set $objs = 0 3696 end 3697 set $pobjs = $ccp->cc_pobjs 3698 if $pobjs <= 0 3699 set $pobjs = 0 3700 end 3701 set $tot_cpu = $objs + $pobjs 3702 set $tot += $tot_cpu 3703 printf "%4d %8d %8d %8d\n", $cnt, $objs, $pobjs, $tot_cpu 3704 set $ccp += 1 3705 set $cnt += 1 3706 end 3707 printf " ========\n" 3708 printf " %8d\n", $tot 3709 printf "\n" 3710 set $tot += $cp->mc_full.bl_total * $bktsize 3711 printf "Total # of full buckets (%d objs/bkt):\t%-8d\n", \ 3712 $bktsize, $cp->mc_full.bl_total 3713 printf "Total # of objects cached:\t\t%-8d\n", $tot 3714end 3715 3716document mcache_showcache 3717| Display the number of objects in the cache 3718end 3719 3720set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t) 3721 3722define mbuf_slabstbl 3723 set $x = 0 3724 3725 printf "slot addr slabs range\n" 3726 printf "---- ---------- -----------------------\n" 3727 while $x < maxslabgrp 3728 set $slg = slabstbl[$x] 3729 printf "%3d: ", $x 3730 if $slg == 0 3731 printf "-\n" 3732 else 3733 printf "%p [%p-%p]\n", $slg, &$slg->slg_slab[0], \ 3734 &$slg->slg_slab[$NSLABSPMB-1] 3735 end 3736 set $x += 1 3737 end 3738end 3739 3740document mbuf_slabstbl 3741| Display the mbuf slabs table 3742end 3743 3744set $SLF_MAPPED=0x0001 3745set $SLF_PARTIAL=0x0002 3746set $SLF_DETACHED=0x0004 3747 3748define mbuf_slabs 3749 set $slg = (mcl_slabg_t *)$arg0 3750 set $x = 0 3751 3752 printf "slot addr next base C R N size flags\n" 3753 printf "---- ---------- ---------- ---------- -- -- -- ------ -----\n" 3754 while $x < $NSLABSPMB 3755 set $sl = &$slg->slg_slab[$x] 3756 printf "%3d: 0x%08x 0x%08x 0x%08x %2d %2d %2d %6d 0x%04x ", \ 3757 $x + 1, $sl, $sl->sl_next, $sl->sl_base, $sl->sl_class, \ 3758 $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \ 3759 $sl->sl_flags 3760 if $sl->sl_flags != 0 3761 printf "<" 3762 if $sl->sl_flags & $SLF_MAPPED 3763 printf "mapped" 3764 end 3765 if $sl->sl_flags & $SLF_PARTIAL 3766 printf ",partial" 3767 end 3768 if $sl->sl_flags & $SLF_DETACHED 3769 printf ",detached" 3770 end 3771 printf ">" 3772 end 3773 printf "\n" 3774 set $x += 1 3775 end 3776end 3777 3778document mbuf_slabs 3779| Display all mbuf slabs in the group 3780end 3781 3782define mbuf_stat 3783 set $x = 0 3784 3785 printf "class total cached uncached inuse failed waiter notified purge\n" 3786 printf "name objs objs objs / slabs objs alloc count count count count\n" 3787 printf "---------------- -------- -------- ------------------- -------- ---------------- -------- -------- --------\n" 3788 while $x < (sizeof(mbuf_table) / sizeof(mbuf_table[0])) 3789 set $mbt = mbuf_table[$x] 3790 set $mcs = (mb_class_stat_t *)mbuf_table[$x].mtbl_stats 3791 set $tot = 0 3792 set $mc = $mbt->mtbl_cache 3793 set $bktsize = $mc->mc_cpu.cc_bktsize 3794 set $tot += $mc->mc_full.bl_total * $bktsize 3795 set $ccp = (mcache_cpu_t *)$mc->mc_cpu 3796 set $n = 0 3797 while $n < ncpu 3798 if $ccp->cc_objs > 0 3799 set $tot += $ccp->cc_objs 3800 end 3801 if $ccp->cc_pobjs > 0 3802 set $tot += $ccp->cc_pobjs 3803 end 3804 set $n += 1 3805 set $ccp += 1 3806 end 3807 3808 printf "%-16s %8d %8d %8d / %-8d %8d %16llu %8d %8llu %8llu", \ 3809 $mcs->mbcl_cname, $mcs->mbcl_total, $tot, \ 3810 $mcs->mbcl_infree, $mcs->mbcl_slab_cnt, \ 3811 ($mcs->mbcl_total - $tot - $mcs->mbcl_infree), \ 3812 $mcs->mbcl_fail_cnt, $mc->mc_waiter_cnt, \ 3813 $mcs->mbcl_notified, $mcs->mbcl_purge_cnt 3814 printf "\n" 3815 set $x += 1 3816 end 3817end 3818 3819document mbuf_stat 3820| Print extended mbuf allocator statistics. 3821end 3822 3823set $MB_INUSE = 0x1 3824set $MB_COMP_INUSE = 0x2 3825set $MB_SCVALID = 0x4 3826 3827set $MCLBYTES = 2048 3828set $MSIZE = 256 3829set $NBPG = 4096 3830set $M16KCLBYTES = 16384 3831 3832define mbuf_mca_ctype 3833 set $mca = (mcache_audit_t *)$arg0 3834 set $vopt = $arg1 3835 set $cp = $mca->mca_cache 3836 set $class = (unsigned int)$cp->mc_private 3837 set $csize = mbuf_table[$class].mtbl_stats->mbcl_size 3838 set $done = 0 3839 if $csize == $MSIZE 3840 if $vopt 3841 printf "M (mbuf) " 3842 else 3843 printf "M " 3844 end 3845 set $done = 1 3846 end 3847 if !$done && $csize == $MCLBYTES 3848 if $vopt 3849 printf "CL (2K cluster) " 3850 else 3851 printf "CL " 3852 end 3853 set $done = 1 3854 end 3855 if !$done && $csize == $NBPG 3856 if $vopt 3857 printf "BCL (4K cluster) " 3858 else 3859 printf "BCL " 3860 end 3861 set $done = 1 3862 end 3863 if !$done && $csize == $M16KCLBYTES 3864 if $vopt 3865 printf "JCL (16K cluster) " 3866 else 3867 printf "JCL " 3868 end 3869 set $done = 1 3870 end 3871 if !$done && $csize == ($MSIZE+$MCLBYTES) 3872 if $mca->mca_uflags & $MB_SCVALID 3873 if $mca->mca_uptr 3874 printf "M+CL " 3875 if $vopt 3876 printf "(paired mbuf, 2K cluster)" 3877 end 3878 else 3879 printf "M-CL " 3880 if $vopt 3881 printf "(unpaired mbuf, 2K cluster) " 3882 end 3883 end 3884 else 3885 if $mca->mca_uptr 3886 printf "CL+M " 3887 if $vopt 3888 printf "(paired 2K cluster, mbuf) " 3889 end 3890 else 3891 printf "CL-M " 3892 if $vopt 3893 printf "(paired 2K cluster, mbuf) " 3894 end 3895 end 3896 end 3897 set $done = 1 3898 end 3899 if !$done && $csize == ($MSIZE+$NBPG) 3900 if $mca->mca_uflags & $MB_SCVALID 3901 if $mca->mca_uptr 3902 printf "M+BCL " 3903 if $vopt 3904 printf "(paired mbuf, 4K cluster) " 3905 end 3906 else 3907 printf "M-BCL " 3908 if $vopt 3909 printf "(unpaired mbuf, 4K cluster) " 3910 end 3911 end 3912 else 3913 if $mca->mca_uptr 3914 printf "BCL+M " 3915 if $vopt 3916 printf "(paired 4K cluster, mbuf) " 3917 end 3918 else 3919 printf "BCL-M " 3920 if $vopt 3921 printf "(unpaired 4K cluster, mbuf) " 3922 end 3923 end 3924 end 3925 set $done = 1 3926 end 3927 if !$done && $csize == ($MSIZE+$M16KCLBYTES) 3928 if $mca->mca_uflags & $MB_SCVALID 3929 if $mca->mca_uptr 3930 printf "M+JCL " 3931 if $vopt 3932 printf "(paired mbuf, 16K cluster) " 3933 end 3934 else 3935 printf "M-JCL " 3936 if $vopt 3937 printf "(unpaired mbuf, 16K cluster) " 3938 end 3939 end 3940 else 3941 if $mca->mca_uptr 3942 printf "JCL+M " 3943 if $vopt 3944 printf "(paired 16K cluster, mbuf) " 3945 end 3946 else 3947 printf "JCL-M " 3948 if $vopt 3949 printf "(unpaired 16K cluster, mbuf) " 3950 end 3951 end 3952 end 3953 set $done = 1 3954 end 3955 if !$done 3956 printf "unknown: %s ", $cp->mc_name 3957 end 3958end 3959 3960document mbuf_mca_ctype 3961| This is a helper macro for mbuf_show{active,inactive,all} that prints 3962| out the mbuf object type represented by a given mcache audit structure. 3963end 3964 3965define mbuf_showactive 3966 mbuf_walkallslabs 1 0 3967end 3968 3969document mbuf_showactive 3970Syntax: (gdb) mbuf_showactive 3971| Walk the mbuf objects pool and print only the active ones; this 3972| requires mbuf debugging to be turned on, by setting the appropriate flags 3973| to the "mbuf_debug" boot-args parameter. Active objects are those that 3974| are outstanding (have not returned to the mbuf slab layer) and in use 3975| by the client (have not been freed). 3976end 3977 3978define mbuf_showinactive 3979 mbuf_walkallslabs 0 1 3980end 3981 3982document mbuf_showinactive 3983Syntax: (gdb) mbuf_showinactive 3984| Walk the mbuf objects pool and print only the inactive ones; this 3985| requires mbuf debugging to be turned on, by setting the appropriate flags 3986| to the "mbuf_debug" boot-args parameter. Inactive objects are those that 3987| are outstanding (have not returned to the mbuf slab layer) but have been 3988| freed by the client, i.e. they still reside in the mcache layer ready to 3989| be used for subsequent allocation requests. 3990end 3991 3992define mbuf_showall 3993 mbuf_walkallslabs 1 1 3994end 3995 3996document mbuf_showall 3997Syntax: (gdb) mbuf_showall 3998| Walk the mbuf objects pool and print them all; this requires 3999| mbuf debugging to be turned on, by setting the appropriate flags to the 4000| "mbuf_debug" boot-args parameter. 4001end 4002 4003define mbuf_mcaobjs 4004end 4005 4006define mbuf_walkallslabs 4007 set $show_a = $arg0 4008 set $show_f = $arg1 4009 set $x = 0 4010 set $total = 0 4011 set $total_a = 0 4012 set $total_f = 0 4013 4014 printf "(" 4015 if $show_a && !$show_f 4016 printf "Searching only for active " 4017 end 4018 if !$show_a && $show_f 4019 printf "Searching only for inactive " 4020 end 4021 if $show_a && $show_f 4022 printf "Displaying all " 4023 end 4024 printf "objects; this may take a while ...)\n\n" 4025 4026 printf " slab mca obj allocation\n" 4027 printf "slot idx address address address type state\n" 4028 printf "---- ---- ---------- ---------- ---------- ----- -----------\n" 4029 4030 while $x < slabgrp 4031 set $slg = slabstbl[$x] 4032 set $y = 0 4033 set $stop = 0 4034 while $y < $NSLABSPMB && $stop == 0 4035 set $sl = &$slg->slg_slab[$y] 4036 set $base = (char *)$sl->sl_base 4037 set $ix = ($base - (char *)mbutl) >> 11 4038 set $clbase = ((union mcluster *)(mbutl + $ix)) 4039 set $mclidx = ($base - (char *)$clbase) >> 8 4040 set $mca = mclaudit[$ix].cl_audit[$mclidx] 4041 set $first = 1 4042 4043 while $mca != 0 && $mca->mca_addr != 0 4044 set $printmca = 0 4045 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE) 4046 set $total_a = $total_a + 1 4047 set $printmca = $show_a 4048 else 4049 set $total_f = $total_f + 1 4050 set $printmca = $show_f 4051 end 4052 4053 if $printmca != 0 4054 if $first == 1 4055 printf "%4d %4d 0x%08x ", $x, $y, $sl 4056 else 4057 printf " " 4058 end 4059 4060 printf "0x%08x 0x%08x ", $mca, $mca->mca_addr 4061 mbuf_mca_ctype $mca 0 4062 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE) 4063 printf "active " 4064 else 4065 printf " freed " 4066 end 4067 if $first == 1 4068 set $first = 0 4069 end 4070 printf "\n" 4071 set $total = $total + 1 4072 end 4073 set $mca = $mca->mca_next 4074 end 4075 set $y += 1 4076 if $slg->slg_slab[$y].sl_base == 0 4077 set $stop = 1 4078 end 4079 end 4080 set $x += 1 4081 end 4082 if $total && $show_a && $show_f 4083 printf "\ntotal objects:\t%d\n", $total 4084 printf "active/unfreed:\t%d\n", $total_a 4085 printf "freed/in_cache:\t%d\n", $total_f 4086 end 4087end 4088 4089document mbuf_walkallslabs 4090| Walk the mbuf objects pool; this requires mbuf debugging to be 4091| turned on, by setting the appropriate flags to the "mbuf_debug" boot-args 4092| parameter. This is a backend routine for mbuf_show{active,inactive,all}. 4093end 4094 4095define rtentry_trash 4096 set $rtd = (struct rtentry_dbg *)rttrash_head.tqh_first 4097 set $cnt = 0 4098 while $rtd != 0 4099 if $cnt == 0 4100 printf " rtentry_dbg ref flags\n" 4101 printf " ------------ --- ----------\n" 4102 end 4103 printf "%4d: %p %3d 0x%08x\n", $cnt + 1, $rtd, \ 4104 $rtd->rtd_refhold_cnt - $rtd->rtd_refrele_cnt, \ 4105 $rtd->rtd_entry.rt_flags 4106 set $rtd = $rtd->rtd_trash_link.tqe_next 4107 set $cnt = $cnt + 1 4108 end 4109end 4110 4111document rtentry_trash 4112Syntax: (gdb) rtentry_trash 4113| Walk the list of trash route entries; this requires route entry 4114| debugging to be turned on, by setting the appropriate flags to the 4115| "rte_debug" boot-args parameter. 4116end 4117 4118set $RTD_TRSTACK_SIZE = 8 4119set $RTD_REFHIST_SIZE = 4 4120 4121define rtentry_showdbg 4122 set $rtd = (struct rtentry_dbg *)$arg0 4123 set $cnt = 0 4124 4125 printf "Total holds: %d\n", $rtd->rtd_refhold_cnt 4126 printf "Next hold slot: %d\n", $rtd->rtd_refhold_next 4127 printf "Total releases: %d\n", $rtd->rtd_refrele_cnt 4128 printf "Next release slot: %d\n", $rtd->rtd_refrele_next 4129 4130 set $ix = 0 4131 while $ix < $RTD_TRSTACK_SIZE 4132 set $pc = $rtd->rtd_alloc_stk_pc[$ix] 4133 if $pc != 0 4134 if $ix == 0 4135 printf "\nAlloc (thread %p):\n", \ 4136 $rtd->rtd_alloc_thread 4137 end 4138 printf "%4d: ", $ix + 1 4139 pcprint $pc 4140 printf "\n" 4141 end 4142 set $ix = $ix + 1 4143 end 4144 set $ix = 0 4145 while $ix < $RTD_TRSTACK_SIZE 4146 set $pc = $rtd->rtd_free_stk_pc[$ix] 4147 if $pc != 0 4148 if $ix == 0 4149 printf "\nFree: (thread %p)\n", \ 4150 $rtd->rtd_free_thread 4151 end 4152 printf "%4d: ", $ix + 1 4153 pcprint $pc 4154 printf "\n" 4155 end 4156 set $ix = $ix + 1 4157 end 4158 while $cnt < $RTD_REFHIST_SIZE 4159 set $ix = 0 4160 while $ix < $RTD_TRSTACK_SIZE 4161 set $pc = $rtd->rtd_refhold[$cnt].pc[$ix] 4162 if $pc != 0 4163 if $ix == 0 4164 printf "\nHold [%d] (thread %p):\n", \ 4165 $cnt, $rtd->rtd_refhold[$cnt].th 4166 end 4167 printf "%4d: ", $ix + 1 4168 pcprint $pc 4169 printf "\n" 4170 end 4171 set $ix = $ix + 1 4172 end 4173 set $cnt = $cnt + 1 4174 end 4175 set $cnt = 0 4176 while $cnt < $RTD_REFHIST_SIZE 4177 set $ix = 0 4178 while $ix < $RTD_TRSTACK_SIZE 4179 set $pc = $rtd->rtd_refrele[$cnt].pc[$ix] 4180 if $pc != 0 4181 if $ix == 0 4182 printf "\nRelease [%d] (thread %p):\n",\ 4183 $cnt, $rtd->rtd_refrele[$cnt].th 4184 end 4185 printf "%4d: ", $ix + 1 4186 pcprint $pc 4187 printf "\n" 4188 end 4189 set $ix = $ix + 1 4190 end 4191 set $cnt = $cnt + 1 4192 end 4193end 4194 4195document rtentry_showdbg 4196Syntax: (gdb) rtentry_showdbg <addr> 4197| Given a route entry structure address, print the debug information 4198| related to it. This requires route entry debugging to be turned 4199| on, by setting the appropriate flags to the "rte_debug" boot-args 4200| parameter. 4201end 4202 4203# 4204# print all OSMalloc stats 4205 4206define ostag_print 4207set $kgm_tagp = (OSMallocTag)$arg0 4208printf "0x%08x: ", $kgm_tagp 4209printf "%8d ",$kgm_tagp->OSMT_refcnt 4210printf "%8x ",$kgm_tagp->OSMT_state 4211printf "%8x ",$kgm_tagp->OSMT_attr 4212printf "%s ",$kgm_tagp->OSMT_name 4213printf "\n" 4214end 4215 4216 4217define showosmalloc 4218printf "TAG COUNT STATE ATTR NAME\n" 4219set $kgm_tagheadp = (OSMallocTag)&OSMalloc_tag_list 4220 set $kgm_tagptr = (OSMallocTag )($kgm_tagheadp->OSMT_link.next) 4221 while $kgm_tagptr != $kgm_tagheadp 4222 ostag_print $kgm_tagptr 4223 set $kgm_tagptr = (OSMallocTag)$kgm_tagptr->OSMT_link.next 4224 end 4225 printf "\n" 4226end 4227document showosmalloc 4228Syntax: (gdb) showosmalloc 4229| Print the outstanding allocation count by OSMallocTags. 4230end 4231 4232 4233define systemlog 4234 if msgbufp->msg_bufc[msgbufp->msg_bufx] == 0 4235 # The buffer hasn't wrapped, so take the easy (and fast!) path 4236 printf "%s", msgbufp->msg_bufc 4237 else 4238 set $kgm_msgbuf = *msgbufp 4239 set $kgm_syslog_bufsize = $kgm_msgbuf.msg_size 4240 set $kgm_syslog_bufend = $kgm_msgbuf.msg_bufx 4241 if $kgm_syslog_bufend >= $kgm_syslog_bufsize 4242 set $kgm_syslog_bufend = 0 4243 end 4244 4245 # print older messages from msg_bufx to end of buffer 4246 set $kgm_i = $kgm_syslog_bufend 4247 while $kgm_i < $kgm_syslog_bufsize 4248 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i] 4249 if $kgm_syslog_char == 0 4250 # break out of loop 4251 set $kgm_i = $kgm_syslog_bufsize 4252 else 4253 printf "%c", $kgm_syslog_char 4254 end 4255 set $kgm_i = $kgm_i + 1 4256 end 4257 4258 # print newer messages from start of buffer to msg_bufx 4259 set $kgm_i = 0 4260 while $kgm_i < $kgm_syslog_bufend 4261 set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i] 4262 printf "%c", $kgm_syslog_char 4263 set $kgm_i = $kgm_i + 1 4264 end 4265 end 4266 printf "\n" 4267end 4268document systemlog 4269| Syntax: systemlog 4270| Display the kernel's printf ring buffer 4271end 4272 4273define printvnodepathint_recur 4274 if $arg0 != 0 4275 if ($arg0->v_flag & 0x000001) && ($arg0->v_mount != 0) 4276 if $arg0->v_mount->mnt_vnodecovered != 0 4277 printvnodepathint_recur $arg0->v_mount->mnt_vnodecovered $arg0->v_mount->mnt_vnodecovered->v_name 4278 end 4279 else 4280 printvnodepathint_recur $arg0->v_parent $arg0->v_parent->v_name 4281 printf "/%s", $arg1 4282 end 4283 end 4284end 4285 4286# 4287# Show the locks held on a vnode by range, type, and holder. 4288# 4289define showvnodelocks 4290 if ($argc == 1) 4291 _showvnodelockheader 4292 _showvnodelocks $arg0 4293 else 4294 printf "| Usage:\n|\n" 4295 help showvnodelocks 4296 end 4297end 4298document showvnodelocks 4299| Given a vnodet pointer, display the list of advisory record locks for the 4300| referenced pvnode. 4301| The following is the syntax: 4302| (gdb) showvnodelocks <vnode_t> 4303end 4304 4305define _showvnodelockheader 4306 printf "* type W held by lock type start end\n" 4307 printf "- ----- - ------------- --------- ------------------ ------------------\n" 4308end 4309 4310# 4311# Macro to display a single lock; used to display both held locks and 4312# blocked locks 4313# 4314define _showvnodelock 4315 set $kgm_svl_lock = ((struct lockf *)$arg0) 4316 4317 # decode flags 4318 set $kgm_svl_flags = $kgm_svl_lock->lf_flags 4319 set $kgm_svl_type = $kgm_svl_lock->lf_type 4320 if ($kgm_svl_flags & 0x20) 4321 printf "flock" 4322 end 4323 if ($kgm_svl_flags & 0x40) 4324 printf "posix" 4325 end 4326 if ($kgm_svl_flags & 0x80) 4327 printf "prov " 4328 end 4329 if ($kgm_svl_flags & 0x10) 4330 printf " W " 4331 else 4332 printf " . " 4333 end 4334 4335 # POSIX file vs. advisory range locks 4336 if ($kgm_svl_flags & 0x40) 4337 set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id 4338 printf "PID %8d ", $kgm_svl_proc->p_pid 4339 else 4340 printf "ID 0x%08x ", $kgm_svl_lock->lf_id 4341 end 4342 4343 # lock type 4344 if ($kgm_svl_type == 1) 4345 printf "shared " 4346 else 4347 if ($kgm_svl_type == 3) 4348 printf "exclusive " 4349 else 4350 if ($kgm_svl_type == 2) 4351 printf "unlock " 4352 else 4353 printf "unknown " 4354 end 4355 end 4356 end 4357 4358 # start and stop 4359 printf "0x%016x..", $kgm_svl_lock->lf_start 4360 printf "0x%016x ", $kgm_svl_lock->lf_end 4361 printf "\n" 4362end 4363 4364# Body of showvnodelocks, not including header 4365define _showvnodelocks 4366 set $kgm_svl_vnode = ((vnode_t)$arg0) 4367 set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf 4368 while ($kgm_svl_lockiter != 0) 4369 # locks that are held 4370 printf "H " 4371 _showvnodelock $kgm_svl_lockiter 4372 4373 # and any locks blocked by them 4374 set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first 4375 while ($kgm_svl_blocker != 0) 4376 printf "> " 4377 _showvnodelock $kgm_svl_blocker 4378 set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next 4379 end 4380 4381 # and on to the next one... 4382 set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next 4383 end 4384end 4385 4386define showvnodepath 4387 set $vp = (struct vnode *)$arg0 4388 if $vp != 0 4389 if ($vp->v_flag & 0x000001) && ($vp->v_mount != 0) && ($vp->v_mount->mnt_flag & 0x00004000) 4390 printf "/" 4391 else 4392 printvnodepathint_recur $vp $vp->v_name 4393 end 4394 end 4395 printf "\n" 4396end 4397 4398document showvnodepath 4399Syntax: (gdb) showvnodepath <vnode> 4400| Prints the path for a vnode 4401end 4402 4403define printcolonhex 4404 if ($argc == 2) 4405 set $addr = $arg0 4406 set $count = $arg1 4407 set $li = 0 4408 while ($li < $count) 4409 if ($li == 0) 4410 printf "%02x", (u_char)$addr[$li] 4411 end 4412 if ($li != 0) 4413 printf ":%02x", (u_char)$addr[$li] 4414 end 4415 set $li = $li + 1 4416 end 4417 end 4418end 4419 4420define showsockaddr_dl 4421 set $sdl = (struct sockaddr_dl *)$arg0 4422 printf "LINK " 4423 if ($sdl == 0) 4424 printf "(null)" 4425 else 4426 set $addr = $sdl->sdl_data + $sdl->sdl_nlen 4427 set $count = $sdl->sdl_alen 4428 printcolonhex $addr $count 4429 end 4430end 4431 4432define showsockaddr_unspec 4433 set $sockaddr = (struct sockaddr *)$arg0 4434 set $addr = $sockaddr->sa_data 4435 set $count = $sockaddr->sa_len - 2 4436 printf "UNSP " 4437 printcolonhex $addr $count 4438end 4439 4440define showsockaddr_at 4441 set $sockaddr = (struct sockaddr *)$arg0 4442 set $addr = $sockaddr->sa_data 4443 set $count = $sockaddr->sa_len - 2 4444 printf "ATLK " 4445 printcolonhex $addr $count 4446end 4447 4448define showsockaddr_in 4449 set $sin = (struct sockaddr_in *)$arg0 4450 set $sa_bytes = (unsigned char *)&($sin->sin_addr) 4451 printf "IPV4 %d.%d.%d.%d", $sa_bytes[0], $sa_bytes[1], $sa_bytes[2], $sa_bytes[3] 4452end 4453 4454define showsockaddr_in6 4455 set $sin6 = (struct sockaddr_in6 *)$arg0 4456 set $sa_bytes = $sin6->sin6_addr.__u6_addr.__u6_addr8 4457 printf "IPV6 %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", $sa_bytes[0], $sa_bytes[1], $sa_bytes[2], $sa_bytes[3], $sa_bytes[4], $sa_bytes[5], $sa_bytes[6], $sa_bytes[7], $sa_bytes[8], $sa_bytes[9], $sa_bytes[10], $sa_bytes[11], $sa_bytes[12], $sa_bytes[13], $sa_bytes[14], $sa_bytes[15] 4458end 4459 4460define showifmultiaddrs 4461 set $ifp = (struct ifnet *)$arg0 4462 set $if_multi = (struct ifmultiaddr *)$ifp->if_multiaddrs->lh_first 4463 set $mymulti = $if_multi 4464 set $myi = 0 4465 while ($mymulti != 0) 4466 printf "%2d. ", $myi 4467 set $sa_family = $mymulti->ifma_addr.sa_family 4468 if ($sa_family == 2) 4469 if ($mymulti->ifma_ll != 0) 4470 showsockaddr_dl $mymulti->ifma_ll->ifma_addr 4471 printf " " 4472 end 4473 showsockaddr_in $mymulti->ifma_addr 4474 end 4475 if ($sa_family == 30) 4476 if ($mymulti->ifma_ll != 0) 4477 showsockaddr_dl $mymulti->ifma_ll->ifma_addr 4478 printf " " 4479 end 4480 showsockaddr_in6 $mymulti->ifma_addr 4481 end 4482 if ($sa_family == 18) 4483 showsockaddr_dl $mymulti->ifma_addr 4484 end 4485 if ($sa_family == 0) 4486 showsockaddr_unspec $mymulti->ifma_addr 6 4487 end 4488 printf " [%d]", $mymulti->ifma_refcount 4489 printf "\n" 4490 set $mymulti = $mymulti->ifma_link.le_next 4491 set $myi = $myi + 1 4492 end 4493end 4494 4495document showifmultiaddrs 4496Syntax showifmultiaddrs <ifp> 4497| show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp 4498end 4499 4500define showsockaddr 4501 set $mysock = (struct sockaddr *)$arg0 4502 set $showsockaddr_handled = 0 4503 if ($mysock == 0) 4504 printf "(null)" 4505 else 4506 if ($mysock->sa_family == 0) 4507 showsockaddr_unspec $mysock 4508 set $showsockaddr_handled = 1 4509 end 4510 if ($mysock->sa_family == 2) 4511 showsockaddr_in $mysock 4512 set $showsockaddr_handled = 1 4513 end 4514 if ($mysock->sa_family == 30) 4515 showsockaddr_in6 $mysock 4516 set $showsockaddr_handled = 1 4517 end 4518 if ($mysock->sa_family == 18) 4519 showsockaddr_dl $mysock 4520 set $showsockaddr_handled = 1 4521 end 4522 if ($mysock->sa_family == 16) 4523 showsockaddr_at $mysock 4524 set $showsockaddr_handled = 1 4525 end 4526 if ($showsockaddr_handled == 0) 4527 printf "%d ", $mysock->sa_family 4528 set $addr = $mysock->sa_data 4529 set $count = $mysock->sa_len 4530 printcolonhex $addr $count 4531 end 4532 end 4533end 4534 4535define showifflags 4536 set $flags = (u_short)$arg0 4537 set $first = 1 4538 printf "<" 4539 if ($flags & 0x1) 4540 printf "UP" 4541 set $first = 0 4542 end 4543 if ($flags & 0x2) 4544 if ($first == 1) 4545 set $first = 0 4546 else 4547 printf "," 4548 end 4549 printf "BROADCAST" 4550 end 4551 if ($flags & 0x4) 4552 printf "DEBUG" 4553 end 4554 if ($flags & 0x8) 4555 if ($first == 1) 4556 set $first = 0 4557 else 4558 printf "," 4559 end 4560 printf "LOOPBACK" 4561 end 4562 if ($flags & 0x10) 4563 if ($first == 1) 4564 set $first = 0 4565 else 4566 printf "," 4567 end 4568 printf "POINTTOPOINT" 4569 end 4570# if ($flags & 0x20) 4571# if ($first == 1) 4572# set $first = 0 4573# else 4574# printf "," 4575# end 4576# printf "NOTRAILERS" 4577# end 4578 if ($flags & 0x40) 4579 if ($first == 1) 4580 set $first = 0 4581 else 4582 printf "," 4583 end 4584 printf "RUNNING" 4585 end 4586 if ($flags & 0x80) 4587 if ($first == 1) 4588 set $first = 0 4589 else 4590 printf "," 4591 end 4592 printf "NOARP" 4593 end 4594 if ($flags & 0x100) 4595 if ($first == 1) 4596 set $first = 0 4597 else 4598 printf "," 4599 end 4600 printf "PROMISC" 4601 end 4602 if ($flags & 0x200) 4603 if ($first == 1) 4604 set $first = 0 4605 else 4606 printf "," 4607 end 4608 printf "ALLMULTI" 4609 end 4610 if ($flags & 0x400) 4611 if ($first == 1) 4612 set $first = 0 4613 else 4614 printf "," 4615 end 4616 printf "OACTIVE" 4617 end 4618 if ($flags & 0x800) 4619 if ($first == 1) 4620 set $first = 0 4621 else 4622 printf "," 4623 end 4624 printf "SIMPLEX" 4625 end 4626 if ($flags & 0x1000) 4627 if ($first == 1) 4628 set $first = 0 4629 else 4630 printf "," 4631 end 4632 printf "LINK0" 4633 end 4634 if ($flags & 0x2000) 4635 if ($first == 1) 4636 set $first = 0 4637 else 4638 printf "," 4639 end 4640 printf "LINK1" 4641 end 4642 if ($flags & 0x4000) 4643 if ($first == 1) 4644 set $first = 0 4645 else 4646 printf "," 4647 end 4648 printf "LINK2-ALTPHYS" 4649 end 4650 if ($flags & 0x8000) 4651 if ($first == 1) 4652 set $first = 0 4653 else 4654 printf "," 4655 end 4656 printf "MULTICAST" 4657 end 4658 printf ">" 4659end 4660 4661define showifaddrs 4662 set $ifp = (struct ifnet *)$arg0 4663 set $myifaddr = (struct ifaddr *)$ifp->if_addrhead->tqh_first 4664 set $myi = 0 4665 while ($myifaddr != 0) 4666 printf "\t%d. ", $myi 4667 showsockaddr $myifaddr->ifa_addr 4668 printf " [%d]\n", $myifaddr->ifa_refcnt 4669 set $myifaddr = $myifaddr->ifa_link->tqe_next 4670 set $myi = $myi + 1 4671 end 4672end 4673 4674document showifaddrs 4675Syntax: showifaddrs <ifp> 4676| show the (struct ifnet).if_addrhead list of addresses for the given ifp 4677end 4678 4679define ifconfig 4680 set $ifconfig_all = 0 4681 if ($argc == 1) 4682 set $ifconfig_all = 1 4683 end 4684 set $ifp = (struct ifnet *)(ifnet->tqh_first) 4685 while ($ifp != 0) 4686 printf "%s%d: flags=%x", $ifp->if_name, $ifp->if_unit, (u_short)$ifp->if_flags 4687 showifflags $ifp->if_flags 4688 printf " mtu %d\n", $ifp->if_data.ifi_mtu 4689 printf "\t(struct ifnet *)0x%x\n", $ifp 4690 if ($ifconfig_all == 1) 4691 showifaddrs $ifp 4692 end 4693 set $ifp = $ifp->if_link->tqe_next 4694 end 4695end 4696document ifconfig 4697Syntax: (gdb) ifconfig 4698| display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection 4699end 4700 4701define showbpfdtab 4702 set $myi = 0 4703 while ($myi < bpf_dtab_size) 4704 if (bpf_dtab[$myi] != 0) 4705 printf "Address 0x%x, bd_next 0x%x\n", bpf_dtab[$myi], bpf_dtab[$myi]->bd_next 4706 print *bpf_dtab[$myi] 4707 end 4708 set $myi = $myi + 1 4709 end 4710end 4711 4712define showallvols 4713 printf "volume mnt_data mnt_devvp typename mountpoint\n" 4714 set $kgm_vol = (mount_t) mountlist.tqh_first 4715 while $kgm_vol 4716 printf "0x%08x ", $kgm_vol 4717 printf "0x%08x ", $kgm_vol->mnt_data 4718 printf "0x%08x ", $kgm_vol->mnt_devvp 4719 if ($kgm_vol->mnt_vtable->vfc_name[0] == 'h') && \ 4720 ($kgm_vol->mnt_vtable->vfc_name[1] == 'f') && \ 4721 ($kgm_vol->mnt_vtable->vfc_name[2] == 's') && \ 4722 ($kgm_vol->mnt_vtable->vfc_name[3] == '\0') 4723 set $kgm_hfsmount = \ 4724 (struct hfsmount *) $kgm_vol->mnt_data 4725 if $kgm_hfsmount->hfs_freezing_proc != 0 4726 printf "FROZEN hfs " 4727 else 4728 printf "hfs " 4729 end 4730 else 4731 printf "%-10s ", $kgm_vol->mnt_vtable->vfc_name 4732 end 4733 printf "%s\n", $kgm_vol->mnt_vfsstat.f_mntonname 4734 4735 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next 4736 end 4737end 4738 4739document showallvols 4740Syntax: (gdb) showallvols 4741| Display a summary of mounted volumes 4742end 4743 4744define showvnodeheader 4745 printf "vnode usecount iocount v_data vtype parent name\n" 4746end 4747 4748define showvnodeint 4749 set $kgm_vnode = (vnode_t) $arg0 4750 printf "0x%08x ", $kgm_vnode 4751 printf "%8d ", $kgm_vnode->v_usecount 4752 printf "%7d ", $kgm_vnode->v_iocount 4753# print information about clean/dirty blocks? 4754 printf "0x%08x ", $kgm_vnode->v_data 4755 4756 # print the vtype, using the enum tag 4757 set $kgm_vtype = $kgm_vnode->v_type 4758 if $kgm_vtype == VNON 4759 printf "VNON " 4760 end 4761 if $kgm_vtype == VREG 4762 printf "VREG " 4763 end 4764 if $kgm_vtype == VDIR 4765 printf "VDIR " 4766 end 4767 if $kgm_vtype == VBLK 4768 printf "VBLK " 4769 end 4770 if $kgm_vtype == VCHR 4771 printf "VCHR " 4772 end 4773 if $kgm_vtype == VLNK 4774 printf "VLNK " 4775 end 4776 if $kgm_vtype == VSOCK 4777 printf "VSOCK " 4778 end 4779 if $kgm_vtype == VFIFO 4780 printf "VFIFO " 4781 end 4782 if $kgm_vtype == VBAD 4783 printf "VBAD " 4784 end 4785 if ($kgm_vtype < VNON) || ($kgm_vtype > VBAD) 4786 printf "%5d ", $kgm_vtype 4787 end 4788 4789 printf "0x%08x ", $kgm_vnode->v_parent 4790 if $kgm_vnode->v_name != 0 4791 printf "%s\n", $kgm_vnode->v_name 4792 else 4793 printf "\n" 4794 end 4795end 4796 4797define showvnode 4798 showvnodeheader 4799 showvnodeint $arg0 4800end 4801 4802document showvnode 4803Syntax: (gdb) showvnode <vnode> 4804| Display info about one vnode 4805end 4806 4807define showvolvnodes 4808 showvnodeheader 4809 set $kgm_vol = (mount_t) $arg0 4810 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first 4811 while $kgm_vnode 4812 showvnodeint $kgm_vnode 4813 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next 4814 end 4815end 4816 4817document showvolvnodes 4818Syntax: (gdb) showvolvnodes <mouont_t> 4819| Display info about all vnodes of a given mount_t 4820end 4821 4822define showvolbusyvnodes 4823 showvnodeheader 4824 set $kgm_vol = (mount_t) $arg0 4825 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first 4826 while $kgm_vnode 4827 if $kgm_vnode->v_iocount != 0 4828 showvnodeint $kgm_vnode 4829 end 4830 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next 4831 end 4832end 4833 4834document showvolbusyvnodes 4835Syntax: (gdb) showvolbusyvnodes <mount_t> 4836| Display info about busy (iocount!=0) vnodes of a given mount_t 4837end 4838 4839define showallbusyvnodes 4840 showvnodeheader 4841 set $kgm_vol = (mount_t) mountlist.tqh_first 4842 while $kgm_vol 4843 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first 4844 while $kgm_vnode 4845 if $kgm_vnode->v_iocount != 0 4846 showvnodeint $kgm_vnode 4847 end 4848 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next 4849 end 4850 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next 4851 end 4852end 4853 4854document showallbusyvnodes 4855Syntax: (gdb) showallbusyvnodes <vnode> 4856| Display info about all busy (iocount!=0) vnodes 4857end 4858 4859define showallvnodes 4860 showvnodeheader 4861 set $kgm_vol = (mount_t) mountlist.tqh_first 4862 while $kgm_vol 4863 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first 4864 while $kgm_vnode 4865 showvnodeint $kgm_vnode 4866 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next 4867 end 4868 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next 4869 end 4870end 4871 4872document showallvnodes 4873Syntax: (gdb) showallvnodes 4874| Display info about all vnodes 4875end 4876 4877define _showvnodelockheader 4878 printf "* type W held by lock type start end\n" 4879 printf "- ----- - ------------- --------- ------------------ ------------------\n" 4880end 4881 4882define _showvnodelock 4883 set $kgm_svl_lock = ((struct lockf *)$arg0) 4884 4885 # decode flags 4886 set $kgm_svl_flags = $kgm_svl_lock->lf_flags 4887 set $kgm_svl_type = $kgm_svl_lock->lf_type 4888 if ($kgm_svl_flags & 0x20) 4889 printf "flock" 4890 end 4891 if ($kgm_svl_flags & 0x40) 4892 printf "posix" 4893 end 4894 if ($kgm_svl_flags & 0x80) 4895 printf "prov " 4896 end 4897 if ($kgm_svl_flags & 0x10) 4898 printf " W " 4899 else 4900 printf " . " 4901 end 4902 4903 # POSIX file vs. advisory range locks 4904 if ($kgm_svl_flags & 0x40) 4905 set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id 4906 printf "PID %8d ", $kgm_svl_proc->p_pid 4907 else 4908 printf "ID 0x%08x ", $kgm_svl_lock->lf_id 4909 end 4910 4911 # lock type 4912 if ($kgm_svl_type == 1) 4913 printf "shared " 4914 else 4915 if ($kgm_svl_type == 3) 4916 printf "exclusive " 4917 else 4918 if ($kgm_svl_type == 2) 4919 printf "unlock " 4920 else 4921 printf "unknown " 4922 end 4923 end 4924 end 4925 4926 # start and stop 4927 printf "0x%016x..", $kgm_svl_lock->lf_start 4928 printf "0x%016x ", $kgm_svl_lock->lf_end 4929 printf "\n" 4930end 4931# Body of showvnodelocks, not including header 4932define _showvnodelocks 4933 set $kgm_svl_vnode = ((vnode_t)$arg0) 4934 set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf 4935 while ($kgm_svl_lockiter != 0) 4936 # locks that are held 4937 printf "H " 4938 _showvnodelock $kgm_svl_lockiter 4939 4940 # and any locks blocked by them 4941 set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first 4942 while ($kgm_svl_blocker != 0) 4943 printf "> " 4944 _showvnodelock $kgm_svl_blocker 4945 set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next 4946 end 4947 4948 # and on to the next one... 4949 set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next 4950 end 4951end 4952 4953 4954define showvnodelocks 4955 if ($argc == 1) 4956 _showvnodelockheader 4957 _showvnodelocks $arg0 4958 else 4959 printf "| Usage:\n|\n" 4960 help showvnodelocks 4961 end 4962end 4963 4964document showvnodelocks 4965Syntax: (gdb) showvnodelocks <vnode_t> 4966| Given a vnodet pointer, display the list of advisory record locks for the 4967| referenced pvnodes 4968end 4969 4970define showbootargs 4971 printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine 4972end 4973 4974document showbootargs 4975Syntax: showbootargs 4976| Display boot arguments passed to the target kernel 4977end 4978 4979define showbootermemorymap 4980 set $kgm_boot_args = kernelBootArgs 4981 set $kgm_msize = kernelBootArgs->MemoryMapDescriptorSize 4982 set $kgm_mcount = kernelBootArgs->MemoryMapSize / $kgm_msize 4983 set $kgm_i = 0 4984 4985 printf "Type Physical Start Number of Pages\n" 4986 while $kgm_i < $kgm_mcount 4987 set $kgm_mptr = (EfiMemoryRange *)((unsigned long)kernelBootArgs->MemoryMap + $kgm_i * $kgm_msize) 4988# p/x *$kgm_mptr 4989 if $kgm_mptr->Type == 0 4990 printf "reserved " 4991 end 4992 if $kgm_mptr->Type == 1 4993 printf "LoaderCode" 4994 end 4995 if $kgm_mptr->Type == 2 4996 printf "LoaderData" 4997 end 4998 if $kgm_mptr->Type == 3 4999 printf "BS_code " 5000 end 5001 if $kgm_mptr->Type == 4 5002 printf "BS_data " 5003 end 5004 if $kgm_mptr->Type == 5 5005 printf "RT_code " 5006 end 5007 if $kgm_mptr->Type == 6 5008 printf "RT_data " 5009 end 5010 if $kgm_mptr->Type == 7 5011 printf "available " 5012 end 5013 if $kgm_mptr->Type == 8 5014 printf "Unusable " 5015 end 5016 if $kgm_mptr->Type == 9 5017 printf "ACPI_recl " 5018 end 5019 if $kgm_mptr->Type == 10 5020 printf "ACPI_NVS " 5021 end 5022 if $kgm_mptr->Type == 11 5023 printf "MemMapIO " 5024 end 5025 if $kgm_mptr->Type == 12 5026 printf "MemPortIO " 5027 end 5028 if $kgm_mptr->Type == 13 5029 printf "PAL_code " 5030 end 5031 if $kgm_mptr->Type > 13 5032 printf "UNKNOWN " 5033 end 5034 5035 printf " %016llx %016llx\n", $kgm_mptr->PhysicalStart, $kgm_mptr->NumberOfPages 5036 set $kgm_i = $kgm_i + 1 5037 end 5038end 5039 5040document showbootermemorymap 5041Syntax: (gdb) showbootermemorymap 5042| Prints out the phys memory map from kernelBootArgs 5043end 5044 5045 5046define showstacksaftertask 5047 set $kgm_head_taskp = &default_pset.tasks 5048 set $kgm_taskp = (struct task *)$arg0 5049 while $kgm_taskp != $kgm_head_taskp 5050 showtaskheader 5051 showtaskint $kgm_taskp 5052 set $kgm_head_actp = &($kgm_taskp->threads) 5053 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 5054 while $kgm_actp != $kgm_head_actp 5055 showactheader 5056 if ($decode_wait_events > 0) 5057 showactint $kgm_actp 1 5058 else 5059 showactint $kgm_actp 2 5060 end 5061 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 5062 end 5063 printf "\n" 5064 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 5065 end 5066end 5067document showstacksaftertask 5068Syntax: (gdb) showstacksaftertask <task> 5069| Routine to print out all stacks (as in showallstacks) starting after a given task 5070| Useful if that gdb refuses to print a certain task's stack. 5071end 5072 5073define showpmworkqueueint 5074 set $kgm_pm_wq = (IOPMWorkQueue *)$arg0 5075 set $kgm_pm_node = (IOService *)$kgm_pm_wq->owner 5076 printf "0x%08x 0x%08x ", $kgm_pm_wq, $kgm_pm_node 5077 printf "%02d ", $kgm_pm_node->pwrMgt->CurrentPowerState 5078 printf "%02d ", $kgm_pm_node->pwrMgt->MachineState 5079 printf "%02d ", $kgm_pm_node->pwrMgt->WaitReason 5080 printf "%s\n", $kgm_pm_node->pwrMgt->Name 5081 set $kgm_pm_queue = &($kgm_pm_wq->fWorkQueue) 5082 set $kgm_pm_req = (IOPMRequest *) $kgm_pm_queue->next 5083 while ( (queue_entry_t) $kgm_pm_req != (queue_entry_t) $kgm_pm_queue) 5084 printf " Request 0x%08x [%02x] Args ", $kgm_pm_req, $kgm_pm_req->fType 5085 printf "0x%08x ", $kgm_pm_req->fArg0 5086 printf "0x%08x ", $kgm_pm_req->fArg1 5087 printf "0x%08x\n", $kgm_pm_req->fArg2 5088 set $kgm_pm_req = (IOPMRequest *)$kgm_pm_req->fCommandChain.next 5089 end 5090end 5091 5092define showallpmworkqueues 5093 set $kgm_pm_next = gIOPMWorkLoop->eventChain 5094 printf "WorkQueue Owner PS MS WT Name\n" 5095 printf "--------------------------------------\n" 5096 while ( $kgm_pm_next ) 5097 set $kgm_vt = *((void **) $kgm_pm_next) 5098 if ($kgm_vt == _ZTV13IOPMWorkQueue) 5099 showpmworkqueueint $kgm_pm_next 5100 end 5101 set $kgm_pm_next = $kgm_pm_next->eventChainNext 5102 end 5103end 5104 5105document showallpmworkqueues 5106Syntax: (gdb) showallpmworkqueues 5107| Display info about all IOPMWorkQueue objects 5108end 5109 5110define showioservicepm 5111 set $kgm_iopmpriv = (IOServicePM *)$arg0 5112 printf "{ this object = %08x", $kgm_iopmpriv->Owner 5113 if ( $kgm_iopmpriv->WeAreRoot ) 5114 printf " (root)" 5115 end 5116 printf ", " 5117 5118 printf "MachineState = %d (", $kgm_iopmpriv->MachineState 5119 if ( $kgm_iopmpriv->MachineState == 1 ) 5120 printf "kIOPM_OurChangeTellClientsPowerDown" 5121 else 5122 if ( $kgm_iopmpriv->MachineState == 2 ) 5123 printf "kIOPM_OurChangeTellPriorityClientsPowerDown" 5124 else 5125 if ( $kgm_iopmpriv->MachineState == 3 ) 5126 printf "kIOPM_OurChangeNotifyInterestedDriversWillChange" 5127 else 5128 if ( $kgm_iopmpriv->MachineState == 4 ) 5129 printf "kIOPM_OurChangeSetPowerState" 5130 else 5131 if ( $kgm_iopmpriv->MachineState == 5 ) 5132 printf "kIOPM_OurChangeWaitForPowerSettle" 5133 else 5134 if ( $kgm_iopmpriv->MachineState == 6 ) 5135 printf "kIOPM_OurChangeNotifyInterestedDriversDidChange" 5136 else 5137 if ( $kgm_iopmpriv->MachineState == 7 ) 5138 printf "kIOPM_OurChangeFinish" 5139 else 5140 if ( $kgm_iopmpriv->MachineState == 8 ) 5141 printf "kIOPM_ParentDownTellPriorityClientsPowerDown" 5142 else 5143 if ( $kgm_iopmpriv->MachineState == 9 ) 5144 printf "kIOPM_ParentDownNotifyInterestedDriversWillChange" 5145 else 5146 if ( $kgm_iopmpriv->MachineState == 10 ) 5147 printf "Unused_MachineState_10" 5148 else 5149 if ( $kgm_iopmpriv->MachineState == 11 ) 5150 printf "kIOPM_ParentDownNotifyDidChangeAndAcknowledgeChange" 5151 else 5152 if ( $kgm_iopmpriv->MachineState == 12 ) 5153 printf "kIOPM_ParentDownSetPowerState" 5154 else 5155 if ( $kgm_iopmpriv->MachineState == 13 ) 5156 printf "kIOPM_ParentDownWaitForPowerSettle" 5157 else 5158 if ( $kgm_iopmpriv->MachineState == 14 ) 5159 printf "kIOPM_ParentDownAcknowledgeChange" 5160 else 5161 if ( $kgm_iopmpriv->MachineState == 15) 5162 printf "kIOPM_ParentUpSetPowerState" 5163 else 5164 if ( $kgm_iopmpriv->MachineState == 16) 5165 printf "Unused_MachineState_16" 5166 else 5167 if ( $kgm_iopmpriv->MachineState == 17) 5168 printf "kIOPM_ParentUpWaitForSettleTime" 5169 else 5170 if ( $kgm_iopmpriv->MachineState == 18) 5171 printf "kIOPM_ParentUpNotifyInterestedDriversDidChange" 5172 else 5173 if ( $kgm_iopmpriv->MachineState == 19) 5174 printf "kIOPM_ParentUpAcknowledgePowerChange" 5175 else 5176 if ( $kgm_iopmpriv->MachineState == 20) 5177 printf "kIOPM_Finished" 5178 else 5179 if ( $kgm_iopmpriv->MachineState == 21) 5180 printf "kIOPM_DriverThreadCallDone" 5181 else 5182 if ( $kgm_iopmpriv->MachineState == 22) 5183 printf "kIOPM_NotifyChildrenDone" 5184 end 5185 end 5186 end 5187 end 5188 end 5189 end 5190 end 5191 end 5192 end 5193 end 5194 end 5195 end 5196 end 5197 end 5198 end 5199 end 5200 end 5201 end 5202 end 5203 end 5204 end 5205 end 5206 printf "), " 5207 5208 if ( $kgm_iopmpriv->MachineState != 20 ) 5209 printf "DriverTimer = %d, ",(unsigned int)$kgm_iopmpriv->DriverTimer 5210 printf "SettleTime = %d, ",(unsigned int)$kgm_iopmpriv->SettleTimeUS 5211 printf "HeadNoteFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteFlags 5212 printf "HeadNoteState = %d, ",(unsigned int)$kgm_iopmpriv->HeadNoteState 5213 printf "HeadNoteOutputFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteOutputFlags 5214 printf "HeadNoteDomainState = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteDomainState 5215 printf "HeadNoteCapabilityFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteCapabilityFlags 5216 printf "HeadNotePendingAcks = %x, ",(unsigned int)$kgm_iopmpriv->HeadNotePendingAcks 5217 end 5218 5219 if ( $kgm_iopmpriv->DeviceOverrides != 0 ) 5220 printf"DeviceOverrides, " 5221 end 5222 5223 printf "DriverDesire = %d, ",(unsigned int)$kgm_iopmpriv->DriverDesire 5224 printf "DeviceDesire = %d, ",(unsigned int)$kgm_iopmpriv->DeviceDesire 5225 printf "DesiredPowerState = %d, ",(unsigned int)$kgm_iopmpriv->DesiredPowerState 5226 printf "PreviousRequest = %d }",(unsigned int)$kgm_iopmpriv->PreviousRequest 5227end 5228 5229document showioservicepm 5230Syntax: (gdb) showioservicepm <IOServicePM pointer> 5231| Routine to dump the IOServicePM object 5232end 5233 5234define showregistryentryrecursepmstate 5235 set $kgm_re = (IOService *)$arg1 5236 set $kgm$arg0_stack = (unsigned long long) $arg2 5237 5238 if ($arg3) 5239 set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth) 5240 else 5241 set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth) 5242 end 5243 5244 dictget $kgm_re->fRegistryTable $kgm_childkey 5245 set $kgm$arg0_child_array = (OSArray *) $kgm_result 5246 5247 if ($kgm$arg0_child_array) 5248 set $kgm$arg0_child_count = $kgm$arg0_child_array->count 5249 else 5250 set $kgm$arg0_child_count = 0 5251 end 5252 5253 if ($kgm$arg0_child_count) 5254 set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth) 5255 else 5256 set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth) 5257 end 5258 5259 indent $kgm_reg_depth $kgm$arg0_stack 5260 printf "+-o " 5261 5262 dictget $kgm_re->fRegistryTable $kgm_namekey 5263 if ($kgm_result == 0) 5264 dictget $kgm_re->fRegistryTable gIONameKey 5265 end 5266 if ($kgm_result == 0) 5267 dictget $kgm_re->fPropertyTable gIOClassKey 5268 end 5269 5270 if ($kgm_result != 0) 5271 printf "%s <%p>", ((OSString *)$kgm_result)->string, $kgm_re 5272 else 5273 if (((IOService*)$kgm_re)->pwrMgt && ((IOService*)$kgm_re)->pwrMgt->Name) 5274 printf "%s <%p>", ((IOService*)$kgm_re)->pwrMgt->Name, $kgm_re 5275 else 5276 printf "?? <%p>", $kgm_re 5277 end 5278 end 5279 5280 if (((IOService*)$kgm_re)->pwrMgt ) 5281 printf " Current Power State: %ld ", ((IOService*)$kgm_re)->pwrMgt->CurrentPowerState 5282 #printf " Mach State %ld", ((IOService*)$kgm_re)->pwrMgt->MachineState 5283 showioservicepm ((IOService*)$kgm_re)->pwrMgt 5284 end 5285 printf "\n" 5286 5287 5288 # recurse 5289 if ($kgm$arg0_child_count != 0) 5290 5291 set $kgm_reg_depth = $kgm_reg_depth + 1 5292 set $kgm$arg0_child_idx = 0 5293 5294 while ($kgm$arg0_child_idx < $kgm$arg0_child_count) 5295 set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++] 5296 set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count) 5297 showregistryentryrecursepmstate _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib 5298 end 5299 5300 set $kgm_reg_depth = $kgm_reg_depth - 1 5301 end 5302end 5303 5304define showregistryentryintpmstate 5305 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane[2] 5306 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane[4] 5307 showregistryentryrecursepmstate _ $arg0 0 0 5308end 5309 5310define showregistrypmstate 5311# setregistryplane gIOPowerPlane 5312 set $kgm_reg_depth = 0 5313 set $kgm_show_props = 1 5314 showregistryentryintpmstate gRegistryRoot 5315end 5316 5317document showregistrypmstate 5318Syntax: (gdb) showregistrypmstate 5319| Routine to dump the PM state of each IOPower registry entry 5320end 5321 5322define showstacksafterthread 5323 set $kgm_head_taskp = &default_pset.tasks 5324 set $kgm_actp = (struct thread *)$arg0 5325 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 5326 set $kgm_taskp = (struct task *)$kgm_actp->task 5327 while $kgm_taskp != $kgm_head_taskp 5328 showtaskheader 5329 showtaskint $kgm_taskp 5330 set $kgm_head_actp = &($kgm_taskp->threads) 5331 while $kgm_actp != $kgm_head_actp 5332 showactheader 5333 if ($decode_wait_events > 0) 5334 showactint $kgm_actp 1 5335 else 5336 showactint $kgm_actp 2 5337 end 5338 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 5339 end 5340 printf "\n" 5341 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 5342 end 5343end 5344 5345document showstacksafterthread 5346Syntax: (gdb) showstacksafterthread <thread> 5347| Routine to print out all stacks (as in showallstacks) starting after a given thread 5348| Useful if that gdb refuses to print a certain task's stack. 5349end 5350 5351define kdp-reenter 5352 set kdp_reentry_deadline = ((unsigned) $arg0)*1000 5353 continue 5354end 5355 5356document kdp-reenter 5357Syntax: (gdb) kdp-reenter <seconds> 5358| Schedules reentry into the debugger after <seconds> seconds, and resumes 5359| the target system. 5360end 5361 5362define _if_present 5363 if (!$arg0) 5364 printf " not" 5365 end 5366 printf " present" 5367end 5368 5369define showMCAstate 5370 if ($kgm_mtype != 7) 5371 printf "Not available for current architecture.\n" 5372 else 5373 printf "MCA" 5374 _if_present mca_MCA_present 5375 printf ", control MSR" 5376 _if_present mca_control_MSR_present 5377 printf ", threshold status" 5378 _if_present mca_threshold_status_present 5379 printf "\n%d error banks, ", mca_error_bank_count 5380 printf "family code 0x%x, ", mca_family 5381 printf "machine-check dump state: %d\n", mca_dump_state 5382 set $kgm_cpu = 0 5383 while cpu_data_ptr[$kgm_cpu] != 0 5384 set $kgm_mcp = cpu_data_ptr[$kgm_cpu]->cpu_mca_state 5385 if $kgm_mcp 5386 printf "CPU %d:", $kgm_cpu 5387 printf " mca_mcg_ctl: 0x%016llx", $kgm_mcp->mca_mcg_ctl 5388 printf " mca_mcg_status: 0x%016llx\n", $kgm_mcp->mca_mcg_status.u64 5389 printf "bank " 5390 printf "mca_mci_ctl " 5391 printf "mca_mci_status " 5392 printf "mca_mci_addr " 5393 printf "mca_mci_misc\n" 5394 set $kgm_bank = 0 5395 while $kgm_bank < mca_error_bank_count 5396 set $kgm_bp = &$kgm_mcp->mca_error_bank[$kgm_bank] 5397 printf " %2d:", $kgm_bank 5398 printf " 0x%016llx", $kgm_bp->mca_mci_ctl 5399 printf " 0x%016llx", $kgm_bp->mca_mci_status.u64 5400 printf " 0x%016llx", $kgm_bp->mca_mci_addr 5401 printf " 0x%016llx\n", $kgm_bp->mca_mci_misc 5402 set $kgm_bank = $kgm_bank + 1 5403 end 5404 end 5405 set $kgm_cpu = $kgm_cpu + 1 5406 end 5407 end 5408end 5409 5410document showMCAstate 5411Syntax: showMCAstate 5412| Print machine-check register state after MC exception. 5413end 5414 5415define _pt_step 5416 # 5417 # Step to lower-level page table and print attributes 5418 # $kgm_pt_paddr: current page table entry physical address 5419 # $kgm_pt_index: current page table entry index (0..511) 5420 # returns 5421 # $kgm_pt_paddr: next level page table entry physical address 5422 # or null if invalid 5423 # For $kgm_pt_verbose = 0: print nothing 5424 # 1: print basic information 5425 # 2: print basic information and hex table dump 5426 # The trickery with kdp_src_high32 is required for accesses above 4GB. 5427 # 5428 set $kgm_entryp = $kgm_pt_paddr + 8*$kgm_pt_index 5429 set kdp_src_high32 = $kgm_pt_paddr >> 32 5430 set kdp_trans_off = 1 5431 set $entry = *(pt_entry_t *)($kgm_entryp & 0x0ffffffffULL) 5432 if $kgm_pt_verbose == 2 5433 x/512g ($kgm_pt_paddr & 0x0ffffffffULL) 5434 end 5435 set kdp_trans_off = 0 5436 set kdp_src_high32 = 0 5437 set $kgm_paddr_mask = ~((0xffffULL<<48) | 0xfffULL) 5438 if $kgm_pt_verbose == 0 5439 if $entry & (0x1 << 0) 5440 set $kgm_pt_paddr = $entry & $kgm_paddr_mask 5441 else 5442 set $kgm_pt_paddr = 0 5443 end 5444 else 5445 printf "0x%016llx:\n\t0x%016llx\n\t", $kgm_entryp, $entry 5446 if $entry & (0x1 << 0) 5447 printf "valid" 5448 set $kgm_pt_paddr = $entry & $kgm_paddr_mask 5449 else 5450 printf "invalid" 5451 set $kgm_pt_paddr = 0 5452 end 5453 if $entry & (0x1 << 1) 5454 printf " writeable" 5455 else 5456 printf " read-only" 5457 end 5458 if $entry & (0x1 << 2) 5459 printf " user" 5460 else 5461 printf " supervisor" 5462 end 5463 if $entry & (0x1 << 3) 5464 printf " PWT" 5465 end 5466 if $entry & (0x1 << 4) 5467 printf " PCD" 5468 end 5469 if $entry & (0x1 << 5) 5470 printf " accessed" 5471 end 5472 if $entry & (0x1 << 6) 5473 printf " dirty" 5474 end 5475 if $entry & (0x1 << 7) 5476 printf " PAT" 5477 end 5478 if $entry & (0x1 << 8) 5479 printf " global" 5480 end 5481 if $entry & (0x3 << 9) 5482 printf " avail:0x%x", ($entry >> 9) & 0x3 5483 end 5484 if $entry & (0x1 << 63) 5485 printf " noexec" 5486 end 5487 printf "\n" 5488 end 5489end 5490 5491define _pmap_walk 5492 set $kgm_pmap = (pmap_t) $arg0 5493 set $kgm_vaddr = $arg1 5494 set $kgm_pt_paddr = $kgm_pmap->pm_cr3 5495 if $kgm_pt_paddr && cpu_64bit 5496 set $kgm_pt_index = ($kgm_vaddr >> 39) & 0x1ffULL 5497 if $kgm_pt_verbose 5498 printf "pml4 (index %d):\n", $kgm_pt_index 5499 end 5500 _pt_step 5501 end 5502 if $kgm_pt_paddr 5503 set $kgm_pt_index = ($kgm_vaddr >> 30) & 0x1ffULL 5504 if $kgm_pt_verbose 5505 printf "pdpt (index %d):\n", $kgm_pt_index 5506 end 5507 _pt_step 5508 end 5509 if $kgm_pt_paddr 5510 set $kgm_pt_index = ($kgm_vaddr >> 21) & 0x1ffULL 5511 if $kgm_pt_verbose 5512 printf "pdt (index %d):\n", $kgm_pt_index 5513 end 5514 _pt_step 5515 end 5516 if $kgm_pt_paddr 5517 set $kgm_pt_index = ($kgm_vaddr >> 12) & 0x1ffULL 5518 if $kgm_pt_verbose 5519 printf "pt (index %d):\n", $kgm_pt_index 5520 end 5521 _pt_step 5522 end 5523 if $kgm_pt_paddr 5524 set $kgm_paddr = $kgm_pt_paddr + ($kgm_vaddr & 0xfffULL) 5525 set kdp_trans_off = 1 5526 set kdp_src_high32 = $kgm_paddr >> 32 5527 set $kgm_value = *($kgm_paddr & 0x0ffffffffULL) 5528 set kdp_trans_off = 0 5529 set kdp_src_high32 = 0 5530 printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value 5531 else 5532 set $kgm_paddr = 0 5533 printf "(no translation)\n" 5534 end 5535end 5536 5537define pmap_walk 5538 if $kgm_mtype != 7 5539 printf "Not available for current architecture.\n" 5540 else 5541 if $argc != 2 5542 printf "pmap_walk <pmap> <vaddr>\n" 5543 else 5544 if !$kgm_pt_verbose 5545 set $kgm_pt_verbose = 1 5546 else 5547 if $kgm_pt_verbose != 2 5548 set $kgm_pt_verbose = 1 5549 end 5550 end 5551 _pmap_walk $arg0 $arg1 5552 end 5553 end 5554end 5555 5556document pmap_walk 5557Syntax: (gdb) pmap_walk <pmap> <virtual_address> 5558| Perform a page-table walk in <pmap> for <virtual_address>. 5559| Set $kgm_pt_verbose=2 for full hex dump of page tables. 5560end 5561 5562define pmap_vtop 5563 if $kgm_mtype != 7 5564 printf "Not available for current architecture.\n" 5565 else 5566 if $argc != 2 5567 printf "pmap_vtop <pamp> <vaddr>\n" 5568 else 5569 set $kgm_pt_verbose = 0 5570 _pmap_walk $arg0 $arg1 5571 end 5572 end 5573end 5574 5575document pmap_vtop 5576Syntax: (gdb) pmap_vtop <pmap> <virtual_address> 5577| For page-tables in <pmap> translate <virtual_address> to physical address. 5578end 5579 5580define zstack 5581 set $index = $arg0 5582 5583 if (log_records == 0) 5584 set $count = 0 5585 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n" 5586 else 5587 if ($argc == 2) 5588 set $count = $arg1 5589 else 5590 set $count = 1 5591 end 5592 end 5593 5594 while ($count) 5595 printf "\n--------------- " 5596 5597 if (zrecords[$index].z_opcode == 1) 5598 printf "ALLOC " 5599 else 5600 printf "FREE " 5601 end 5602 5603 printf " 0x%x : index %d : ztime %d -------------\n", zrecords[$index].z_element, $index, zrecords[$index].z_time 5604 5605 set $frame = 0 5606 5607 while ($frame < 15) 5608 set $frame_pc = zrecords[$index].z_pc[$frame] 5609 5610 if ($frame_pc == 0) 5611 loop_break 5612 end 5613 5614 x/i $frame_pc 5615 set $frame = $frame + 1 5616 end 5617 5618 set $index = $index + 1 5619 set $count = $count - 1 5620 end 5621end 5622 5623document zstack 5624Syntax: (gdb) zstack <index> [<count>] 5625| Zone leak debugging: print the stack trace of log element at <index>. 5626| If a <count> is supplied, it prints <count> log elements starting at <index>. 5627| 5628| The suggested usage is to look at indexes below zcurrent and look for common stack traces. 5629| The stack trace that occurs the most is probably the cause of the leak. Find the pc of the 5630| function calling into zalloc and use the countpcs kgmacro to find out how often that pc occurs in the log. 5631| The pc occuring in a high percentage of records is most likely the source of the leak. 5632| 5633| The findoldest kgmacro is also useful for leak debugging since it identifies the oldest record 5634| in the log, which may indicate the leaker. 5635end 5636 5637define findoldest 5638 set $index = 0 5639 set $count = log_records 5640 set $cur_min = 2000000000 5641 set $cur_index = 0 5642 5643 if (log_records == 0) 5644 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n" 5645 else 5646 5647 while ($count) 5648 if (zrecords[$index].z_element && zrecords[$index].z_time < $cur_min) 5649 set $cur_index = $index 5650 set $cur_min = zrecords[$index].z_time 5651 end 5652 5653 set $count = $count - 1 5654 set $index = $index + 1 5655 end 5656 5657 printf "oldest record is at log index %d:\n", $cur_index 5658 zstack $cur_index 5659 end 5660end 5661 5662document findoldest 5663Syntax: (gdb) findoldest 5664| Zone leak debugging: find and print the oldest record in the log. Note that this command 5665| can take several minutes to run since it uses linear search. 5666| 5667| Once it prints a stack trace, find the pc of the caller above all the zalloc, kalloc and 5668| IOKit layers. Then use the countpcs kgmacro to see how often this caller has allocated 5669| memory. A caller with a high percentage of records in the log is probably the leaker. 5670end 5671 5672define countpcs 5673 set $target_pc = $arg0 5674 set $index = 0 5675 set $count = log_records 5676 set $found = 0 5677 5678 if (log_records == 0) 5679 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n" 5680 else 5681 5682 while ($count) 5683 set $frame = 0 5684 5685 if (zrecords[$index].z_element != 0) 5686 while ($frame < 15) 5687 if (zrecords[$index].z_pc[$frame] == $target_pc) 5688 set $found = $found + 1 5689 set $frame = 15 5690 end 5691 5692 set $frame = $frame + 1 5693 end 5694 end 5695 5696 set $index = $index + 1 5697 set $count = $count - 1 5698 end 5699 5700 printf "occurred %d times in log (%d%c of records)\n", $found, ($found * 100) / zrecorded, '%' 5701 end 5702end 5703 5704document countpcs 5705Syntax: (gdb) countpcs <pc> 5706| Zone leak debugging: search the log and print a count of all log entries that contain the given <pc> 5707| in the stack trace. This is useful for verifying a suspected <pc> as being the source of 5708| the leak. If a high percentage of the log entries contain the given <pc>, then it's most 5709| likely the source of the leak. Note that this command can take several minutes to run. 5710end 5711 5712define findelem 5713 set $fe_index = zcurrent 5714 set $fe_count = log_records 5715 set $fe_elem = $arg0 5716 set $fe_prev_op = -1 5717 5718 if (log_records == 0) 5719 printf "Zone logging not enabled. Add 'zlog=<zone name>' to boot-args.\n" 5720 end 5721 5722 while ($fe_count) 5723 if (zrecords[$fe_index].z_element == $fe_elem) 5724 zstack $fe_index 5725 5726 if (zrecords[$fe_index].z_opcode == $fe_prev_op) 5727 printf "*************** DOUBLE OP! *********************\n 5728 end 5729 5730 set $fe_prev_op = zrecords[$fe_index].z_opcode 5731 end 5732 5733 set $fe_count = $fe_count - 1 5734 set $fe_index = $fe_index + 1 5735 5736 if ($fe_index >= log_records) 5737 set $fe_index = 0 5738 end 5739 end 5740end 5741 5742document findelem 5743Syntax: (gdb) findelem <elem addr> 5744| Zone corruption debugging: search the log and print out the stack traces for all log entries that 5745| refer to the given zone element. When the kernel panics due to a corrupted zone element, get the 5746| element address and use this macro. This will show you the stack traces of all logged zalloc and 5747| zfree operations which tells you who touched the element in the recent past. This also makes 5748| double-frees readily apparent. 5749end 5750