]> git.saurik.com Git - apple/xnu.git/blob - kgmacros
xnu-1228.15.4.tar.gz
[apple/xnu.git] / kgmacros
1 # Kernel gdb macros
2 #
3 # These gdb macros should be useful during kernel development in
4 # determining what's going on in the kernel.
5 #
6 # All the convenience variables used by these macros begin with $kgm_
7
8 set print asm-demangle on
9 set cp-abi gnu-v2
10
11 echo Loading Kernel GDB Macros package. Type "help kgm" for more info.\n
12
13 define kgm
14 printf ""
15 echo These are the gdb macros for kernel debugging. Type "help kgm" for more info.\n
16 end
17
18 document 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.
169 end
170
171 # This macro should appear before any symbol references, to facilitate
172 # a gdb "source" without a loaded symbol file.
173 define showversion
174 printf "%s\n", *(char **)0x501C
175 end
176
177 document showversion
178 Syntax: 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.
186 end
187
188 set $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
194 if ($kgm_mtype != 12)
195 set backtrace sanity-checks off
196 end
197
198 set $kgm_dummy = &proc0
199 set $kgm_dummy = &kmod
200
201 set $kgm_reg_depth = 0
202 set $kgm_reg_plane = (void **) gIOServicePlane
203 set $kgm_namekey = (OSSymbol *) 0
204 set $kgm_childkey = (OSSymbol *) 0
205
206 set $kgm_show_object_addrs = 0
207 set $kgm_show_object_retain = 0
208 set $kgm_show_props = 0
209
210 set $kgm_show_kmod_syms = 0
211
212 define showkmodheader
213 printf "kmod address size "
214 printf "id refs version name\n"
215 end
216
217 define 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
226 end
227
228 set $kgm_kmodmin = 0xffffffff
229 set $kgm_fkmodmin = 0x00000000
230 set $kgm_kmodmax = 0x00000000
231 set $kgm_fkmodmax = 0xffffffff
232 set $kgm_pkmod = 0
233 set $kgm_pkmodst = 0
234 set $kgm_pkmoden = 0
235 define 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
268 end
269
270 define showkmodaddr
271 showkmodaddrint $arg0
272 end
273
274 document showkmodaddr
275 Syntax: (gdb) showkmodaddr <addr>
276 | Given an address, print the offset and name for the kmod containing it
277 end
278
279 define showkmod
280 showkmodheader
281 showkmodint $arg0
282 end
283 document showkmod
284 Syntax: (gdb) showkmod <kmod>
285 | Routine to print info about a kernel module
286 end
287
288 define 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
295 end
296 document showallkmods
297 Syntax: (gdb) showallkmods
298 | Routine to print a summary listing of all the kernel modules
299 end
300
301 define showactheader
302 printf " thread "
303 printf "processor pri state wait_queue wait_event\n"
304 end
305
306
307 define 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
415 end
416
417 define showact
418 showactheader
419 showactint $arg0 0
420 end
421 document showact
422 Syntax: (gdb) showact <activation>
423 | Routine to print out the state of a specific thread.
424 end
425
426
427 define showactstack
428 showactheader
429 showactint $arg0 1
430 end
431 document showactstack
432 Syntax: (gdb) showactstack <activation>
433 | Routine to print out the stack of a specific thread.
434 end
435
436
437 define 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
453 end
454 document showallthreads
455 Syntax: (gdb) showallthreads
456 | Routine to print out info about all threads in the system.
457 end
458
459 define showcurrentthreads
460 set $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
473 end
474 document showcurrentthreads
475 Syntax: (gdb) showcurrentthreads
476 | Routine to print out info about the thread running on each cpu.
477 end
478
479 set $decode_wait_events = 0
480 define 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
500 end
501
502 document showallstacks
503 Syntax: (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.
508 end
509
510 define showcurrentstacks
511 set $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
524 end
525
526 document showcurrentstacks
527 Syntax: (gdb) showcurrentstacks
528 | Routine to print out the thread running on each cpu (incl. its stack)
529 end
530
531 define showwaiterheader
532 printf "waiters activation "
533 printf "thread pri state wait_queue wait_event\n"
534 end
535
536 define 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
552 end
553
554 define 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
566 end
567
568 define 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
578 end
579
580
581 define showwaitqmemberheader
582 printf "set-members wait_queue interlock "
583 printf "pol type member_cnt waiter_cnt\n"
584 end
585
586 define 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"
603 end
604
605
606 define showwaitqmemberofheader
607 printf "member-of wait_queue interlock "
608 printf "pol type member_cnt waiter_cnt\n"
609 end
610
611 define 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
628 end
629
630 define 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
644 end
645
646 define showwaitqheader
647 printf "wait_queue ref_count interlock "
648 printf "pol type member_cnt waiter_cnt\n"
649 end
650
651 define 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"
673 end
674
675 define 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
685 end
686
687 define showmapheader
688 printf "vm_map pmap vm_size "
689 printf "#ents rpage hint first_free\n"
690 end
691
692 define showvmeheader
693 printf " entry start "
694 printf " prot #page object offset\n"
695 end
696
697 define 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"
749 end
750
751
752 define showmapvme
753 showmapheader
754 showvmint $arg0 1
755 end
756 document showmapvme
757 Syntax: (gdb) showmapvme <vm_map>
758 | Routine to print out a summary listing of all the entries in a vm_map
759 end
760
761
762 define showmap
763 showmapheader
764 showvmint $arg0 0
765 end
766 document showmap
767 Syntax: (gdb) showmap <vm_map>
768 | Routine to print out info about the specified vm_map
769 end
770
771 define 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
781 end
782 document showallvm
783 Syntax: (gdb) showallvm
784 | Routine to print a summary listing of all the vm maps
785 end
786
787
788 define 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
798 end
799 document showallvme
800 Syntax: (gdb) showallvme
801 | Routine to print a summary listing of all the vm map entries
802 end
803
804
805 define showipcheader
806 printf "ipc_space is_table table_next "
807 printf "flags tsize splaytree splaybase\n"
808 end
809
810 define showipceheader
811 printf " name object "
812 printf "rite urefs destname destination\n"
813 end
814
815 define 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
855 end
856
857 define 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"
900 end
901
902
903 define showipc
904 set $kgm_isp = (ipc_space_t)$arg0
905 showipcheader
906 showipcint $kgm_isp 0
907 end
908 document showipc
909 Syntax: (gdb) showipc <ipc_space>
910 | Routine to print the status of the specified ipc space
911 end
912
913 define showrights
914 set $kgm_isp = (ipc_space_t)$arg0
915 showipcheader
916 showipcint $kgm_isp 1
917 end
918 document showrights
919 Syntax: (gdb) showrights <ipc_space>
920 | Routine to print a summary list of all the rights in a specified ipc space
921 end
922
923
924 define showtaskipc
925 set $kgm_taskp = (task_t)$arg0
926 showtaskheader
927 showipcheader
928 showtaskint $kgm_taskp
929 showipcint $kgm_taskp->itk_space 0
930 end
931 document showtaskipc
932 Syntax: (gdb) showtaskipc <task>
933 | Routine to print info about the ipc space for a task
934 end
935
936
937 define showtaskrights
938 set $kgm_taskp = (task_t)$arg0
939 showtaskheader
940 showipcheader
941 showtaskint $kgm_taskp
942 showipcint $kgm_taskp->itk_space 1
943 end
944 document showtaskrights
945 Syntax: (gdb) showtaskrights <task>
946 | Routine to print info about the ipc rights for a task
947 end
948
949 define 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
959 end
960 document showallipc
961 Syntax: (gdb) showallipc
962 | Routine to print a summary listing of all the ipc spaces
963 end
964
965
966 define 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
976 end
977 document showallrights
978 Syntax: (gdb) showallrights
979 | Routine to print a summary listing of all the ipc rights
980 end
981
982
983 define showtaskvm
984 set $kgm_taskp = (task_t)$arg0
985 showtaskheader
986 showmapheader
987 showtaskint $kgm_taskp
988 showvmint $kgm_taskp->map 0
989 end
990 document showtaskvm
991 Syntax: (gdb) showtaskvm <task>
992 | Routine to print out info about a task's vm_map
993 end
994
995 define showtaskvme
996 set $kgm_taskp = (task_t)$arg0
997 showtaskheader
998 showmapheader
999 showtaskint $kgm_taskp
1000 showvmint $kgm_taskp->map 1
1001 end
1002 document showtaskvme
1003 Syntax: (gdb) showtaskvme <task>
1004 | Routine to print out info about a task's vm_map_entries
1005 end
1006
1007
1008 define showtaskheader
1009 printf "task vm_map ipc_space #acts "
1010 showprocheader
1011 end
1012
1013
1014 define 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
1021 end
1022
1023 define showtask
1024 showtaskheader
1025 showtaskint $arg0
1026 end
1027 document showtask
1028 Syntax (gdb) showtask <task>
1029 | Routine to print out info about a task.
1030 end
1031
1032
1033 define 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
1044 end
1045 document showtaskthreads
1046 Syntax: (gdb) showtaskthreads <task>
1047 | Routine to print info about the threads in a task.
1048 end
1049
1050
1051 define 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
1062 end
1063 document showtaskstacks
1064 Syntax: (gdb) showtaskstacks <task>
1065 | Routine to print out the stack for each thread in a task.
1066 end
1067
1068
1069 define 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
1077 end
1078 document showalltasks
1079 Syntax: (gdb) showalltasks
1080 | Routine to print a summary listing of all the tasks
1081 end
1082
1083
1084 define showprocheader
1085 printf " pid proc command\n"
1086 end
1087
1088 define 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
1097 end
1098
1099 define 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
1112 end
1113 document showpid
1114 Syntax: (gdb) showpid <pid>
1115 | Routine to print a single process by pid
1116 end
1117
1118 define showproc
1119 showtaskheader
1120 set $kgm_procp = (struct proc *)$arg0
1121 showtaskint $kgm_procp->task $arg1 $arg2
1122 end
1123
1124
1125 define kdb
1126 set switch_debugger=1
1127 continue
1128 end
1129 document 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.
1135 end
1136
1137 define showpsetheader
1138 printf "portset waitqueue recvname "
1139 printf "flags refs recvname process\n"
1140 end
1141
1142 define showportheader
1143 printf "port mqueue recvname "
1144 printf "flags refs recvname process\n"
1145 end
1146
1147 define showportmemberheader
1148 printf "members port recvname "
1149 printf "flags refs mqueue msgcount\n"
1150 end
1151
1152 define showkmsgheader
1153 printf "messages kmsg size "
1154 printf "disp msgid remote-port local-port\n"
1155 end
1156
1157 define 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
1179 end
1180
1181
1182
1183 define 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"
1281 end
1282
1283 define 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
1305 end
1306
1307 define 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
1320 end
1321
1322 define 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
1339 end
1340
1341 define 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
1366 end
1367
1368 define 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
1398 end
1399
1400 define showpset
1401 showpsetheader
1402 showpsetint $arg0 1
1403 end
1404
1405 define showport
1406 showportheader
1407 showportint $arg0 1
1408 end
1409
1410 define 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
1417 end
1418
1419 define 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
1433 end
1434
1435 define zprint_one
1436 set $kgm_zone = (struct zone *)$arg0
1437
1438 printf "0x%08x ", $kgm_zone
1439 printf "%8d ",$kgm_zone->count
1440 printf "%8x ",$kgm_zone->cur_size
1441 printf "%8x ",$kgm_zone->max_size
1442 printf "%6d ",$kgm_zone->elem_size
1443 printf "%8x ",$kgm_zone->alloc_size
1444 printf "%s ",$kgm_zone->zone_name
1445
1446 if ($kgm_zone->exhaustible)
1447 printf "H"
1448 end
1449 if ($kgm_zone->collectable)
1450 printf "C"
1451 end
1452 if ($kgm_zone->expandable)
1453 printf "X"
1454 end
1455 printf "\n"
1456 end
1457
1458
1459 define zprint
1460 printf "ZONE COUNT TOT_SZ MAX_SZ ELT_SZ ALLOC_SZ NAME\n"
1461 set $kgm_zone_ptr = (struct zone *)first_zone
1462 while ($kgm_zone_ptr != 0)
1463 zprint_one $kgm_zone_ptr
1464 set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
1465 end
1466 printf "\n"
1467 end
1468 document zprint
1469 Syntax: (gdb) zprint
1470 | Routine to print a summary listing of all the kernel zones
1471 end
1472
1473 define showmtxgrp
1474 set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0
1475
1476 if ($kgm_mtxgrp->lck_grp_mtxcnt)
1477 printf "0x%08x ", $kgm_mtxgrp
1478 printf "%8d ",$kgm_mtxgrp->lck_grp_mtxcnt
1479 printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
1480 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
1481 printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
1482 printf "%s ",&$kgm_mtxgrp->lck_grp_name
1483 printf "\n"
1484 end
1485 end
1486
1487
1488 define showallmtx
1489 printf "LCK GROUP CNT UTIL MISS WAIT NAME\n"
1490 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1491 set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
1492 while ($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
1495 end
1496 printf "\n"
1497 end
1498 document showallmtx
1499 Syntax: (gdb) showallmtx
1500 | Routine to print a summary listing of all mutexes
1501 end
1502
1503 define showrwlckgrp
1504 set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0
1505
1506 if ($kgm_rwlckgrp->lck_grp_rwcnt)
1507 printf "0x%08x ", $kgm_rwlckgrp
1508 printf "%8d ",$kgm_rwlckgrp->lck_grp_rwcnt
1509 printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
1510 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
1511 printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
1512 printf "%s ",&$kgm_rwlckgrp->lck_grp_name
1513 printf "\n"
1514 end
1515 end
1516
1517
1518 define showallrwlck
1519 printf "LCK GROUP CNT UTIL MISS WAIT NAME\n"
1520 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
1521 set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
1522 while ($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
1525 end
1526 printf "\n"
1527 end
1528 document showallrwlck
1529 Syntax: (gdb) showallrwlck
1530 | Routine to print a summary listing of all read/writer locks
1531 end
1532
1533 set $kdp_act_counter = 0
1534
1535 set $r0_save = 0
1536 set $r1_save = 0
1537 set $r2_save = 0
1538 set $r3_save = 0
1539 set $r4_save = 0
1540 set $r5_save = 0
1541 set $r6_save = 0
1542 set $r7_save = 0
1543 set $r8_save = 0
1544 set $r9_save = 0
1545 set $r10_save = 0
1546 set $r11_save = 0
1547 set $r12_save = 0
1548 set $sp_save = 0
1549 set $lr_save = 0
1550 set $pc_save = 0
1551
1552 define showcontext_int
1553 echo Context switched, current instruction pointer:
1554 output/a $pc
1555 echo \n
1556 end
1557
1558 define 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
1638 end
1639
1640 document switchtoact
1641 Syntax: 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.
1647 end
1648
1649 define 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
1702 end
1703
1704 document switchtoctx
1705 Syntax: 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.
1710 end
1711
1712 define 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
1768 end
1769
1770 document 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.
1775 end
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.
1779 define hook-continue
1780 resetctx
1781 end
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.
1785 define hook-detach
1786 resetctx
1787 end
1788
1789 define resume_on
1790 set noresume_on_disconnect = 0
1791 end
1792
1793 document resume_on
1794 | Syntax: resume_on
1795 | The target system will resume when detaching or exiting from gdb.
1796 | This is the default behavior.
1797 end
1798
1799 define resume_off
1800 set noresume_on_disconnect = 1
1801 end
1802
1803 document 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
1807 end
1808
1809 define 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
1820 end
1821
1822 document paniclog
1823 | Syntax: paniclog
1824 | Display the panic log information
1825 |
1826 end
1827
1828 define 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
1845 end
1846
1847 document dumpcallqueue
1848 | Syntax: dumpcallqueue <queue head>
1849 | Displays the contents of the specified call_entry queue.
1850 end
1851
1852 define showtaskacts
1853 showtaskthreads $arg0
1854 end
1855 document showtaskacts
1856 | See help showtaskthreads.
1857 end
1858
1859 define showallacts
1860 showallthreads
1861 end
1862 document showallacts
1863 | See help showallthreads.
1864 end
1865
1866
1867 define 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
1876 end
1877
1878 document resetstacks
1879 | Syntax: resetstacks
1880 | Internal kgmacro routine used by the "showuserstack" macro
1881 | to reset the target pmap to the kernel pmap.
1882 end
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.
1887 define _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
1894 end
1895
1896 define _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
1902 end
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
1911 set $kgm_cur_ebp = 0
1912 set $kgm_cur_eip = 0
1913
1914 define 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
1936 end
1937
1938 define 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
1990 end
1991 document showuserstack
1992 Syntax: 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.
2001 end
2002
2003 #Stopgap until gdb can generate the HOSTREBOOT packet
2004 define kdp-reboot
2005 #Alternatively, set *(*(unsigned **) 0x2498) = 1 (or 0x5498 on PPC)
2006 set flag_kdp_trigger_reboot = 1
2007 continue
2008 end
2009
2010 document kdp-reboot
2011 Syntax: kdp-reboot
2012 |Reboot the remote target machine; not guaranteed to succeed. Requires symbols
2013 |until gdb support for the HOSTREBOOT packet is implemented.
2014 end
2015
2016 define 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
2026 end
2027
2028 document sendcore
2029 Syntax: 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.
2037 end
2038
2039 define disablecore
2040 set kdp_trigger_core_dump = 0
2041 set kdp_flag |= 0x40
2042 set kdp_flag &= ~0x10
2043 set panicd_specified = 0
2044 end
2045
2046 document disablecore
2047 Syntax: 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.
2051 end
2052
2053 define 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
2079 end
2080
2081 document switchtocorethread
2082 Syntax: 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.
2090 end
2091
2092 define 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
2146 end
2147
2148 define 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
2173 end
2174
2175 document resetcorectx
2176 Syntax: 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.
2181 end
2182
2183 #Helper function for "showallgdbstacks"
2184
2185 define 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
2262 end
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
2270 define 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
2287 end
2288
2289 document showallgdbstacks
2290 Syntax: 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.
2300 end
2301
2302 define 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
2320 end
2321
2322
2323 document showallgdbcorestacks
2324 Syntax: showallgdbcorestacks
2325 |Corefile version of "showallgdbstacks"
2326 end
2327
2328
2329 define 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
2356 end
2357
2358 document switchtouserthread
2359 Syntax: 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.
2382 end
2383
2384 define 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
2389 end
2390
2391 define showstring
2392 printf "\"%s\"", ((OSString *)$arg0)->string
2393 end
2394
2395 define shownumber
2396 printf "%lld", ((OSNumber *)$arg0)->value
2397 end
2398
2399 define showboolean
2400 if ($arg0 == gOSBooleanFalse)
2401 printf "No"
2402 else
2403 printf "Yes"
2404 end
2405 end
2406
2407 define 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 ">"
2466 end
2467
2468 define 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 "}"
2484 end
2485
2486 define 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
2495 end
2496
2497 define 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"
2515 end
2516
2517
2518 define 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
2529 end
2530
2531 define showarrayint
2532 printf "("
2533 showarraysetint $arg0 $arg1
2534 printf ")"
2535 end
2536
2537 define showsetint
2538 set $kgm_array = ((OSSet *)$arg1)->members
2539 printf "["
2540 showarraysetint $arg0 $kgm_array
2541 printf "]"
2542 end
2543
2544
2545 define 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
2599 end
2600
2601 define 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"
2609 end
2610 document showobject
2611 Syntax: (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.
2614 end
2615
2616 define 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
2627 end
2628
2629
2630 define 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
2727 end
2728
2729 define 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
2734 end
2735
2736 define showregistry
2737 set $kgm_reg_depth = 0
2738 set $kgm_show_props = 0
2739 showregistryentryint gRegistryRoot
2740 end
2741 document showregistry
2742 Syntax: (gdb) showregistry
2743 | Show info about all registry entries in the current plane.
2744 end
2745
2746 define showregistryprops
2747 set $kgm_reg_depth = 0
2748 set $kgm_show_props = 1
2749 showregistryentryint gRegistryRoot
2750 end
2751 document showregistryprops
2752 Syntax: (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
2756 end
2757
2758 define showregistryentry
2759 set $kgm_reg_depth = 0
2760 set $kgm_show_props = 1
2761 showregistryentryint $arg0
2762 end
2763 document showregistryentry
2764 Syntax: (gdb) showregistryentry <object address>
2765 | Show info about a registry entry; its properties and descendants in the current plane.
2766 end
2767
2768 define setregistryplane
2769 if ($arg0)
2770 set $kgm_reg_plane = (void **) $arg0
2771 else
2772 showobjectint _ gIORegistryPlanes
2773 printf "\n"
2774 end
2775 end
2776 document setregistryplane
2777 Syntax: (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.
2780 end
2781
2782 define 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
2800 end
2801
2802 define 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
2808 end
2809
2810 document showallclasses
2811 Syntax: (gdb) showallclasses
2812 | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
2813 end
2814
2815 define 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
2820 end
2821
2822 document showioalloc
2823 Syntax: (gdb) showioalloc
2824 | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
2825 end
2826
2827 define 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
2848 end
2849
2850 document showosobjecttracking
2851 Syntax: (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.
2855 end
2856
2857 define readphys
2858 set kdp_trans_off = 1
2859 x/x $arg0
2860 set kdp_trans_off = 0
2861 end
2862
2863 define 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
2871 end
2872
2873 document 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.
2877 end
2878
2879 document 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.
2883 end
2884
2885 define 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
2889 end
2890
2891 document 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
2895 end
2896
2897 define showprocfiles
2898 if ($argc == 1)
2899 _showprocheader
2900 _showprocfiles $arg0
2901 else
2902 printf "| Usage:\n|\n"
2903 help showprocfiles
2904 end
2905 end
2906 document showprocfiles
2907 Syntax: (gdb) showprocfiles <proc_t>
2908 | Given a proc_t pointer, display the list of open file descriptors for the
2909 | referenced process.
2910 end
2911
2912 define _showprocheader
2913 printf "fd fileglob fg flags fg type fg data info\n"
2914 printf "----- ---------- ---------- -------- ---------- -------------------\n"
2915 end
2916
2917 define _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
2974 end
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 #
2982 define showproclocks
2983 if ($argc == 1)
2984 _showproclocks $arg0
2985 else
2986 printf "| Usage:\n|\n"
2987 help showproclocks
2988 end
2989 end
2990 document showproclocks
2991 Syntax: (gdb) showproclocks <proc_t>
2992 | Given a proc_t pointer, display the list of advisory file locks held by the
2993 | referenced process.
2994 end
2995
2996 define _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
3033 end
3034
3035 define 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
3175 end
3176
3177 document showprocinfo
3178 Syntax: (gdb) showprocinfo <proc_t>
3179 | Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
3180 end
3181
3182 #
3183 # dump the zombprocs
3184 #
3185 define 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
3192 end
3193
3194 document zombproc
3195 Syntax: (gdb) zombproc
3196 | Routine to print out all procs in the zombie list
3197 end
3198
3199 #
3200 # dump the zombstacks
3201 #
3202 define 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
3211 end
3212
3213 document zombstacks
3214 Syntax: (gdb) zombstacks
3215 | Routine to print out all stacks of tasks that are exiting
3216 end
3217
3218
3219 #
3220 # dump the allprocs
3221 #
3222 define 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
3229 end
3230
3231 document allproc
3232 Syntax: (gdb) allproc
3233 | Routine to print out all process in the system
3234 | which are not in the zombie list
3235 end
3236
3237
3238
3239 define 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"
3258 end
3259
3260 document print_vnode
3261 Syntax: (gdb) print_vnode <vnode>
3262 | Prints out the fields of a vnode struct
3263 end
3264
3265 define 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
3300 end
3301
3302 document showprocvnodes
3303 Syntax: (gdb) showprocvnodes <proc_address>
3304 | Routine to print out all the open fds
3305 | which are vnodes in a process
3306 end
3307
3308 define 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
3317 end
3318
3319 document showallprocvnodes
3320 Syntax: (gdb) showallprocvnodes
3321 | Routine to print out all the open fds
3322 | which are vnodes
3323 end
3324
3325
3326 #
3327 # dump the childrent of a proc
3328 #
3329 define 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
3336 end
3337
3338 document showinitchild
3339 Syntax: (gdb) showinitchild
3340 | Routine to print out all processes in the system
3341 | which are children of init process
3342 end
3343
3344
3345 define 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
3368 end
3369 document showmountallvnodes
3370 Syntax: showmountallvnodes <struct mount *>
3371 | Print the vnode inactive list
3372 end
3373
3374
3375 define 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
3384 end
3385 document showmountvnodes
3386 Syntax: showmountvnodes <struct mount *>
3387 | Print the vnode list
3388 end
3389
3390
3391
3392 define 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
3401 end
3402 document showworkqvnodes
3403 Syntax: showworkqvnodes <struct mount *>
3404 | Print the vnode worker list
3405 end
3406
3407
3408 define 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
3417 end
3418
3419 document shownewvnodes
3420 Syntax: shownewvnodes <struct mount *>
3421 | Print the new vnode list
3422 end
3423
3424
3425 #
3426 # print mount point info
3427 define 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"
3438 end
3439
3440 define 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
3446 end
3447
3448 document showallmounts
3449 Syntax: showallmounts
3450 | Print all mount points
3451 end
3452
3453 define 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
3461 end
3462
3463 define 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
3479 end
3480
3481 document mbuf_walkpkt
3482 Syntax: (gdb) mbuf_walkpkt <addr>
3483 | Given an mbuf address, walk its m_nextpkt pointer
3484 end
3485
3486 define 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
3502 end
3503
3504 document mbuf_walk
3505 Syntax: (gdb) mbuf_walk <addr>
3506 | Given an mbuf address, walk its m_next pointer
3507 end
3508
3509 define 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
3515 end
3516
3517 document mbuf_buf2slab
3518 | Given an mbuf object, find its corresponding slab address.
3519 end
3520
3521 define 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
3528 end
3529
3530 document mbuf_buf2mca
3531 Syntax: (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.
3535 end
3536
3537 define 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
3589 end
3590
3591 document mbuf_showmca
3592 Syntax: (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.
3595 end
3596
3597 set $MCF_NOCPUCACHE = 0x10
3598
3599 define 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
3647 end
3648
3649 document mcache_stat
3650 Syntax: (gdb) mcache_stat
3651 | Print all mcaches in the system.
3652 end
3653
3654 define 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"
3660 end
3661
3662 document mcache_showzone
3663 Syntax: (gdb) mcache_showzone <mcache_addr>
3664 | Print the type of backend (custom or zone) of a mcache.
3665 end
3666
3667 define 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
3676 end
3677
3678 document mcache_walkobj
3679 Syntax: (gdb) mcache_walkobj <addr>
3680 | Given a mcache object address, walk its obj_next pointer
3681 end
3682
3683 define 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
3714 end
3715
3716 document mcache_showcache
3717 | Display the number of objects in the cache
3718 end
3719
3720 set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
3721
3722 define 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
3738 end
3739
3740 document mbuf_slabstbl
3741 | Display the mbuf slabs table
3742 end
3743
3744 set $SLF_MAPPED=0x0001
3745 set $SLF_PARTIAL=0x0002
3746 set $SLF_DETACHED=0x0004
3747
3748 define 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
3776 end
3777
3778 document mbuf_slabs
3779 | Display all mbuf slabs in the group
3780 end
3781
3782 define 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
3817 end
3818
3819 document mbuf_stat
3820 | Print extended mbuf allocator statistics.
3821 end
3822
3823 set $MB_INUSE = 0x1
3824 set $MB_COMP_INUSE = 0x2
3825 set $MB_SCVALID = 0x4
3826
3827 set $MCLBYTES = 2048
3828 set $MSIZE = 256
3829 set $NBPG = 4096
3830 set $M16KCLBYTES = 16384
3831
3832 define 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
3958 end
3959
3960 document 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.
3963 end
3964
3965 define mbuf_showactive
3966 mbuf_walkallslabs 1 0
3967 end
3968
3969 document mbuf_showactive
3970 Syntax: (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).
3976 end
3977
3978 define mbuf_showinactive
3979 mbuf_walkallslabs 0 1
3980 end
3981
3982 document mbuf_showinactive
3983 Syntax: (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.
3990 end
3991
3992 define mbuf_showall
3993 mbuf_walkallslabs 1 1
3994 end
3995
3996 document mbuf_showall
3997 Syntax: (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.
4001 end
4002
4003 define mbuf_mcaobjs
4004 end
4005
4006 define 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
4087 end
4088
4089 document 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}.
4093 end
4094
4095 define 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
4109 end
4110
4111 document rtentry_trash
4112 Syntax: (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.
4116 end
4117
4118 set $RTD_TRSTACK_SIZE = 8
4119 set $RTD_REFHIST_SIZE = 4
4120
4121 define 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
4193 end
4194
4195 document rtentry_showdbg
4196 Syntax: (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.
4201 end
4202
4203 #
4204 # print all OSMalloc stats
4205
4206 define ostag_print
4207 set $kgm_tagp = (OSMallocTag)$arg0
4208 printf "0x%08x: ", $kgm_tagp
4209 printf "%8d ",$kgm_tagp->OSMT_refcnt
4210 printf "%8x ",$kgm_tagp->OSMT_state
4211 printf "%8x ",$kgm_tagp->OSMT_attr
4212 printf "%s ",$kgm_tagp->OSMT_name
4213 printf "\n"
4214 end
4215
4216
4217 define showosmalloc
4218 printf "TAG COUNT STATE ATTR NAME\n"
4219 set $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"
4226 end
4227 document showosmalloc
4228 Syntax: (gdb) showosmalloc
4229 | Print the outstanding allocation count by OSMallocTags.
4230 end
4231
4232
4233 define 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"
4267 end
4268 document systemlog
4269 | Syntax: systemlog
4270 | Display the kernel's printf ring buffer
4271 end
4272
4273 define 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
4284 end
4285
4286 #
4287 # Show the locks held on a vnode by range, type, and holder.
4288 #
4289 define showvnodelocks
4290 if ($argc == 1)
4291 _showvnodelockheader
4292 _showvnodelocks $arg0
4293 else
4294 printf "| Usage:\n|\n"
4295 help showvnodelocks
4296 end
4297 end
4298 document 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>
4303 end
4304
4305 define _showvnodelockheader
4306 printf "* type W held by lock type start end\n"
4307 printf "- ----- - ------------- --------- ------------------ ------------------\n"
4308 end
4309
4310 #
4311 # Macro to display a single lock; used to display both held locks and
4312 # blocked locks
4313 #
4314 define _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"
4362 end
4363
4364 # Body of showvnodelocks, not including header
4365 define _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
4384 end
4385
4386 define 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"
4396 end
4397
4398 document showvnodepath
4399 Syntax: (gdb) showvnodepath <vnode>
4400 | Prints the path for a vnode
4401 end
4402
4403 define 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
4418 end
4419
4420 define 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
4430 end
4431
4432 define 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
4438 end
4439
4440 define 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
4446 end
4447
4448 define 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]
4452 end
4453
4454 define 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]
4458 end
4459
4460 define 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
4493 end
4494
4495 document showifmultiaddrs
4496 Syntax showifmultiaddrs <ifp>
4497 | show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
4498 end
4499
4500 define 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
4533 end
4534
4535 define 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 ">"
4659 end
4660
4661 define 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
4672 end
4673
4674 document showifaddrs
4675 Syntax: showifaddrs <ifp>
4676 | show the (struct ifnet).if_addrhead list of addresses for the given ifp
4677 end
4678
4679 define 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
4695 end
4696 document ifconfig
4697 Syntax: (gdb) ifconfig
4698 | display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
4699 end
4700
4701 define 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
4710 end
4711
4712 define 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
4737 end
4738
4739 document showallvols
4740 Syntax: (gdb) showallvols
4741 | Display a summary of mounted volumes
4742 end
4743
4744 define showvnodeheader
4745 printf "vnode usecount iocount v_data vtype parent name\n"
4746 end
4747
4748 define 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
4795 end
4796
4797 define showvnode
4798 showvnodeheader
4799 showvnodeint $arg0
4800 end
4801
4802 document showvnode
4803 Syntax: (gdb) showvnode <vnode>
4804 | Display info about one vnode
4805 end
4806
4807 define 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
4815 end
4816
4817 document showvolvnodes
4818 Syntax: (gdb) showvolvnodes <mouont_t>
4819 | Display info about all vnodes of a given mount_t
4820 end
4821
4822 define 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
4832 end
4833
4834 document showvolbusyvnodes
4835 Syntax: (gdb) showvolbusyvnodes <mount_t>
4836 | Display info about busy (iocount!=0) vnodes of a given mount_t
4837 end
4838
4839 define 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
4852 end
4853
4854 document showallbusyvnodes
4855 Syntax: (gdb) showallbusyvnodes <vnode>
4856 | Display info about all busy (iocount!=0) vnodes
4857 end
4858
4859 define 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
4870 end
4871
4872 document showallvnodes
4873 Syntax: (gdb) showallvnodes
4874 | Display info about all vnodes
4875 end
4876
4877 define _showvnodelockheader
4878 printf "* type W held by lock type start end\n"
4879 printf "- ----- - ------------- --------- ------------------ ------------------\n"
4880 end
4881
4882 define _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"
4930 end
4931 # Body of showvnodelocks, not including header
4932 define _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
4951 end
4952
4953
4954 define showvnodelocks
4955 if ($argc == 1)
4956 _showvnodelockheader
4957 _showvnodelocks $arg0
4958 else
4959 printf "| Usage:\n|\n"
4960 help showvnodelocks
4961 end
4962 end
4963
4964 document showvnodelocks
4965 Syntax: (gdb) showvnodelocks <vnode_t>
4966 | Given a vnodet pointer, display the list of advisory record locks for the
4967 | referenced pvnodes
4968 end
4969
4970 define showbootargs
4971 printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
4972 end
4973
4974 document showbootargs
4975 Syntax: showbootargs
4976 | Display boot arguments passed to the target kernel
4977 end
4978
4979 define 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
5038 end
5039
5040 document showbootermemorymap
5041 Syntax: (gdb) showbootermemorymap
5042 | Prints out the phys memory map from kernelBootArgs
5043 end
5044
5045
5046 define 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
5066 end
5067 document showstacksaftertask
5068 Syntax: (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.
5071 end
5072
5073 define 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
5090 end
5091
5092 define 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
5103 end
5104
5105 document showallpmworkqueues
5106 Syntax: (gdb) showallpmworkqueues
5107 | Display info about all IOPMWorkQueue objects
5108 end
5109
5110 define 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
5227 end
5228
5229 document showioservicepm
5230 Syntax: (gdb) showioservicepm <IOServicePM pointer>
5231 | Routine to dump the IOServicePM object
5232 end
5233
5234 define 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
5302 end
5303
5304 define showregistryentryintpmstate
5305 set $kgm_namekey = (OSSymbol *) $kgm_reg_plane[2]
5306 set $kgm_childkey = (OSSymbol *) $kgm_reg_plane[4]
5307 showregistryentryrecursepmstate _ $arg0 0 0
5308 end
5309
5310 define showregistrypmstate
5311 # setregistryplane gIOPowerPlane
5312 set $kgm_reg_depth = 0
5313 set $kgm_show_props = 1
5314 showregistryentryintpmstate gRegistryRoot
5315 end
5316
5317 document showregistrypmstate
5318 Syntax: (gdb) showregistrypmstate
5319 | Routine to dump the PM state of each IOPower registry entry
5320 end
5321
5322 define 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
5343 end
5344
5345 document showstacksafterthread
5346 Syntax: (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.
5349 end
5350
5351 define kdp-reenter
5352 set kdp_reentry_deadline = ((unsigned) $arg0)*1000
5353 continue
5354 end
5355
5356 document kdp-reenter
5357 Syntax: (gdb) kdp-reenter <seconds>
5358 | Schedules reentry into the debugger after <seconds> seconds, and resumes
5359 | the target system.
5360 end
5361
5362 define _if_present
5363 if (!$arg0)
5364 printf " not"
5365 end
5366 printf " present"
5367 end
5368
5369 define 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
5408 end
5409
5410 document showMCAstate
5411 Syntax: showMCAstate
5412 | Print machine-check register state after MC exception.
5413 end
5414
5415 define _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
5489 end
5490
5491 define _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
5535 end
5536
5537 define 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
5554 end
5555
5556 document pmap_walk
5557 Syntax: (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.
5560 end
5561
5562 define 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
5573 end
5574
5575 document pmap_vtop
5576 Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
5577 | For page-tables in <pmap> translate <virtual_address> to physical address.
5578 end
5579
5580 define 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
5621 end
5622
5623 document zstack
5624 Syntax: (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.
5635 end
5636
5637 define 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
5660 end
5661
5662 document findoldest
5663 Syntax: (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.
5670 end
5671
5672 define 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
5702 end
5703
5704 document countpcs
5705 Syntax: (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.
5710 end
5711
5712 define 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
5740 end
5741
5742 document findelem
5743 Syntax: (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.
5749 end