1# 2# Kernel gdb macros 3# 4# These gdb macros should be useful during kernel development in 5# determining what's going on in the kernel. 6# 7# All the convenience variables used by these macros begin with $kgm_ 8 9define showversion 10#Display version string, a pointer to which is pinned at 0x501C in the kernel's 11#low memory globals 12 p (char *) *0x501c 13end 14 15document showversion 16Syntax: showversion 17| Read the kernel version string from a fixed address in low 18| memory. Useful if you don't know which kernel is on the other end, 19| and need to find the appropriate symbols. Beware that if you've 20| loaded a symbol file, but aren't connected to a remote target, 21| the version string from the symbol file will be displayed instead. 22| This macro expects to be connected to the remote kernel to function 23| correctly. 24end 25 26set $kgm_dummy = &proc0 27set $kgm_dummy = &kmod 28set $kgm_mtype = ((struct mach_header)_mh_execute_header).cputype 29 30echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n 31 32define kgm 33printf "" 34echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n 35end 36 37document kgm 38| These are the kernel gdb macros. These gdb macros are intended to be 39| used when debugging a remote kernel via the kdp protocol. Typically, you 40| would connect to your remote target like so: 41| (gdb) target remote-kdp 42| (gdb) attach <name-of-remote-host> 43| 44| The following macros are available in this package: 45| showversion Displays a string describing the remote kernel version 46| 47| showalltasks Display a summary listing of all tasks 48| showallthreads Display info about all threads in the system 49| showallstacks Display the stack for each thread in the system 50| showcurrentthreads Display info about the thread running on each cpu 51| showcurrentstacks Display the stack for the thread running on each cpu 52| showallvm Display a summary listing of all the vm maps 53| showallvme Display a summary listing of all the vm map entries 54| showallipc Display a summary listing of all the ipc spaces 55| showallrights Display a summary listing of all the ipc rights 56| showallkmods Display a summary listing of all the kernel modules 57| showallclasses Display info about all OSObject subclasses in the system 58| 59| showtask Display info about the specified task 60| showtaskthreads Display info about the threads in the task 61| showtaskstacks Display the stack for each thread in the task 62| showtaskvm Display info about the specified task's vm_map 63| showtaskvme Display info about the task's vm_map entries 64| showtaskipc Display info about the specified task's ipc space 65| showtaskrights Display info about the task's ipc space entries 66| 67| showact Display info about a thread specified by activation 68| showactstack Display the stack for a thread specified by activation 69| 70| showmap Display info about the specified vm_map 71| showmapvme Display a summary list of the specified vm_map's entries 72| 73| showipc Display info about the specified ipc space 74| showrights Display a summary list of all the rights in an ipc space 75| 76| showpid Display info about the process identified by pid 77| showproc Display info about the process identified by proc struct 78| 79| showkmod Display info about a kernel module 80| showkmodaddr Given an address, display the kernel module and offset 81| 82| dumpcallqueue Dump out all the entries given a queue head 83| 84| showallmtx Display info about mutexes usage 85| showallrwlck Display info about reader/writer locks usage 86| 87| zprint Display info about the memory zones 88| showioalloc Display info about iokit allocations 89| paniclog Display the panic log info 90| 91| switchtoact Switch to different context specified by activation 92| switchtoctx Switch to different context 93| showuserstack Display numeric backtrace of the user stack for an 94| activation 95| 96| switchtouserthread Switch to the user context of the specified thread 97| resetstacks Return to the original kernel context 98| 99| resetctx Reset context 100| resume_on Resume when detaching from gdb 101| resume_off Don't resume when detaching from gdb 102| 103| sendcore Configure kernel to send a coredump to the specified IP 104| disablecore Configure the kernel to disable coredump transmission 105| switchtocorethread Corefile version of "switchtoact" 106| resetcorectx Corefile version of "resetctx" 107| 108| kdp-reboot Restart remote target 109| 110| Type "help <macro>" for more specific help on a particular macro. 111| Type "show user <macro>" to see what the macro is really doing. 112end 113 114 115define showkmodheader 116 printf "kmod address size " 117 printf "id refs version name\n" 118end 119 120define showkmodint 121 set $kgm_kmodp = (struct kmod_info *)$arg0 122 printf "0x%08x ", $arg0 123 printf "0x%08x ", $kgm_kmodp->address 124 printf "0x%08x ", $kgm_kmodp->size 125 printf "%3d ", $kgm_kmodp->id 126 printf "%5d ", $kgm_kmodp->reference_count 127 printf "%10s ", &$kgm_kmodp->version 128 printf "%s\n", &$kgm_kmodp->name 129end 130 131set $kgm_kmodmin = 0xffffffff 132set $kgm_fkmodmin = 0x00000000 133set $kgm_kmodmax = 0x00000000 134set $kgm_fkmodmax = 0xffffffff 135set $kgm_pkmod = 0 136set $kgm_pkmodst = 0 137set $kgm_pkmoden = 0 138define showkmodaddr 139 printf "0x%x" , $arg0 140 if ((unsigned int)$arg0 >= (unsigned int)$kgm_pkmodst) && ((unsigned int)$arg0 <= (unsigned int)$kgm_pkmoden) 141 set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_pkmodst) 142 printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off 143 else 144 if ((unsigned int)$arg0 <= (unsigned int)$kgm_fkmodmax) && ((unsigned int)$arg0 >= (unsigned int)$kgm_fkmodmin) 145 set $kgm_kmodp = (struct kmod_info *)kmod 146 while $kgm_kmodp 147 set $kgm_kmod = *$kgm_kmodp 148 if $kgm_kmod.address && ($kgm_kmod.address < $kgm_kmodmin) 149 set $kgm_kmodmin = $kgm_kmod.address 150 end 151 if ($kgm_kmod.address + $kgm_kmod.size) > $kgm_kmodmax 152 set $kgm_kmodmax = $kgm_kmod.address 153 end 154 set $kgm_off = ((unsigned int)$arg0 - (unsigned int)$kgm_kmod.address) 155 if ($kgm_kmod.address <= $arg0) && ($kgm_off <= $kgm_kmod.size) 156 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off 157 set $kgm_pkmod = $kgm_kmodp 158 set $kgm_pkmodst = $kgm_kmod.address 159 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmod.size 160 set $kgm_kmodp = 0 161 else 162 set $kgm_kmodp = $kgm_kmod.next 163 end 164 end 165 if !$kgm_pkmod 166 set $kgm_fkmodmin = $kgm_kmodmin 167 set $kgm_fkmodmax = $kgm_kmodmax 168 end 169 end 170 end 171end 172document showkmodaddr 173| Given an address, print the offset and name for the kmod containing it 174| The following is the syntax: 175| (gdb) showkmodaddr <addr> 176end 177 178define showkmod 179 showkmodheader 180 showkmodint $arg0 181end 182document showkmod 183| Routine to print info about a kernel module 184| The following is the syntax: 185| (gdb) showkmod <kmod> 186end 187 188define showallkmods 189 showkmodheader 190 set $kgm_kmodp = (struct kmod_info *)kmod 191 while $kgm_kmodp 192 showkmodint $kgm_kmodp 193 set $kgm_kmodp = $kgm_kmodp->next 194 end 195end 196document showallkmods 197| Routine to print a summary listing of all the kernel modules 198| The following is the syntax: 199| (gdb) showallkmods 200end 201 202define showactheader 203 printf " activation " 204 printf "thread pri state wait_queue wait_event\n" 205end 206 207 208define showactint 209 printf " 0x%08x ", $arg0 210 set $kgm_thread = *(struct thread *)$arg0 211 printf "0x%08x ", $arg0 212 printf "%3d ", $kgm_thread.sched_pri 213 set $kgm_state = $kgm_thread.state 214 if $kgm_state & 0x80 215 printf "I" 216 end 217 if $kgm_state & 0x40 218 printf "P" 219 end 220 if $kgm_state & 0x20 221 printf "A" 222 end 223 if $kgm_state & 0x10 224 printf "H" 225 end 226 if $kgm_state & 0x08 227 printf "U" 228 end 229 if $kgm_state & 0x04 230 printf "R" 231 end 232 if $kgm_state & 0x02 233 printf "S" 234 end 235 if $kgm_state & 0x01 236 printf "W\t" 237 printf "0x%08x ", $kgm_thread.wait_queue 238 239 if ((unsigned)$kgm_thread.wait_event > (unsigned)sectPRELINKB) 240 showkmodaddr $kgm_thread.wait_event 241 else 242 output /a (unsigned) $kgm_thread.wait_event 243 end 244 end 245 if $arg1 != 0 246 if ($kgm_thread.kernel_stack != 0) 247 if ($kgm_thread.reserved_stack != 0) 248 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack 249 end 250 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack 251 if ($kgm_mtype == 18) 252 set $mysp = $kgm_thread.machine.pcb->save_r1 253 else 254 set $kgm_statep = (struct i386_kernel_state *) \ 255 ($kgm_thread->kernel_stack + 0x4000 \ 256 - sizeof(struct i386_kernel_state)) 257 set $mysp = $kgm_statep->k_ebp 258 end 259 set $prevsp = 0 260 printf "\n\t\tstacktop=0x%08x", $mysp 261 if ($kgm_mtype == 18) 262 set $stkmask = 0xf 263 set $stklimit = 0xb0000000 264 else 265 set $stkmask = 0x3 266 set $stklimit = 0xfc000000 267 end 268 while ($mysp != 0) && (($mysp & $stkmask) == 0) \ 269 && ($mysp < $stklimit) \ 270 && ((unsigned)$mysp > (unsigned)$prevsp) 271 printf "\n\t\t0x%08x ", $mysp 272 if ($kgm_mtype == 18) 273 set $kgm_return = *($mysp + 8) 274 else 275 set $kgm_return = *($mysp + 4) 276 end 277 if ((unsigned) $kgm_return > (unsigned) sectPRELINKB) 278 showkmodaddr $kgm_return 279 else 280 output /a (unsigned) $kgm_return 281 end 282 set $prevsp = $mysp 283 set $mysp = * $mysp 284 end 285 printf "\n\t\tstackbottom=0x%08x", $prevsp 286 else 287 printf "\n\t\t\tcontinuation=" 288 output /a (unsigned) $kgm_thread.continuation 289 end 290 printf "\n" 291 else 292 printf "\n" 293 end 294end 295 296define showact 297 showactheader 298 showactint $arg0 0 299end 300document showact 301| Routine to print out the state of a specific thread. 302| The following is the syntax: 303| (gdb) showact <activation> 304end 305 306 307define showactstack 308 showactheader 309 showactint $arg0 1 310end 311document showactstack 312| Routine to print out the stack of a specific thread. 313| The following is the syntax: 314| (gdb) showactstack <activation> 315end 316 317 318define showallthreads 319 set $kgm_head_taskp = &default_pset.tasks 320 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 321 while $kgm_taskp != $kgm_head_taskp 322 showtaskheader 323 showtaskint $kgm_taskp 324 showactheader 325 set $kgm_head_actp = &($kgm_taskp->threads) 326 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 327 while $kgm_actp != $kgm_head_actp 328 showactint $kgm_actp 0 329 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 330 end 331 printf "\n" 332 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 333 end 334end 335document showallthreads 336| Routine to print out info about all threads in the system. 337| The following is the syntax: 338| (gdb) showallthreads 339end 340 341define showcurrentthreads 342set $kgm_prp = processor_list 343 while $kgm_prp != 0 344 if ($kgm_prp)->active_thread != 0 345 set $kgm_actp = ($kgm_prp)->active_thread 346 showtaskheader 347 showtaskint ($kgm_actp)->task 348 showactheader 349 showactint $kgm_actp 0 350 printf "\n" 351 end 352 set $kgm_prp = ($kgm_prp)->processor_list 353 end 354end 355document showcurrentthreads 356| Routine to print out info about the thread running on each cpu. 357| The following is the syntax: 358| (gdb) showcurrentthreads 359end 360 361define showallstacks 362 set $kgm_head_taskp = &default_pset.tasks 363 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 364 while $kgm_taskp != $kgm_head_taskp 365 showtaskheader 366 showtaskint $kgm_taskp 367 set $kgm_head_actp = &($kgm_taskp->threads) 368 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 369 while $kgm_actp != $kgm_head_actp 370 showactheader 371 showactint $kgm_actp 1 372 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 373 end 374 printf "\n" 375 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 376 end 377end 378document showallstacks 379| Routine to print out the stack for each thread in the system. 380| The following is the syntax: 381| (gdb) showallstacks 382end 383 384define showcurrentstacks 385set $kgm_prp = processor_list 386 while $kgm_prp != 0 387 if ($kgm_prp)->active_thread != 0 388 set $kgm_actp = ($kgm_prp)->active_thread 389 showtaskheader 390 showtaskint ($kgm_actp)->task 391 showactheader 392 showactint $kgm_actp 1 393 printf "\n" 394 end 395 set $kgm_prp = ($kgm_prp)->processor_list 396 end 397end 398document showcurrentstacks 399| Routine to print out the thread running on each cpu (incl. its stack) 400| The following is the syntax: 401| (gdb) showcurrentstacks 402end 403 404define showwaiterheader 405 printf "waiters activation " 406 printf "thread pri state wait_queue wait_event\n" 407end 408 409define showwaitqwaiters 410 set $kgm_w_waitqp = (struct wait_queue *)$arg0 411 set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue) 412 set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_linksp->next 413 set $kgm_w_found = 0 414 while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp) 415 if ($kgm_w_wqe->wqe_type != &_wait_queue_link) 416 if !$kgm_w_found 417 set $kgm_w_found = 1 418 showwaiterheader 419 end 420 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe 421 showactint $kgm_w_shuttle 0 422 end 423 set $kgm_w_wqe = (struct wait_queue_element *)$kgm_w_wqe->wqe_links.next 424 end 425end 426 427define showwaitqwaitercount 428 set $kgm_wc_waitqp = (struct wait_queue *)$arg0 429 set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue) 430 set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_linksp->next 431 set $kgm_wc_count = 0 432 while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp) 433 if ($kgm_wc_wqe->wqe_type != &_wait_queue_link) 434 set $kgm_wc_count = $kgm_wc_count + 1 435 end 436 set $kgm_wc_wqe = (struct wait_queue_element *)$kgm_wc_wqe->wqe_links.next 437 end 438 printf "0x%08x ", $kgm_wc_count 439end 440 441define showwaitqmembercount 442 set $kgm_mc_waitqsetp = (struct wait_queue_set *)$arg0 443 set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks) 444 set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_setlinksp->next 445 set $kgm_mc_count = 0 446 while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp) 447 set $kgm_mc_count = $kgm_mc_count + 1 448 set $kgm_mc_wql = (struct wait_queue_link *)$kgm_mc_wql->wql_setlinks.next 449 end 450 printf "0x%08x ", $kgm_mc_count 451end 452 453 454define showwaitqmemberheader 455 printf "set-members wait_queue interlock " 456 printf "pol type member_cnt waiter_cnt\n" 457end 458 459define showwaitqmemberint 460 set $kgm_m_waitqp = (struct wait_queue *)$arg0 461 printf " 0x%08x ", $kgm_m_waitqp 462 printf "0x%08x ", $kgm_m_waitqp->wq_interlock.lock_data 463 if ($kgm_m_waitqp->wq_fifo) 464 printf "Fifo " 465 else 466 printf "Prio " 467 end 468 if ($kgm_m_waitqp->wq_type == 0xf1d1) 469 printf "Set " 470 showwaitqmembercount $kgm_m_waitqp 471 else 472 printf "Que 0x00000000 " 473 end 474 showwaitqwaitercount $kgm_m_waitqp 475 printf "\n" 476end 477 478 479define showwaitqmemberofheader 480 printf "member-of wait_queue interlock " 481 printf "pol type member_cnt waiter_cnt\n" 482end 483 484define showwaitqmemberof 485 set $kgm_mo_waitqp = (struct wait_queue *)$arg0 486 set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue) 487 set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_linksp->next 488 set $kgm_mo_found = 0 489 while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp) 490 if ($kgm_mo_wqe->wqe_type == &_wait_queue_link) 491 if !$kgm_mo_found 492 set $kgm_mo_found = 1 493 showwaitqmemberofheader 494 end 495 set $kgm_mo_wqlp = (struct wait_queue_link *)$kgm_mo_wqe 496 set $kgm_mo_wqsetp = (struct wait_queue *)($kgm_mo_wqlp->wql_setqueue) 497 showwaitqmemberint $kgm_mo_wqsetp 498 end 499 set $kgm_mo_wqe = (struct wait_queue_element *)$kgm_mo_wqe->wqe_links.next 500 end 501end 502 503define showwaitqmembers 504 set $kgm_ms_waitqsetp = (struct wait_queue_set *)$arg0 505 set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks) 506 set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_setlinksp->next 507 set $kgm_ms_found = 0 508 while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp) 509 set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue 510 if !$kgm_ms_found 511 showwaitqmemberheader 512 set $kgm_ms_found = 1 513 end 514 showwaitqmemberint $kgm_ms_waitqp 515 set $kgm_ms_wql = (struct wait_queue_link *)$kgm_ms_wql->wql_setlinks.next 516 end 517end 518 519define showwaitqheader 520 printf "wait_queue ref_count interlock " 521 printf "pol type member_cnt waiter_cnt\n" 522end 523 524define showwaitqint 525 set $kgm_waitqp = (struct wait_queue *)$arg0 526 printf "0x%08x ", $kgm_waitqp 527 if ($kgm_waitqp->wq_type == 0xf1d1) 528 printf "0x%08x ", ((struct wait_queue_set *)$kgm_waitqp)->wqs_refcount 529 else 530 printf "0x00000000 " 531 end 532 printf "0x%08x ", $kgm_waitqp->wq_interlock.lock_data 533 if ($kgm_waitqp->wq_fifo) 534 printf "Fifo " 535 else 536 printf "Prio " 537 end 538 if ($kgm_waitqp->wq_type == 0xf1d1) 539 printf "Set " 540 showwaitqmembercount $kgm_waitqp 541 else 542 printf "Que 0x00000000 " 543 end 544 showwaitqwaitercount $kgm_waitqp 545 printf "\n" 546end 547 548define showwaitq 549 set $kgm_waitq1p = (wait_queue_t)$arg0 550 showwaitqheader 551 showwaitqint $kgm_waitq1p 552 if ($kgm_waitq1p->wq_type == 0xf1d1) 553 showwaitqmembers $kgm_waitq1p 554 else 555 showwaitqmemberof $kgm_waitq1p 556 end 557 showwaitqwaiters $kgm_waitq1p 558end 559 560define showmapheader 561 printf "vm_map pmap vm_size " 562 printf "#ents rpage hint first_free\n" 563end 564 565define showvmeheader 566 printf " entry start " 567 printf " prot #page object offset\n" 568end 569 570define showvmint 571 set $kgm_mapp = (vm_map_t)$arg0 572 set $kgm_map = *$kgm_mapp 573 printf "0x%08x ", $arg0 574 printf "0x%08x ", $kgm_map.pmap 575 printf "0x%08x ", $kgm_map.size 576 printf "%3d ", $kgm_map.hdr.nentries 577 if $kgm_map.pmap 578 printf "%5d ", $kgm_map.pmap->stats.resident_count 579 else 580 printf "<n/a> " 581 end 582 printf "0x%08x ", $kgm_map.hint 583 printf "0x%08x\n", $kgm_map.first_free 584 if $arg1 != 0 585 showvmeheader 586 set $kgm_head_vmep = &($kgm_mapp->hdr.links) 587 set $kgm_vmep = $kgm_map.hdr.links.next 588 while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep)) 589 set $kgm_vme = *$kgm_vmep 590 printf " 0x%08x ", $kgm_vmep 591 printf "0x%016llx ", $kgm_vme.links.start 592 printf "%1x", $kgm_vme.protection 593 printf "%1x", $kgm_vme.max_protection 594 if $kgm_vme.inheritance == 0x0 595 printf "S" 596 end 597 if $kgm_vme.inheritance == 0x1 598 printf "C" 599 end 600 if $kgm_vme.inheritance == 0x2 601 printf "-" 602 end 603 if $kgm_vme.inheritance == 0x3 604 printf "D" 605 end 606 if $kgm_vme.is_sub_map 607 printf "s " 608 else 609 if $kgm_vme.needs_copy 610 printf "n " 611 else 612 printf " " 613 end 614 end 615 printf "%5d ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12 616 printf "0x%08x ", $kgm_vme.object.vm_object 617 printf "0x%016llx\n", $kgm_vme.offset 618 set $kgm_vmep = $kgm_vme.links.next 619 end 620 end 621 printf "\n" 622end 623 624 625define showmapvme 626 showmapheader 627 showvmint $arg0 1 628end 629document showmapvme 630| Routine to print out a summary listing of all the entries in a vm_map 631| The following is the syntax: 632| (gdb) showmapvme <vm_map> 633end 634 635 636define showmap 637 showmapheader 638 showvmint $arg0 0 639end 640document showmap 641| Routine to print out info about the specified vm_map 642| The following is the syntax: 643| (gdb) showmap <vm_map> 644end 645 646define showallvm 647 set $kgm_head_taskp = &default_pset.tasks 648 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 649 while $kgm_taskp != $kgm_head_taskp 650 showtaskheader 651 showmapheader 652 showtaskint $kgm_taskp 653 showvmint $kgm_taskp->map 0 654 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 655 end 656end 657document showallvm 658| Routine to print a summary listing of all the vm maps 659| The following is the syntax: 660| (gdb) showallvm 661end 662 663 664define showallvme 665 set $kgm_head_taskp = &default_pset.tasks 666 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 667 while $kgm_taskp != $kgm_head_taskp 668 showtaskheader 669 showmapheader 670 showtaskint $kgm_taskp 671 showvmint $kgm_taskp->map 1 672 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 673 end 674end 675document showallvme 676| Routine to print a summary listing of all the vm map entries 677| The following is the syntax: 678| (gdb) showallvme 679end 680 681 682define showipcheader 683 printf "ipc_space is_table table_next " 684 printf "flags tsize splaytree splaybase\n" 685end 686 687define showipceheader 688 printf " name object " 689 printf "rite urefs destname destination\n" 690end 691 692define showipceint 693 set $kgm_ie = *(ipc_entry_t)$arg0 694 printf " 0x%08x ", $arg1 695 printf "0x%08x ", $kgm_ie.ie_object 696 if $kgm_ie.ie_bits & 0x00100000 697 printf "Dead " 698 printf "%5d\n", $kgm_ie.ie_bits & 0xffff 699 else 700 if $kgm_ie.ie_bits & 0x00080000 701 printf "SET " 702 printf "%5d\n", $kgm_ie.ie_bits & 0xffff 703 else 704 if $kgm_ie.ie_bits & 0x00010000 705 if $kgm_ie.ie_bits & 0x00020000 706 printf " SR" 707 else 708 printf " S" 709 end 710 else 711 if $kgm_ie.ie_bits & 0x00020000 712 printf " R" 713 end 714 end 715 if $kgm_ie.ie_bits & 0x00040000 716 printf " O" 717 end 718 if $kgm_ie.index.request 719 printf "n" 720 else 721 printf " " 722 end 723 if $kgm_ie.ie_bits & 0x00800000 724 printf "c" 725 else 726 printf " " 727 end 728 printf "%5d ", $kgm_ie.ie_bits & 0xffff 729 showportdest $kgm_ie.ie_object 730 end 731 end 732end 733 734define showipcint 735 set $kgm_isp = (ipc_space_t)$arg0 736 set $kgm_is = *$kgm_isp 737 printf "0x%08x ", $arg0 738 printf "0x%08x ", $kgm_is.is_table 739 printf "0x%08x ", $kgm_is.is_table_next 740 if $kgm_is.is_growing != 0 741 printf "G" 742 else 743 printf " " 744 end 745 if $kgm_is.is_fast != 0 746 printf "F" 747 else 748 printf " " 749 end 750 if $kgm_is.is_active != 0 751 printf "A " 752 else 753 printf " " 754 end 755 printf "%5d ", $kgm_is.is_table_size 756 printf "0x%08x ", $kgm_is.is_tree_total 757 printf "0x%08x\n", &$kgm_isp->is_tree 758 if $arg1 != 0 759 showipceheader 760 set $kgm_iindex = 0 761 set $kgm_iep = $kgm_is.is_table 762 set $kgm_destspacep = (ipc_space_t)0 763 while ( $kgm_iindex < $kgm_is.is_table_size ) 764 set $kgm_ie = *$kgm_iep 765 if $kgm_ie.ie_bits & 0x001f0000 766 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24)) 767 showipceint $kgm_iep $kgm_name 768 end 769 set $kgm_iindex = $kgm_iindex + 1 770 set $kgm_iep = &($kgm_is.is_table[$kgm_iindex]) 771 end 772 if $kgm_is.is_tree_total 773 printf "Still need to write tree traversal\n" 774 end 775 end 776 printf "\n" 777end 778 779 780define showipc 781 set $kgm_isp = (ipc_space_t)$arg0 782 showipcheader 783 showipcint $kgm_isp 0 784end 785document showipc 786| Routine to print the status of the specified ipc space 787| The following is the syntax: 788| (gdb) showipc <ipc_space> 789end 790 791define showrights 792 set $kgm_isp = (ipc_space_t)$arg0 793 showipcheader 794 showipcint $kgm_isp 1 795end 796document showrights 797| Routine to print a summary list of all the rights in a specified ipc space 798| The following is the syntax: 799| (gdb) showrights <ipc_space> 800end 801 802 803define showtaskipc 804 set $kgm_taskp = (task_t)$arg0 805 showtaskheader 806 showipcheader 807 showtaskint $kgm_taskp 808 showipcint $kgm_taskp->itk_space 0 809end 810document showtaskipc 811| Routine to print info about the ipc space for a task 812| The following is the syntax: 813| (gdb) showtaskipc <task> 814end 815 816 817define showtaskrights 818 set $kgm_taskp = (task_t)$arg0 819 showtaskheader 820 showipcheader 821 showtaskint $kgm_taskp 822 showipcint $kgm_taskp->itk_space 1 823end 824document showtaskrights 825| Routine to print info about the ipc rights for a task 826| The following is the syntax: 827| (gdb) showtaskrights <task> 828end 829 830define showallipc 831 set $kgm_head_taskp = &default_pset.tasks 832 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) 833 while $kgm_cur_taskp != $kgm_head_taskp 834 showtaskheader 835 showipcheader 836 showtaskint $kgm_cur_taskp 837 showipcint $kgm_cur_taskp->itk_space 0 838 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->pset_tasks.next) 839 end 840end 841document showallipc 842| Routine to print a summary listing of all the ipc spaces 843| The following is the syntax: 844| (gdb) showallipc 845end 846 847 848define showallrights 849 set $kgm_head_taskp = &default_pset.tasks 850 set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next) 851 while $kgm_cur_taskp != $kgm_head_taskp 852 showtaskheader 853 showipcheader 854 showtaskint $kgm_cur_taskp 855 showipcint $kgm_cur_taskp->itk_space 1 856 set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->pset_tasks.next) 857 end 858end 859document showallrights 860| Routine to print a summary listing of all the ipc rights 861| The following is the syntax: 862| (gdb) showallrights 863end 864 865 866define showtaskvm 867 set $kgm_taskp = (task_t)$arg0 868 showtaskheader 869 showmapheader 870 showtaskint $kgm_taskp 871 showvmint $kgm_taskp->map 0 872end 873document showtaskvm 874| Routine to print out info about a task's vm_map 875| The following is the syntax: 876| (gdb) showtaskvm <task> 877end 878 879define showtaskvme 880 set $kgm_taskp = (task_t)$arg0 881 showtaskheader 882 showmapheader 883 showtaskint $kgm_taskp 884 showvmint $kgm_taskp->map 1 885end 886document showtaskvme 887| Routine to print out info about a task's vm_map_entries 888| The following is the syntax: 889| (gdb) showtaskvme <task> 890end 891 892 893define showtaskheader 894 printf "task vm_map ipc_space #acts " 895 showprocheader 896end 897 898 899define showtaskint 900 set $kgm_task = *(struct task *)$arg0 901 printf "0x%08x ", $arg0 902 printf "0x%08x ", $kgm_task.map 903 printf "0x%08x ", $kgm_task.itk_space 904 printf "%3d ", $kgm_task.thread_count 905 showprocint $kgm_task.bsd_info 906end 907 908define showtask 909 showtaskheader 910 showtaskint $arg0 911end 912document showtask 913| Routine to print out info about a task. 914| The following is the syntax: 915| (gdb) showtask <task> 916end 917 918 919define showtaskthreads 920 showtaskheader 921 set $kgm_taskp = (struct task *)$arg0 922 showtaskint $kgm_taskp 923 showactheader 924 set $kgm_head_actp = &($kgm_taskp->threads) 925 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 926 while $kgm_actp != $kgm_head_actp 927 showactint $kgm_actp 0 928 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 929 end 930end 931document showtaskthreads 932| Routine to print info about the threads in a task. 933| The following is the syntax: 934| (gdb) showtaskthreads <task> 935end 936 937 938define showtaskstacks 939 showtaskheader 940 set $kgm_taskp = (struct task *)$arg0 941 showtaskint $kgm_taskp 942 set $kgm_head_actp = &($kgm_taskp->threads) 943 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 944 while $kgm_actp != $kgm_head_actp 945 showactheader 946 showactint $kgm_actp 1 947 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 948 end 949end 950document showtaskstacks 951| Routine to print out the stack for each thread in a task. 952| The following is the syntax: 953| (gdb) showtaskstacks <task> 954end 955 956 957define showalltasks 958 showtaskheader 959 set $kgm_head_taskp = &default_pset.tasks 960 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 961 while $kgm_taskp != $kgm_head_taskp 962 showtaskint $kgm_taskp 963 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 964 end 965end 966document showalltasks 967| Routine to print a summary listing of all the tasks 968| The following is the syntax: 969| (gdb) showalltasks 970end 971 972 973define showprocheader 974 printf " pid proc command\n" 975end 976 977define showprocint 978 set $kgm_procp = (struct proc *)$arg0 979 if $kgm_procp != 0 980 printf "%5d ", $kgm_procp->p_pid 981 printf "0x%08x ", $kgm_procp 982 printf "%s\n", $kgm_procp->p_comm 983 else 984 printf " *0* 0x00000000 --\n" 985 end 986end 987 988define showpid 989 showtaskheader 990 set $kgm_head_taskp = &default_pset.tasks 991 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 992 while $kgm_taskp != $kgm_head_taskp 993 set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info 994 if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0)) 995 showtaskint $kgm_taskp 996 set $kgm_taskp = $kgm_head_taskp 997 else 998 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 999 end 1000 end
1001end 1002document showpid 1003| Routine to print a single process by pid 1004| The following is the syntax: 1005| (gdb) showpid <pid> 1006end 1007 1008define showproc 1009 showtaskheader 1010 set $kgm_procp = (struct proc *)$arg0 1011 showtaskint $kgm_procp->task $arg1 $arg2 1012end 1013 1014 1015define kdb 1016 set switch_debugger=1 1017 continue 1018end 1019document kdb 1020| kdb - Switch to the inline kernel debugger 1021| 1022| usage: kdb 1023| 1024| The kdb macro allows you to invoke the inline kernel debugger. 1025end 1026 1027define showpsetheader 1028 printf "portset waitqueue recvname " 1029 printf "flags refs recvname process\n" 1030end 1031 1032define showportheader 1033 printf "port mqueue recvname " 1034 printf "flags refs recvname process\n" 1035end 1036 1037define showportmemberheader 1038 printf "members port recvname " 1039 printf "flags refs mqueue msgcount\n" 1040end 1041 1042define showkmsgheader 1043 printf "messages kmsg size " 1044 printf "disp msgid remote-port local-port\n" 1045end 1046 1047define showkmsgint 1048 printf " 0x%08x ", $arg0 1049 set $kgm_kmsgh = ((ipc_kmsg_t)$arg0)->ikm_header 1050 printf "0x%08x ", $kgm_kmsgh.msgh_size 1051 if (($kgm_kmsgh.msgh_bits & 0xff) == 19) 1052 printf "rC" 1053 else 1054 printf "rM" 1055 end 1056 if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 < 8)) 1057 printf "lC" 1058 else 1059 printf "lM" 1060 end 1061 if ($kgm_kmsgh.msgh_bits & 0xf0000000) 1062 printf "c" 1063 else 1064 printf "s" 1065 end 1066 printf "%5d ", $kgm_kmsgh.msgh_id 1067 printf "0x%08x ", $kgm_kmsgh.msgh_remote_port 1068 printf "0x%08x\n", $kgm_kmsgh.msgh_local_port 1069end 1070 1071 1072 1073define showkobject 1074 set $kgm_portp = (struct ipc_port *)$arg0 1075 printf "0x%08x kobject(", $kgm_portp->ip_kobject 1076 set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff) 1077 if ($kgm_kotype == 1) 1078 printf "THREAD" 1079 end 1080 if ($kgm_kotype == 2) 1081 printf "TASK" 1082 end 1083 if ($kgm_kotype == 3) 1084 printf "HOST" 1085 end 1086 if ($kgm_kotype == 4) 1087 printf "HOST_PRIV" 1088 end 1089 if ($kgm_kotype == 5) 1090 printf "PROCESSOR" 1091 end 1092 if ($kgm_kotype == 6) 1093 printf "PSET" 1094 end 1095 if ($kgm_kotype == 7) 1096 printf "PSET_NAME" 1097 end 1098 if ($kgm_kotype == 8) 1099 printf "TIMER" 1100 end 1101 if ($kgm_kotype == 9) 1102 printf "PAGER_REQ" 1103 end 1104 if ($kgm_kotype == 10) 1105 printf "DEVICE" 1106 end 1107 if ($kgm_kotype == 11) 1108 printf "XMM_OBJECT" 1109 end 1110 if ($kgm_kotype == 12) 1111 printf "XMM_PAGER" 1112 end 1113 if ($kgm_kotype == 13) 1114 printf "XMM_KERNEL" 1115 end 1116 if ($kgm_kotype == 14) 1117 printf "XMM_REPLY" 1118 end 1119 if ($kgm_kotype == 15) 1120 printf "NOTDEF 15" 1121 end 1122 if ($kgm_kotype == 16) 1123 printf "NOTDEF 16" 1124 end 1125 if ($kgm_kotype == 17) 1126 printf "HOST_SEC" 1127 end 1128 if ($kgm_kotype == 18) 1129 printf "LEDGER" 1130 end 1131 if ($kgm_kotype == 19) 1132 printf "MASTER_DEV" 1133 end 1134 if ($kgm_kotype == 20) 1135 printf "ACTIVATION" 1136 end 1137 if ($kgm_kotype == 21) 1138 printf "SUBSYSTEM" 1139 end 1140 if ($kgm_kotype == 22) 1141 printf "IO_DONE_QUE" 1142 end 1143 if ($kgm_kotype == 23) 1144 printf "SEMAPHORE" 1145 end 1146 if ($kgm_kotype == 24) 1147 printf "LOCK_SET" 1148 end 1149 if ($kgm_kotype == 25) 1150 printf "CLOCK" 1151 end 1152 if ($kgm_kotype == 26) 1153 printf "CLOCK_CTRL" 1154 end 1155 if ($kgm_kotype == 27) 1156 printf "IOKIT_SPARE" 1157 end 1158 if ($kgm_kotype == 28) 1159 printf "NAMED_MEM" 1160 end 1161 if ($kgm_kotype == 29) 1162 printf "IOKIT_CON" 1163 end 1164 if ($kgm_kotype == 30) 1165 printf "IOKIT_OBJ" 1166 end 1167 if ($kgm_kotype == 31) 1168 printf "UPL" 1169 end 1170 printf ")\n" 1171end 1172 1173define showportdestproc 1174 set $kgm_portp = (struct ipc_port *)$arg0 1175 set $kgm_spacep = $kgm_portp->data.receiver 1176# check against the previous cached value - this is slow 1177 if ($kgm_spacep != $kgm_destspacep) 1178 set $kgm_destprocp = (struct proc *)0 1179 set $kgm_head_taskp = &default_pset.tasks 1180 set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next) 1181 while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp)) 1182 set $kgm_destspacep = $kgm_desttaskp->itk_space 1183 if ($kgm_destspacep == $kgm_spacep) 1184 set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info 1185 else 1186 set $kgm_desttaskp = (struct task *)($kgm_desttaskp->pset_tasks.next) 1187 end 1188 end 1189 end 1190 if $kgm_destprocp != 0 1191 printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid 1192 else 1193 printf "task 0x%08x\n", $kgm_desttaskp 1194 end 1195end 1196 1197define showportdest 1198 set $kgm_portp = (struct ipc_port *)$arg0 1199 set $kgm_spacep = $kgm_portp->data.receiver 1200 if ($kgm_spacep == ipc_space_kernel) 1201 showkobject $kgm_portp 1202 else 1203 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1204 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1205 showportdestproc $kgm_portp 1206 else 1207 printf "0x%08x inactive-port\n", $kgm_portp 1208 end 1209 end 1210end 1211 1212define showportmember 1213 printf " 0x%08x ", $arg0 1214 set $kgm_portp = (struct ipc_port *)$arg0 1215 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1216 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1217 printf "A" 1218 else 1219 printf " " 1220 end 1221 if ($kgm_portp->ip_object.io_bits & 0x7fff0000) 1222 printf "Set " 1223 else 1224 printf "Port" 1225 end 1226 printf "%5d ", $kgm_portp->ip_object.io_references 1227 printf "0x%08x ", &($kgm_portp->ip_messages) 1228 printf "0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount 1229end 1230 1231define showportint 1232 printf "0x%08x ", $arg0 1233 set $kgm_portp = (struct ipc_port *)$arg0 1234 printf "0x%08x ", &($kgm_portp->ip_messages) 1235 printf "0x%08x ", $kgm_portp->ip_object.io_receiver_name 1236 if ($kgm_portp->ip_object.io_bits & 0x80000000) 1237 printf "A" 1238 else 1239 printf "D" 1240 end 1241 printf "Port" 1242 printf "%5d ", $kgm_portp->ip_object.io_references 1243 set $kgm_destspacep = (struct ipc_space *)0 1244 showportdest $kgm_portp 1245 set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base 1246 if $arg1 && $kgm_kmsgp 1247 showkmsgheader 1248 showkmsgint $kgm_kmsgp 1249 set $kgm_kmsgheadp = $kgm_kmsgp 1250 set $kgm_kmsgp = $kgm_kmsgp->ikm_next 1251 while $kgm_kmsgp != $kgm_kmsgheadp 1252 showkmsgint $kgm_kmsgp 1253 set $kgm_kmsgp = $kgm_kmsgp->ikm_next 1254 end 1255 end 1256end 1257 1258define showpsetint 1259 printf "0x%08x ", $arg0 1260 set $kgm_psetp = (struct ipc_pset *)$arg0 1261 printf "0x%08x ", &($kgm_psetp->ips_messages) 1262 printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name 1263 if ($kgm_psetp->ips_object.io_bits & 0x80000000) 1264 printf "A" 1265 else 1266 printf "D" 1267 end 1268 printf "Set " 1269 printf "%5d ", $kgm_psetp->ips_object.io_references 1270 printf "0x%08x ", $kgm_psetp->ips_object.io_receiver_name 1271 set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.set_queue.wqs_setlinks) 1272 set $kgm_wql = (struct wait_queue_link *)$kgm_setlinksp->next 1273 set $kgm_found = 0 1274 while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp) 1275 set $kgm_portp = (struct ipc_port *)((int)($kgm_wql->wql_element->wqe_queue) - ((int)$kgm_portoff)) 1276 if !$kgm_found 1277 set $kgm_destspacep = (struct ipc_space *)0 1278 showportdestproc $kgm_portp 1279 showportmemberheader 1280 set $kgm_found = 1 1281 end 1282 showportmember $kgm_portp 0 1283 set $kgm_wql = (struct wait_queue_link *)$kgm_wql->wql_setlinks.next 1284 end 1285 if !$kgm_found 1286 printf "--n/e--\n" 1287 end 1288end 1289 1290define showpset 1291 showpsetheader 1292 showpsetint $arg0 1 1293end 1294 1295define showport 1296 showportheader 1297 showportint $arg0 1 1298end 1299 1300define showipcobject 1301 set $kgm_object = (ipc_object_t)$arg0 1302 if ($kgm_objectp->io_bits & 0x7fff0000) 1303 showpset $kgm_objectp 1304 else 1305 showport $kgm_objectp 1306 end 1307end 1308 1309define showmqueue 1310 set $kgm_mqueue = *(struct ipc_mqueue *)$arg0 1311 set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages) 1312 set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages) 1313 if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d1) 1314 set $kgm_pset = (((int)$arg0) - ((int)$kgm_psetoff)) 1315 showpsetheader 1316 showpsetint $kgm_pset 1 1317 end 1318 if ($kgm_mqueue.data.set_queue.wqs_wait_queue.wq_type == 0xf1d0) 1319 showportheader 1320 set $kgm_port = (((int)$arg0) - ((int)$kgm_portoff)) 1321 showportint $kgm_port 1 1322 end 1323end 1324 1325define zprint_one 1326set $kgm_zone = (struct zone *)$arg0 1327 1328printf "0x%08x ", $kgm_zone 1329printf "%8d ",$kgm_zone->count 1330printf "%8x ",$kgm_zone->cur_size 1331printf "%8x ",$kgm_zone->max_size 1332printf "%6d ",$kgm_zone->elem_size 1333printf "%8x ",$kgm_zone->alloc_size 1334printf "%s ",$kgm_zone->zone_name 1335 1336if ($kgm_zone->exhaustible) 1337 printf "H" 1338end 1339if ($kgm_zone->collectable) 1340 printf "C" 1341end 1342if ($kgm_zone->expandable) 1343 printf "X" 1344end 1345printf "\n" 1346end 1347 1348 1349define zprint 1350printf "ZONE COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n" 1351set $kgm_zone_ptr = (struct zone *)first_zone 1352while ($kgm_zone_ptr != 0) 1353 zprint_one $kgm_zone_ptr 1354 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone 1355end 1356printf "\n" 1357end 1358document zprint 1359| Routine to print a summary listing of all the kernel zones 1360| The following is the syntax: 1361| (gdb) zprint 1362end 1363 1364define showmtxgrp 1365set $kgm_mtxgrp = (lck_grp_t *)$arg0 1366 1367if ($kgm_mtxgrp->lck_grp_mtxcnt) 1368printf "0x%08x ", $kgm_mtxgrp 1369printf "%8d ",$kgm_mtxgrp->lck_grp_mtxcnt 1370printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt 1371printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt 1372printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt 1373printf "%s ",&$kgm_mtxgrp->lck_grp_name 1374printf "\n" 1375end 1376end 1377 1378 1379define showallmtx 1380printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" 1381set $kgm_mtxgrp_ptr = (lck_grp_t *)&lck_grp_queue 1382set $kgm_mtxgrp_ptr = (lck_grp_t *)$kgm_mtxgrp_ptr->lck_grp_link.next 1383while ($kgm_mtxgrp_ptr != (lck_grp_t *)&lck_grp_queue) 1384 showmtxgrp $kgm_mtxgrp_ptr 1385 set $kgm_mtxgrp_ptr = (lck_grp_t *)$kgm_mtxgrp_ptr->lck_grp_link.next 1386end 1387printf "\n" 1388end 1389document showallmtx 1390| Routine to print a summary listing of all mutexes 1391| The following is the syntax: 1392| (gdb) showallmtx 1393end 1394 1395define showrwlckgrp 1396set $kgm_rwlckgrp = (lck_grp_t *)$arg0 1397 1398if ($kgm_rwlckgrp->lck_grp_rwcnt) 1399printf "0x%08x ", $kgm_rwlckgrp 1400printf "%8d ",$kgm_rwlckgrp->lck_grp_rwcnt 1401printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt 1402printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt 1403printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt 1404printf "%s ",&$kgm_rwlckgrp->lck_grp_name 1405printf "\n" 1406end 1407end 1408 1409 1410define showallrwlck 1411printf "LCK GROUP CNT UTIL MISS WAIT NAME\n" 1412set $kgm_rwlckgrp_ptr = (lck_grp_t *)&lck_grp_queue 1413set $kgm_rwlckgrp_ptr = (lck_grp_t *)$kgm_rwlckgrp_ptr->lck_grp_link.next 1414while ($kgm_rwlckgrp_ptr != (lck_grp_t *)&lck_grp_queue) 1415 showrwlckgrp $kgm_rwlckgrp_ptr 1416 set $kgm_rwlckgrp_ptr = (lck_grp_t *)$kgm_rwlckgrp_ptr->lck_grp_link.next 1417end 1418printf "\n" 1419end 1420document showallrwlck 1421| Routine to print a summary listing of all read/writer locks 1422| The following is the syntax: 1423| (gdb) showallrwlck 1424end 1425 1426set $kdp_act_counter = 0 1427 1428define switchtoact 1429 if ($kgm_mtype == 18) 1430 if ($kdp_act_counter == 0) 1431 set $kdpstate = (struct savearea *) kdp.saved_state 1432 end 1433 set $kdp_act_counter = $kdp_act_counter + 1 1434 set $newact = (struct thread *) $arg0 1435 if ($newact->kernel_stack == 0) 1436 echo This activation does not have a stack.\n 1437 echo continuation: 1438 output/a (unsigned) $newact.continuation 1439 echo \n 1440 else 1441 set (struct savearea *) kdp.saved_state=$newact->machine->pcb 1442 flush 1443 set $pc=$newact->machine->pcb.save_srr0 1444 update 1445 end 1446 else 1447 echo switchtoact not implemented for this architecture.\n 1448 end 1449end 1450 1451document switchtoact 1452Syntax: switchtoact <address of activation> 1453| This command allows gdb to examine the execution context and call 1454| stack for the specified activation. For example, to view the backtrace 1455| for an activation issue "switchtoact <address>", followed by "bt". 1456| Before resuming execution, issue a "resetctx" command, to 1457| return to the original execution context. 1458end 1459 1460define switchtoctx 1461 if ($kgm_mtype == 18) 1462 if ($kdp_act_counter == 0) 1463 set $kdpstate = (struct savearea *) kdp.saved_state 1464 end 1465 set $kdp_act_counter = $kdp_act_counter + 1 1466 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0 1467 flush 1468 set $pc=((struct savearea *) $arg0)->save_srr0 1469 update 1470 else 1471 echo switchtoctx not implemented for this architecture.\n 1472 end 1473end 1474 1475document switchtoctx 1476Syntax: switchtoctx <address of pcb> 1477| This command allows gdb to examine an execution context and dump the 1478| backtrace for this execution context. 1479| Before resuming execution, issue a "resetctx" command, to 1480| return to the original execution context. 1481end 1482 1483define resetctx 1484 if ($kgm_mtype == 18) 1485 set (struct savearea *)kdp.saved_state=$kdpstate 1486 flush 1487 set $pc=((struct savearea *) kdp.saved_state)->save_srr0 1488 update 1489 set $kdp_act_counter = 0 1490 else 1491 echo resetctx not implemented for this architecture.\n 1492 end 1493end 1494 1495document resetctx 1496| Syntax: resetctx 1497| Returns to the original execution context. This command should be 1498| issued if you wish to resume execution after using the "switchtoact" 1499| or "switchtoctx" commands. 1500end 1501 1502define resume_on 1503 set noresume_on_disconnect = 0 1504end 1505 1506document resume_on 1507| Syntax: resume_on 1508| The target system will resume when detaching or exiting from gdb. 1509| This is the default behavior. 1510end 1511 1512define resume_off 1513 set noresume_on_disconnect = 1 1514end 1515 1516document resume_off 1517| Syntax: resume_off 1518| The target system won't resume after detaching from gdb and 1519| can be attached with a new gdb session 1520end 1521 1522define paniclog 1523 set $kgm_panic_bufptr = debug_buf 1524 set $kgm_panic_bufptr_max = debug_buf_ptr 1525 while $kgm_panic_bufptr < $kgm_panic_bufptr_max 1526 if *(char *)$kgm_panic_bufptr == 10 1527 printf "\n" 1528 else 1529 printf "%c", *$kgm_panic_bufptr 1530 end 1531 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1 1532 end 1533end 1534 1535document paniclog 1536| Syntax: paniclog 1537| Display the panic log information 1538| 1539end 1540 1541define dumpcallqueue 1542 set $kgm_callhead = (queue_t)&$arg0 1543 set $kgm_call = (struct call_entry *)$kgm_callhead.next 1544 set $kgm_i = 0 1545 while $kgm_call != $kgm_callhead 1546 printf "0x%08x ", $kgm_call 1547 printf "0x%08x 0x%08x ", $kgm_call->param0, $kgm_call->param1 1548 output $kgm_call->state 1549 printf "\t" 1550 output $kgm_call->deadline 1551 printf "\t" 1552 output $kgm_call->func 1553 printf "\n" 1554 set $kgm_i = $kgm_i + 1 1555 set $kgm_call = (struct call_entry *)$kgm_call->q_link.next 1556 end 1557 printf "%d entries\n", $kgm_i 1558end 1559 1560document dumpcallqueue 1561| Syntax: dumpcallqueue <queue head> 1562| Displays the contents of the specified call_entry queue. 1563end 1564 1565define showtaskacts 1566showtaskthreads $arg0 1567end 1568document showtaskacts 1569| See help showtaskthreads. 1570end 1571 1572define showallacts 1573showallthreads 1574end 1575document showallacts 1576| See help showallthreads. 1577end 1578 1579 1580define resetstacks 1581 _kgm_flush_loop 1582 set kdp_pmap = 0 1583 _kgm_flush_loop 1584 resetctx 1585 _kgm_flush_loop 1586 _kgm_update_loop 1587 resetctx 1588 _kgm_update_loop 1589end 1590 1591document resetstacks 1592| Syntax: resetstacks 1593| Internal kgmacro routine used by the "showuserstack" macro 1594| to reset the target pmap to the kernel pmap. 1595end 1596 1597#Barely effective hacks to work around bugs in the "flush" and "update" 1598#gdb commands in Tiger (up to 219); these aren't necessary with Panther 1599#gdb, but do no harm. 1600define _kgm_flush_loop 1601 set $kgm_flush_loop_ctr = 0 1602 while ($kgm_flush_loop_ctr < 30) 1603 flush 1604 set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1 1605 end 1606end 1607 1608define _kgm_update_loop 1609 set $kgm_update_loop_ctr = 0 1610 while ($kgm_update_loop_ctr < 30) 1611 update 1612 set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1 1613 end 1614end 1615 1616define showuserstack 1617 if ($kgm_mtype == 18) 1618 if ($kdp_act_counter == 0) 1619 set $kdpstate = (struct savearea *) kdp.saved_state 1620 end 1621 set $kdp_act_counter = $kdp_act_counter + 1 1622 set $newact = (struct thread *) $arg0 1623 _kgm_flush_loop 1624 set $checkpc = $newact->machine->upcb.save_srr0 1625 if ($checkpc == 0) 1626 echo This activation does not appear to have 1627 echo \20 a valid user context.\n 1628 else 1629 set (struct savearea *) kdp.saved_state=$newact->machine->upcb 1630 set $pc = $checkpc 1631#flush and update seem to be executed lazily by gdb on Tiger, hence the 1632#repeated invocations - see 3743135 1633 _kgm_flush_loop 1634# This works because the new pmap is used only for reads 1635 set kdp_pmap = $newact->task->map->pmap 1636 _kgm_flush_loop 1637 _kgm_update_loop 1638 bt 1639 resetstacks 1640 _kgm_flush_loop 1641 _kgm_update_loop 1642 resetstacks 1643 _kgm_flush_loop 1644 _kgm_update_loop 1645 end 1646 else 1647 echo showuserstack not implemented for this architecture.\n 1648 end 1649end 1650 1651document showuserstack 1652Syntax: showuserstack <address of thread activation> 1653|This command displays a numeric backtrace for the user space stack of 1654|the given thread activation. It may, of course, fail to display a 1655|complete backtrace if portions of the user stack are not mapped in. 1656|Symbolic backtraces can be obtained either by running gdb on the 1657|user space binary, or a tool such as "symbolicate". 1658|Note that while this command works on Panther's gdb, an issue 1659|with Tiger gdb (3743135) appears to hamper the evaluation of this 1660|macro in some cases. 1661end 1662 1663#Stopgap until gdb can generate the HOSTREBOOT packet 1664define kdp-reboot 1665 set flag_kdp_trigger_reboot = 1 1666 continue 1667end 1668 1669document kdp-reboot 1670Syntax: kdp-reboot 1671|Reboot the remote target machine; not guaranteed to succeed. Requires symbols 1672|until gdb support for the HOSTREBOOT packet is implemented. 1673end 1674 1675define sendcore 1676 set kdp_trigger_core_dump = 1 1677 set kdp_flag |= 0x40 1678 set panicd_ip_str = "$arg0" 1679 set panicd_specified = 1 1680 set disableDebugOuput = 0 1681 set disableConsoleOutput = 0 1682 set logPanicDataToScreen = 1 1683 set reattach_wait = 1 1684 resume_off 1685end 1686 1687document sendcore 1688Syntax: sendcore <IP address> 1689|Configure the kernel to transmit a kernel coredump to a server (kdumpd) 1690|at the specified IP address. This is useful when the remote target has 1691|not been previously configured to transmit coredumps, and you wish to 1692|preserve kernel state for later examination. NOTE: You must issue a "continue" 1693|command after using this macro to trigger the kernel coredump. The kernel 1694|will resume waiting in the debugger after completion of the coredump. You 1695|may disable coredumps by executing the "disablecore" macro. 1696end 1697 1698define disablecore 1699 set kdp_trigger_core_dump = 0 1700 set kdp_flag |= 0x40 1701 set kdp_flag &= ~0x10 1702 set panicd_specified = 0 1703end 1704 1705document disablecore 1706Syntax: disablecore 1707|Reconfigures the kernel so that it no longer transmits kernel coredumps. This 1708|complements the "sendcore" macro, but it may be used if the kernel has been 1709|configured to transmit coredumps through boot-args as well. 1710end 1711 1712#Use of this macro requires the gdb submission from 3401283 1713define switchtocorethread 1714 if ($kgm_mtype == 18) 1715 if ($kdp_act_counter == 0) 1716 set $kdpstate = (struct savearea *) kdp.saved_state 1717 end 1718 set $kdp_act_counter = $kdp_act_counter + 1 1719 set $newact = (struct thread *) $arg0 1720 if ($newact->kernel_stack == 0) 1721 echo This thread does not have a stack.\n 1722 echo continuation: 1723 output/a (unsigned) $newact.continuation 1724 echo \n 1725 else 1726 loadcontext $newact->machine->pcb 1727# flushstack will be introduced in a gdb version > gdb-357 1728 flushstack 1729 set $pc = $newact->machine->pcb.save_srr0 1730 end 1731 else 1732 echo switchtocorethread not implemented for this architecture.\n 1733 end 1734end 1735 1736document switchtocorethread 1737Syntax: switchtocorethread <address of activation> 1738| The corefile equivalent of "switchtoact". When debugging a kernel coredump 1739| file, this command can be used to examine the execution context and stack 1740| trace for a given thread activation. For example, to view the backtrace 1741| for a thread issue "switchtocorethread <address>", followed by "bt". 1742| Before resuming execution, issue a "resetcorectx" command, to 1743| return to the original execution context. Note that this command 1744| requires gdb support, as documented in Radar 3401283. 1745end 1746 1747define loadcontext 1748 set $pc = $arg0.save_srr0 1749 set $r1 = $arg0.save_r1 1750 set $lr = $arg0.save_lr 1751 1752 set $r2 = $arg0.save_r2 1753 set $r3 = $arg0.save_r3 1754 set $r4 = $arg0.save_r4 1755 set $r5 = $arg0.save_r5 1756 set $r6 = $arg0.save_r6 1757 set $r7 = $arg0.save_r7 1758 set $r8 = $arg0.save_r8 1759 set $r9 = $arg0.save_r9 1760 set $r10 = $arg0.save_r10 1761 set $r11 = $arg0.save_r11 1762 set $r12 = $arg0.save_r12 1763 set $r13 = $arg0.save_r13 1764 set $r14 = $arg0.save_r14 1765 set $r15 = $arg0.save_r15 1766 set $r16 = $arg0.save_r16 1767 set $r17 = $arg0.save_r17 1768 set $r18 = $arg0.save_r18 1769 set $r19 = $arg0.save_r19 1770 set $r20 = $arg0.save_r20 1771 set $r21 = $arg0.save_r21 1772 set $r22 = $arg0.save_r22 1773 set $r23 = $arg0.save_r23 1774 set $r24 = $arg0.save_r24 1775 set $r25 = $arg0.save_r25 1776 set $r26 = $arg0.save_r26 1777 set $r27 = $arg0.save_r27 1778 set $r28 = $arg0.save_r28 1779 set $r29 = $arg0.save_r29 1780 set $r30 = $arg0.save_r30 1781 set $r31 = $arg0.save_r31 1782 1783 set $cr = $arg0.save_cr 1784 set $ctr = $arg0.save_ctr 1785end 1786 1787define resetcorectx 1788 set $kgm_corecontext = (struct savearea *) kdp.saved_state 1789 loadcontext $kgm_corecontext 1790# Maintaining this act counter wouldn't be necessary if we just initialized 1791# $kdpstate at the beginning of the macro.. 1792 set $kdp_act_counter = 0 1793end 1794 1795document resetcorectx 1796Syntax: resetcorectx 1797| The corefile equivalent of "resetctx". Returns to the original 1798| execution context (that of the active thread at the time of the NMI or 1799| panic). This command should be issued if you wish to resume 1800| execution after using the "switchtocorethread" command. 1801end 1802 1803#Helper function for "showallgdbstacks" 1804 1805define showgdbthread 1806 printf " 0x%08x ", $arg0 1807 set $kgm_thread = *(struct thread *)$arg0 1808 printf "0x%08x ", $arg0 1809 printf "%3d ", $kgm_thread.sched_pri 1810 set $kgm_state = $kgm_thread.state 1811 if $kgm_state & 0x80 1812 printf "I" 1813 end 1814 if $kgm_state & 0x40 1815 printf "P" 1816 end 1817 if $kgm_state & 0x20 1818 printf "A" 1819 end 1820 if $kgm_state & 0x10 1821 printf "H" 1822 end 1823 if $kgm_state & 0x08 1824 printf "U" 1825 end 1826 if $kgm_state & 0x04 1827 printf "R" 1828 end 1829 if $kgm_state & 0x02 1830 printf "S" 1831 end 1832 if $kgm_state & 0x01 1833 printf "W\t" 1834 printf "0x%08x ", $kgm_thread.wait_queue 1835 output /a (unsigned) $kgm_thread.wait_event 1836 end 1837 if $arg1 != 0 1838 if ($kgm_thread.kernel_stack != 0) 1839 if ($kgm_thread.reserved_stack != 0) 1840 printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack 1841 end 1842 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack 1843 if ($kgm_mtype == 18) 1844 set $mysp = $kgm_thread.machine.pcb->save_r1 1845 else 1846 set $kgm_statep = (struct i386_kernel_state *) \ 1847 ($kgm_thread->kernel_stack + 0x4000 \ 1848 - sizeof(struct i386_kernel_state)) 1849 set $mysp = $kgm_statep->k_ebp 1850 end 1851 set $prevsp = 0 1852 printf "\n\t\tstacktop=0x%08x", $mysp 1853 switchtoact $arg0 1854 bt 1855 else 1856 printf "\n\t\t\tcontinuation=" 1857 output /a (unsigned) $kgm_thread.continuation 1858 end 1859 printf "\n" 1860 else 1861 printf "\n" 1862 end 1863end 1864 1865#Use of this macro is currently (8/04) blocked by the fact that gdb 1866#stops evaluating macros when encountering an error, such as a failure 1867#to read memory from a certain location. Until this issue (described in 1868#3758949) is addressed, evaluation of this macro may stop upon 1869#encountering such an error. 1870 1871define showallgdbstacks 1872 set $kgm_head_taskp = &default_pset.tasks 1873 set $kgm_taskp = (struct task *)($kgm_head_taskp->next) 1874 while $kgm_taskp != $kgm_head_taskp 1875 showtaskheader 1876 showtaskint $kgm_taskp 1877 set $kgm_head_actp = &($kgm_taskp->threads) 1878 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next) 1879 while $kgm_actp != $kgm_head_actp 1880 showactheader 1881 showgdbthread $kgm_actp 1 1882 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next) 1883 end 1884 printf "\n" 1885 set $kgm_taskp = (struct task *)($kgm_taskp->pset_tasks.next) 1886 end 1887 resetctx 1888end 1889 1890document showallgdbstacks 1891Syntax: showallgdbstacks 1892| An alternative to "showallstacks". Iterates through the task list and 1893| displays a gdb generated backtrace for each kernel thread. It is 1894| advantageous in that it is much faster than "showallstacks", and 1895| decodes function call arguments and displays source level traces, but 1896| it has the drawback that it doesn't determine if frames belong to 1897| functions from kernel extensions, as with "showallstacks". 1898| This command may terminate prematurely because of a gdb bug 1899| (Radar 3758949), which stops macro evaluation on memory read 1900| errors. 1901end 1902 1903define switchtouserthread 1904 if ($kgm_mtype == 18) 1905 if ($kdp_act_counter == 0) 1906 set $kdpstate = (struct savearea *) kdp.saved_state 1907 end 1908 set $kdp_act_counter = $kdp_act_counter + 1 1909 set $newact = (struct thread *) $arg0 1910 _kgm_flush_loop 1911 set $checkpc = $newact->machine->upcb.save_srr0 1912 if ($checkpc == 0) 1913 echo This activation does not appear to have 1914 echo \20 a valid user context.\n 1915 else 1916 set (struct savearea *) kdp.saved_state=$newact->machine->upcb 1917 set $pc = $checkpc 1918#flush and update seem to be executed lazily by gdb on Tiger, hence the 1919#repeated invocations - see 3743135 1920 _kgm_flush_loop 1921# This works because the new pmap is used only for reads 1922 set kdp_pmap = $newact->task->map->pmap 1923 _kgm_flush_loop 1924 _kgm_update_loop 1925 end 1926 else 1927 echo switchtouserthread not implemented for this architecture.\n 1928 end 1929end 1930 1931document switchtouserthread 1932Syntax: switchtouserthread <address of thread> 1933| Analogous to switchtoact, but switches to the user context of a 1934| specified thread address. Similar to the "showuserstack" 1935| command, but this command does not return gdb to the kernel context 1936| immediately. This is to assist with the following (rather risky) 1937| manoeuvre - upon switching to the user context and virtual address 1938| space, the user may choose to call remove-symbol-file on the 1939| mach_kernel symbol file, and then add-symbol-file on the user space 1940| binary's symfile. gdb can then generate symbolic backtraces 1941| for the user space thread. To return to the 1942| kernel context and virtual address space, the process must be 1943| reversed, i.e. call remove-symbol-file on the user space symbols, and 1944| then add-symbol-file on the appropriate mach_kernel, and issue the 1945| "resetstacks" command. Note that gdb may not react kindly to all these 1946| symbol file switches. The same restrictions that apply to "showuserstack" 1947| apply here - pages that have been paged out cannot be read while in the 1948| debugger context, so backtraces may terminate early. 1949| If the virtual addresses in the stack trace do not conflict with those 1950| of symbols in the kernel's address space, it may be sufficient to 1951| just do an add-symbol-file on the user space binary's symbol file. 1952| Note that while this command works on Panther's gdb, an issue 1953| with Tiger gdb (3743135) appears to hamper the evaluation of this 1954| macro in some cases. 1955end 1956 1957define showmetaclass 1958 set cp-abi gnu-v2 1959 set $kgm_metaclassp = (OSMetaClass *)$arg0 1960 printf "%-5d", $kgm_metaclassp->instanceCount 1961 printf "x %5d bytes", $kgm_metaclassp->classSize 1962 printf " %s\n", $kgm_metaclassp->className->string 1963end 1964 1965define showallclasses 1966 set cp-abi gnu-v2 1967 set $kgm_classidx = 0 1968 while $kgm_classidx < sAllClassesDict->count 1969 set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value 1970 showmetaclass $kgm_meta 1971 set $kgm_classidx = $kgm_classidx + 1 1972 end 1973end 1974document showallclasses 1975| Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details. 1976| The following is the syntax: 1977| (gdb) showallclasses 1978end 1979 1980define showioalloc 1981 printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024 1982 printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024 1983 printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024 1984 printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024 1985end 1986 1987document showioalloc 1988| Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details. 1989| The following is the syntax: 1990| (gdb) showioalloc 1991end 1992

