2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
31 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
32 * Import of Mac OS X kernel (~semeria)
34 * Revision 1.2 1998/04/29 17:35:25 mburg
37 * Revision 1.2.85.1 1998/02/03 09:24:09 gdt
39 * [1998/02/03 09:10:24 gdt]
41 * Revision 1.2.81.1 1997/03/27 18:46:38 barbou
42 * ri-osc CR1565 - clean up db_print_act, removing old !USER code
43 * which had gotten stale (the option made little sense here anyway).
44 * Added routine db_show_one_thread() to take either act/shuttle and
45 * do something sensible. [dwm] Also rationalize plain, /u and /l
46 * output for "show act", "show task" and "show all acts".
47 * [1995/08/28 15:47:00 bolinger]
50 * Revision 1.2.31.13 1996/01/09 19:16:02 devrcs
51 * Alpha kdebug Changes:
52 * Correct various header spacing to account for 64-bit addresses.
53 * Modify db_show_all_*() functions, so the can be called from kdebug.
54 * ( There's no way to call with "char *modif", so added NULL check. )
55 * Changed db_error() calls to DB_ERROR() macro, so we return on error
56 * on Alpha (we gotta return to kdebug).
57 * Changed declarations of 'register foo' to 'register int foo'.
58 * [1995/12/01 21:42:20 jfraser]
60 * Merged '64-bit safe' changes from DEC alpha port.
61 * [1995/11/21 18:03:24 jfraser]
63 * Revision 1.2.31.12 1995/10/09 17:03:30 devrcs
65 * [1995/08/24 20:56:42 watkins]
67 * Revision 1.2.59.1 1995/08/04 17:03:17 watkins
68 * Change to stack per shuttle model.
69 * [1995/07/19 20:26:13 watkins]
71 * Revision 1.2.31.11 1995/09/18 19:08:49 devrcs
73 * [1995/08/24 20:56:42 watkins]
75 * Revision 1.2.59.1 1995/08/04 17:03:17 watkins
76 * Change to stack per shuttle model.
77 * [1995/07/19 20:26:13 watkins]
79 * Revision 1.2.31.10 1995/05/19 15:43:04 bernadat
80 * Fixed db_print_act for empty activations.
81 * Let thread swapping be configurable.
84 * Revision 1.2.31.9 1995/05/14 18:10:25 dwm
85 * ri-osc CR1304 - merge (nmk19_latest - nmk19b1) diffs into mainline.
86 * mk6 CR938 - restore mach_msg hot path
87 * remove use of now-defunct fields in thread [mmp,dwm]
88 * [1995/05/14 17:25:05 dwm]
90 * Revision 1.2.31.8 1995/04/07 18:53:00 barbou
91 * VM Merge - Task Swapper.
92 * Renamed TH_SWAPPED to TH_STACK_HANDOFF and swap_func to continuation
93 * to resolve name conflict.
94 * From kernel/kdb/kdb_mach.c:
95 * Put in changes for swapping.
96 * [1991/11/21 20:32:15 mmp]
100 * Revision 1.2.31.7 1995/02/28 01:58:38 dwm
101 * mk6 CR1120 - Merge mk6pro_shared into cnmk_shared
102 * * Rev1.2.43.1 1995/01/27 22:01:26 bolinger
103 * * Fix ri-osc CR977: Make "show space" and "show ipc_port" give
104 * * accurate count of ports active in IPC space. Make "show ipc_port"
105 * * output task-visible port name.
106 * [1995/02/28 01:12:46 dwm]
108 * Revision 1.2.31.6 1995/02/23 21:43:34 alanl
109 * Fix db_show_one_task_vm for thread_act_ts.
112 * Merged with DIPC2_SHARED.
115 * Revision 1.2.31.5 1995/01/10 04:49:52 devrcs
116 * mk6 CR801 - merge up from nmk18b4 to nmk18b7
117 * Fix "sh thr/ul"; no cont. to print, fix pri/policy format.
118 * * Rev 1.2.31.4 1994/10/11 16:35:58 emcmanus
119 * Added "show runq" and "show shuttle".
120 * [1994/12/09 20:36:49 dwm]
122 * mk6 CR668 - 1.3b26 merge
123 * * Revision 1.2.8.6 1994/05/06 18:39:37 tmt
124 * Merged osc1.3dec/shared with osc1.3b19
125 * Merge Alpha changes into osc1.312b source code.
128 * [1994/11/04 08:49:52 dwm]
130 * Revision 1.2.31.3 1994/09/23 01:20:51 ezf
131 * change marker to not FREE
132 * [1994/09/22 21:10:41 ezf]
134 * Revision 1.2.31.2 1994/06/14 17:21:05 bolinger
135 * Merge up to NMK17.2.
136 * [1994/06/14 17:20:35 bolinger]
138 * Revision 1.2.23.4 1994/04/15 18:41:31 paire
139 * Changed interface of db_task_from_space routine.
142 * Revision 1.2.23.3 1994/03/07 16:37:48 paire
143 * Merge with Intel R1_1
144 * Change from NMK14.10 [1993/11/15 16:06:21 rwd]
146 * Enhanced pretty print routine and added db_task_from_space.
147 * Change from NMK14.10 [93/09/24 sjs]
150 * Exported ANSI prototype of db_port_kmsg_count routine.
151 * Added header file include for the declaration of db_norma_ipc routine.
154 * Revision 1.2.23.2 1994/02/11 14:21:58 paire
155 * Added new vm_print.h header file for db_vm declaration.
158 * Revision 1.2.23.1 1994/02/08 10:58:19 bernadat
159 * print out msgcount for each port in db_port_iterate
160 * Change from NORMA_MK14.6(August 93) [1993/07/27 12:35:17 mmp]
162 * Removed defintion of db_maxoff (got from <ddb/db_sym.h>).
165 * Show ipc_space_remote msg counts only if NORMA_IPC is on
166 * [93/07/21 bernadat]
168 * Add /s option to "show ipc_port" to pick out port sets.
169 * Change from NORMA_MK14.6 [1993/02/17 16:29:54 dwm]
170 * [93/07/16 bernadat]
171 * [94/02/07 bernadat]
173 * Revision 1.2.20.8 1994/06/08 19:11:15 dswartz
175 * [1994/06/08 19:10:18 dswartz]
177 * Revision 1.2.20.7 1994/04/30 21:28:24 bolinger
178 * Thread control ops synchronization: now that TH_SUSP is back,
179 * enable ddb to show it when printing thread state.
180 * [1994/04/28 21:55:42 bolinger]
182 * Revision 1.2.20.6 1994/03/17 22:35:31 dwm
183 * The infamous name change: thread_activation + thread_shuttle = thread.
184 * [1994/03/17 21:25:46 dwm]
186 * Revision 1.2.20.5 1994/01/26 15:43:37 bolinger
187 * Move kernel_stack from thread to activation.
188 * [1994/01/25 21:53:11 bolinger]
190 * Revision 1.2.20.4 1994/01/12 17:50:44 dwm
191 * Coloc: initial restructuring to follow Utah model.
192 * [1994/01/12 17:13:12 dwm]
194 * Revision 1.2.20.3 1993/11/18 18:11:47 dwm
195 * Coloc: remove continuations entirely; they are incompatible
196 * with migration, and their volume is obfuscatory.
197 * [1993/11/18 18:06:27 dwm]
199 * Revision 1.2.20.2 1993/10/12 16:38:50 dwm
200 * CoLoc: neuter continuations, ifdef USE_CONTINUATIONS.
201 * [1993/10/12 16:14:46 dwm]
203 * Revision 1.2.8.4 1993/08/11 20:38:06 elliston
204 * Add ANSI Prototypes. CR #9523.
205 * [1993/08/11 03:33:51 elliston]
207 * Revision 1.2.8.3 1993/07/27 18:27:55 elliston
208 * Add ANSI prototypes. CR #9523.
209 * [1993/07/27 18:12:39 elliston]
211 * Revision 1.2.8.2 1993/06/09 02:20:35 gm
212 * CR9176 - ANSI C violations: trailing tokens on CPP
213 * directives, extra semicolons after decl_ ..., asm keywords
214 * [1993/06/07 18:57:22 jeffc]
216 * Removed a '#if MACH_FIXPRI' which somehow survived the purge. CR #9131.
217 * [1993/05/11 20:56:00 dswartz]
219 * Revision 1.2 1993/04/19 16:02:50 devrcs
220 * Added printout of thread scheduling policy to long form
225 * Removed unused variable from db_show_regs().
227 * Converted some db_printsyms to db_task_printsyms.
229 * Changed db_print_thread so that both display formats
230 * show the floating-point-used status of the thread.
234 * Revision 1.1 1992/09/30 02:01:18 robert
241 * Revision 2.11.3.2 92/04/08 15:43:10 jeffreyh
242 * Added i option to show thread. This gives wait state information.
245 * Revision 2.11.3.1 92/03/03 16:13:34 jeffreyh
246 * Pick up changes from TRUNK
247 * [92/02/26 11:00:01 jeffreyh]
249 * Revision 2.13 92/02/20 18:34:28 elf
253 * Revision 2.12 92/02/19 15:07:47 elf
254 * Added db_thread_fp_used, to avoid machine-dependent conditionals.
257 * Added 'F' flag to db_thread_stat showing if the thread has a valid
258 * FPU context. Tested on i386 and pmax.
261 * Revision 2.11 91/11/12 11:50:32 rvb
262 * Added OPTION_USER ("/u") to db_show_all_threads, db_show_one_thread,
263 * db_show_one_task. Without it, we display old-style information.
266 * Revision 2.10 91/10/09 16:01:48 af
267 * Supported "show registers" for non current thread.
268 * Changed display format of thread and task information.
269 * Changed "show thread" to print current thread information
270 * if no thread is specified.
271 * Added "show_one_task" for "show task" command.
272 * Added IPC port print routines for "show ipc_port" command.
275 * Revision 2.9 91/08/03 18:17:19 jsb
276 * In db_print_thread, if the thread is swapped and there is a
277 * continuation function, print the function name in parentheses
278 * instead of '(swapped)'.
279 * [91/07/04 09:59:27 jsb]
281 * Revision 2.8 91/07/31 17:30:43 dbg
282 * Revise scheduling state machine.
283 * [91/07/30 16:43:42 dbg]
285 * Revision 2.7 91/07/09 23:15:57 danner
286 * Fixed a few printf that should be db_printfs.
289 * Revision 2.6 91/05/14 15:35:25 mrt
290 * Correcting copyright
292 * Revision 2.5 91/02/05 17:06:53 mrt
293 * Changed to new Mach copyright
294 * [91/01/31 16:18:56 mrt]
296 * Revision 2.4 90/10/25 14:43:54 rwd
297 * Changed db_show_regs to print unsigned.
299 * Generalized the watchpoint support.
302 * Revision 2.3 90/09/09 23:19:52 rpd
303 * Avoid totally incorrect guesses of symbol names for small values.
304 * [90/08/30 17:39:08 af]
306 * Revision 2.2 90/08/27 21:51:49 dbg
307 * Insist that 'show thread' be called with an explicit address.
310 * Fix type for db_maxoff.
313 * Do not dereference the "valuep" field of a variable directly,
314 * call the new db_read/write_variable functions instead.
315 * Reflected changes in symbol lookup functions.
318 * [90/08/10 14:33:44 dbg]
326 * Mach Operating System
327 * Copyright (c) 1991,1990 Carnegie Mellon University
328 * All Rights Reserved.
330 * Permission to use, copy, modify and distribute this software and its
331 * documentation is hereby granted, provided that both the copyright
332 * notice and this permission notice appear in all copies of the
333 * software, derivative works or modified versions, and any portions
334 * thereof, and that both notices appear in supporting documentation.
336 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
337 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
338 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
340 * Carnegie Mellon requests users of this software to return to
342 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
343 * School of Computer Science
344 * Carnegie Mellon University
345 * Pittsburgh PA 15213-3890
347 * any improvements or extensions that they make and grant Carnegie Mellon
348 * the rights to redistribute these changes.
353 * Author: David B. Golub, Carnegie Mellon University
358 * Miscellaneous printing.
361 #include <task_swapper.h>
363 #include <string.h> /* For strlen() */
364 #include <mach/port.h>
365 #include <kern/task.h>
366 #include <kern/thread.h>
367 #include <kern/thread_swap.h>
368 #include <kern/queue.h>
369 #include <ipc/ipc_port.h>
370 #include <ipc/ipc_space.h>
371 #include <ipc/ipc_pset.h>
372 #include <vm/vm_print.h> /* for db_vm() */
374 #include <machine/db_machdep.h>
375 #include <machine/thread.h>
377 #include <ddb/db_lex.h>
378 #include <ddb/db_variables.h>
379 #include <ddb/db_sym.h>
380 #include <ddb/db_task_thread.h>
381 #include <ddb/db_command.h>
382 #include <ddb/db_output.h> /* For db_printf() */
383 #include <ddb/db_print.h>
386 #include <kern/sp_mk.h> /*** ??? fix so this can be removed ***/
389 #include <kern/task_swap.h>
390 #endif /* TASK_SWAPPER */
392 /* Prototypes for functions local to this file. XXX -- should be static!
396 register thread_act_t thr_act
,
399 char *db_act_swap_stat(
400 register thread_act_t thr_act
,
408 void db_reset_print_entry(
411 void db_print_one_entry(
414 mach_port_name_t name
,
418 thread_act_t thr_act
,
420 boolean_t do_output
);
422 ipc_port_t
db_lookup_port(
423 thread_act_t thr_act
,
426 static void db_print_port_id(
433 thread_act_t thr_act
,
442 void db_print_task_vm(
448 void db_system_stats(void);
458 register struct db_variable
*regp
;
463 struct db_var_aux_param aux_param
;
464 task_t task
= TASK_NULL
;
466 aux_param
.modif
= modif
;
467 aux_param
.thr_act
= THR_ACT_NULL
;
468 if (db_option(modif
, 't')) {
470 if (!db_check_act_address_valid((thread_act_t
)addr
))
472 aux_param
.thr_act
= (thread_act_t
)addr
;
474 aux_param
.thr_act
= db_default_act
;
475 if (aux_param
.thr_act
!= THR_ACT_NULL
)
476 task
= aux_param
.thr_act
->task
;
478 for (regp
= db_regs
; regp
< db_eregs
; regp
++) {
479 if (regp
->max_level
> 1) {
480 db_printf("bad multi-suffixed register %s\n", regp
->name
);
483 aux_param
.level
= regp
->max_level
;
484 for (i
= regp
->low
; i
<= regp
->high
; i
++) {
485 aux_param
.suffix
[0] = i
;
486 db_read_write_variable(regp
, &value
, DB_VAR_GET
, &aux_param
);
487 if (regp
->max_level
> 0)
488 db_printf("%s%d%*s", regp
->name
, i
,
489 12-strlen(regp
->name
)-((i
<10)?1:2), "");
491 db_printf("%-12s", regp
->name
);
492 db_printf("%#*N", 2+2*sizeof(vm_offset_t
), value
);
493 db_find_xtrn_task_sym_and_offset((db_addr_t
)value
, &name
,
495 if (name
!= 0 && offset
<= db_maxoff
&& offset
!= value
) {
496 db_printf("\t%s", name
);
498 db_printf("+%#r", offset
);
505 #define OPTION_LONG 0x001 /* long print option */
506 #define OPTION_USER 0x002 /* print ps-like stuff */
507 #define OPTION_INDENT 0x100 /* print with indent */
508 #define OPTION_THREAD_TITLE 0x200 /* print thread title */
509 #define OPTION_TASK_TITLE 0x400 /* print thread title */
512 #define DB_TASK_NAME(task) /* no task name */
513 #define DB_TASK_NAME_TITLE "" /* no task name */
514 #endif /* DB_TASK_NAME */
516 #ifndef db_act_fp_used
517 #define db_act_fp_used(thr_act) FALSE
522 register thread_act_t thr_act
,
525 register char *p
= status
;
527 if (!thr_act
->active
) {
534 } else if (!thr_act
->thread
) {
542 thread_t athread
= thr_act
->thread
;
544 *p
++ = (athread
->state
& TH_RUN
) ? 'R' : '.';
545 *p
++ = (athread
->state
& TH_WAIT
) ? 'W' : '.';
546 *p
++ = (athread
->state
& TH_SUSP
) ? 'S' : '.';
547 *p
++ = (athread
->state
& TH_SWAPPED_OUT
) ? 'O' : '.';
548 *p
++ = (athread
->state
& TH_UNINT
) ? 'N' : '.';
549 /* show if the FPU has been used */
550 *p
++ = db_act_fp_used(thr_act
) ? 'F' : '.';
558 register thread_act_t thr_act
,
561 register char *p
= status
;
564 switch (thr_act
->swap_state
& TH_SW_STATE
) {
565 case TH_SW_UNSWAPPABLE
:
571 case TH_SW_GOING_OUT
:
580 case TH_SW_COMING_IN
:
587 *p
++ = (thr_act
->swap_state
& TH_SW_TASK_SWAPPING
) ? 'T' : '.';
588 #endif /* THREAD_SWAPPER */
594 char *policy_list
[] = { "TS", "RR", "??", "FF",
595 "??", "??", "??", "BE"};
599 thread_act_t thr_act
,
610 db_printf("db_print_act(NULL)!\n");
614 athread
= thr_act
->thread
;
615 if (flag
& OPTION_USER
) {
617 if (flag
& OPTION_LONG
) {
618 if (flag
& OPTION_INDENT
)
620 if (flag
& OPTION_THREAD_TITLE
) {
621 db_printf("%s ID: ACT STAT SW STACK SHUTTLE", indent
);
622 db_printf(" SUS PRI WAIT_FUNC\n");
624 policy
= (athread
? athread
->policy
: 2);
625 db_printf("%s%3d%c %0*X %s %s %0*X %0*X %3d %3d/%s ",
627 (thr_act
== current_act())? '#': ':',
628 2*sizeof(vm_offset_t
), thr_act
,
629 db_act_stat(thr_act
, status
),
630 db_act_swap_stat(thr_act
, swap_status
),
631 2*sizeof(vm_offset_t
), (athread
?athread
->kernel_stack
:0),
632 2*sizeof(vm_offset_t
), athread
,
633 thr_act
->suspend_count
,
634 (athread
? athread
->sched_pri
: 999), /* XXX */
635 policy_list
[policy
-1]);
637 /* no longer TH_SWAP, no continuation to print */
638 if (athread
->state
& TH_WAIT
)
639 db_task_printsym((db_addr_t
)athread
->wait_event
,
640 DB_STGY_ANY
, kernel_task
);
644 if (act_id
% 3 == 0) {
645 if (flag
& OPTION_INDENT
)
649 db_printf("%3d%c(%0*X,%s)", act_id
,
650 (thr_act
== current_act())? '#': ':',
651 2*sizeof(vm_offset_t
), thr_act
,
652 db_act_stat(thr_act
, status
));
655 if (flag
& OPTION_INDENT
)
656 db_printf(" %3d (%0*X) ", act_id
,
657 2*sizeof(vm_offset_t
), thr_act
);
659 db_printf("(%0*X) ", 2*sizeof(vm_offset_t
), thr_act
);
661 db_printf("%c%c%c%c%c",
662 (athread
->state
& TH_RUN
) ? 'R' : ' ',
663 (athread
->state
& TH_WAIT
) ? 'W' : ' ',
664 (athread
->state
& TH_SUSP
) ? 'S' : ' ',
665 (athread
->state
& TH_UNINT
)? 'N' : ' ',
666 db_act_fp_used(thr_act
) ? 'F' : ' ');
667 /* Obsolete TH_STACK_HANDOFF code, left for now; might enhance
668 * to print out safe_points instead */
669 if (athread
->state
& TH_STACK_HANDOFF
) {
670 if (athread
->continuation
) {
672 db_task_printsym((db_addr_t
)athread
->continuation
,
673 DB_STGY_ANY
, kernel_task
);
676 db_printf("(handoff)");
679 if (athread
->state
& TH_WAIT
) {
681 db_task_printsym((db_addr_t
)athread
->wait_event
,
682 DB_STGY_ANY
, kernel_task
);
696 thread_act_t thr_act
;
700 if (flag
& OPTION_USER
) {
701 if (flag
& OPTION_TASK_TITLE
) {
702 db_printf(" ID: TASK MAP THD RES SUS PR SW %s",
704 if ((flag
& OPTION_LONG
) == 0)
709 switch ((int) task
->swap_state
) {
716 case TASK_SW_GOING_OUT
:
719 case TASK_SW_COMING_IN
:
722 case TASK_SW_UNSWAPPABLE
:
729 #else /* TASK_SWAPPER */
731 #endif /* TASK_SWAPPER */
733 db_printf("%3d: %0*X %0*X %3d %3d %3d %2d %c ",
734 task_id
, 2*sizeof(vm_offset_t
), task
,
735 2*sizeof(vm_offset_t
), task
->map
,
736 task
->thr_act_count
, task
->res_act_count
,
738 ((mk_sp_attributes_t
)(task
->sp_attributes
))->priority
,
741 if (flag
& OPTION_LONG
) {
742 if (flag
& OPTION_TASK_TITLE
)
743 flag
|= OPTION_THREAD_TITLE
;
745 } else if (task
->thr_act_count
<= 1)
746 flag
&= ~OPTION_INDENT
;
748 queue_iterate(&task
->thr_acts
, thr_act
, thread_act_t
, thr_acts
) {
749 db_print_act(thr_act
, act_id
, flag
);
750 flag
&= ~OPTION_THREAD_TITLE
;
753 if ((flag
& OPTION_LONG
) == 0)
756 if (flag
& OPTION_LONG
) {
757 if (flag
& OPTION_TASK_TITLE
) {
758 db_printf(" TASK ACT\n");
759 if (task
->thr_act_count
> 1)
760 flag
|= OPTION_THREAD_TITLE
;
763 db_printf("%3d (%0*X): ", task_id
, 2*sizeof(vm_offset_t
), task
);
764 if (task
->thr_act_count
== 0) {
765 db_printf("no threads\n");
767 if (task
->thr_act_count
> 1) {
768 db_printf("%d threads: \n", task
->thr_act_count
);
769 flag
|= OPTION_INDENT
;
771 flag
&= ~OPTION_INDENT
;
773 queue_iterate(&task
->thr_acts
, thr_act
,
774 thread_act_t
, thr_acts
) {
775 db_print_act(thr_act
, act_id
++, flag
);
776 flag
&= ~OPTION_THREAD_TITLE
;
789 thread_act_t act
= (thread_act_t
)queue_first(&task
->thr_acts
);
793 space
= task
->itk_space
;
795 count
= db_port_iterate(act
, FALSE
, FALSE
);
796 db_printf("%3d: %08x %08x %08x %sactive %d\n",
797 task_id
, task
, space
, task
->map
,
798 space
->is_active
? "":"!", count
);
815 db_printf("id task map pmap virtual rss pg rss mem wir pg wir mem\n");
819 pmap
= vm_map_pmap(map
);
821 size
= db_vm_map_total_size(map
);
822 resident
= pmap
->stats
.resident_count
;
823 wired
= pmap
->stats
.wired_count
;
825 db_printf("%2d %08x %08x %08x %7dK %6d %6dK %6d %6dK\n",
831 resident
, (resident
* PAGE_SIZE
) / 1024,
832 wired
, (wired
* PAGE_SIZE
) / 1024);
847 if (have_addr
== FALSE
) {
848 if ((thread
= db_default_act
) == THR_ACT_NULL
) {
849 if ((thread
= current_act()) == THR_ACT_NULL
) {
850 db_printf("no thread.\n");
856 task
= (task_t
) addr
;
859 task_id
= db_lookup_task(task
);
861 db_printf("0x%x is not a task_t\n", addr
);
865 db_print_task_vm(task
, task_id
, TRUE
, modif
);
877 boolean_t title
= TRUE
;
878 processor_set_t pset
;
881 queue_iterate(&all_psets
, pset
, processor_set_t
, all_psets
) {
882 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
883 db_print_task_vm(task
, task_id
, title
, modif
);
900 processor_set_t pset
;
902 flag
= OPTION_TASK_TITLE
|OPTION_INDENT
;
903 if (db_option(modif
, 'u'))
905 if (db_option(modif
, 'l'))
909 queue_iterate(&all_psets
, pset
, processor_set_t
, all_psets
) {
910 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
911 db_print_task(task
, task_id
, flag
);
912 flag
&= ~OPTION_TASK_TITLE
;
914 if ((flag
& (OPTION_LONG
|OPTION_INDENT
)) == OPTION_INDENT
)
931 flag
= OPTION_TASK_TITLE
;
932 if (db_option(modif
, 'u'))
934 if (db_option(modif
, 'l'))
938 task
= db_current_task();
939 if (task
== TASK_NULL
) {
940 db_error("No task\n");
944 task
= (task_t
) addr
;
946 if ((task_id
= db_lookup_task(task
)) < 0) {
947 db_printf("bad task address 0x%x\n", addr
);
952 db_printf(" ID: TASK SPACE MAP COUNT\n");
953 db_print_space(task
, task_id
, flag
);
966 processor_set_t pset
;
968 flag
= OPTION_TASK_TITLE
|OPTION_INDENT
;
969 if (db_option(modif
, 'u'))
971 if (db_option(modif
, 'l'))
974 db_printf(" ID: TASK SPACE MAP COUNT\n");
975 queue_iterate(&all_psets
, pset
, processor_set_t
, all_psets
) {
976 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
977 db_print_space(task
, task_id
, flag
);
990 processor_set_t pset
;
992 queue_iterate(&all_psets
, pset
, processor_set_t
, all_psets
) {
993 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
994 if (task
->itk_space
== space
) {
996 return (db_addr_t
)task
;
1008 boolean_t have_addr
,
1014 thread_act_t thr_act
;
1016 flag
= OPTION_THREAD_TITLE
;
1017 if (db_option(modif
, 'u'))
1018 flag
|= OPTION_USER
;
1019 if (db_option(modif
, 'l'))
1020 flag
|= OPTION_LONG
;
1023 thr_act
= current_act();
1024 if (thr_act
== THR_ACT_NULL
) {
1025 db_error("No thr_act\n");
1029 thr_act
= (thread_act_t
) addr
;
1031 if ((act_id
= db_lookup_act(thr_act
)) < 0) {
1032 db_printf("bad thr_act address %#x\n", addr
);
1037 if (flag
& OPTION_USER
) {
1038 db_printf("TASK%d(%0*X):\n",
1039 db_lookup_task(thr_act
->task
),
1040 2*sizeof(vm_offset_t
), thr_act
->task
);
1041 db_print_act(thr_act
, act_id
, flag
);
1043 db_printf("task %d(%0*Xx): thr_act %d",
1044 db_lookup_task(thr_act
->task
),
1045 2*sizeof(vm_offset_t
), thr_act
->task
, act_id
);
1046 db_print_act(thr_act
, act_id
, flag
);
1048 if (db_option(modif
, 'i') && thr_act
->thread
&&
1049 (thr_act
->thread
->state
& TH_WAIT
) &&
1050 thr_act
->thread
->kernel_stack
== 0) {
1052 db_printf("Wait State: option 0x%x\n",
1053 thr_act
->thread
->ith_option
);
1060 boolean_t have_addr
,
1068 flag
= OPTION_TASK_TITLE
|OPTION_INDENT
;
1069 if (db_option(modif
, 'u'))
1070 flag
|= OPTION_USER
;
1071 if (db_option(modif
, 'l'))
1072 flag
|= OPTION_LONG
;
1075 task
= db_current_task();
1076 if (task
== TASK_NULL
) {
1077 db_error("No task\n");
1081 task
= (task_t
) addr
;
1083 if ((task_id
= db_lookup_task(task
)) < 0) {
1084 db_printf("bad task address 0x%x\n", addr
);
1089 db_print_task(task
, task_id
, flag
);
1095 boolean_t have_addr
,
1099 thread_shuttle_t shuttle
;
1100 thread_act_t thr_act
;
1103 shuttle
= (thread_shuttle_t
) addr
;
1105 thr_act
= current_act();
1106 if (thr_act
== THR_ACT_NULL
) {
1107 db_error("No thr_act\n");
1110 shuttle
= thr_act
->thread
;
1111 if (shuttle
== THREAD_NULL
) {
1112 db_error("No shuttle associated with current thr_act\n");
1116 db_printf("shuttle %x:\n", shuttle
);
1117 if (shuttle
->top_act
== THR_ACT_NULL
)
1118 db_printf(" no activations\n");
1120 db_printf(" activations:");
1121 for (thr_act
= shuttle
->top_act
; thr_act
!= THR_ACT_NULL
;
1122 thr_act
= thr_act
->lower
) {
1123 if (thr_act
!= shuttle
->top_act
)
1125 printf(" $task%d.%d(%x)", db_lookup_task(thr_act
->task
),
1126 db_lookup_act(thr_act
), thr_act
);
1132 #define db_pset_kmsg_count(port) \
1133 (ipc_list_count((port)->ip_pset->ips_messages.imq_messages.ikmq_base))
1139 return (port
->ip_pset
? db_pset_kmsg_count(port
) : port
->ip_msgcount
);
1142 static int db_print_ent_cnt
= 0;
1144 void db_reset_print_entry(
1147 db_print_ent_cnt
= 0;
1157 ipc_port_t aport
= (ipc_port_t
)entry
->ie_object
;
1158 unsigned bits
= entry
->ie_bits
;
1160 if (is_pset
&& !aport
->ip_pset
)
1162 if (db_print_ent_cnt
&& db_print_ent_cnt
% 2 == 0)
1165 db_printf("\t%s%d[%x]",
1166 !is_pset
&& aport
->ip_pset
? "pset" : "port",
1168 MACH_PORT_MAKE(index
, IE_BITS_GEN(bits
)));
1170 db_printf("\t%s[%x]",
1171 !is_pset
&& aport
->ip_pset
? "pset" : "port",
1174 db_printf("(%s,%x,%d)",
1175 (bits
& MACH_PORT_TYPE_RECEIVE
)? "r":
1176 (bits
& MACH_PORT_TYPE_SEND
)? "s": "S",
1178 db_port_kmsg_count(aport
));
1182 db_printf("(%s,%x,set=%x,%d)",
1183 (bits
& MACH_PORT_TYPE_RECEIVE
)? "r":
1184 (bits
& MACH_PORT_TYPE_SEND
)? "s": "S",
1187 db_pset_kmsg_count(aport
));
1194 thread_act_t thr_act
,
1196 boolean_t do_output
)
1199 ipc_tree_entry_t tentry
;
1206 space
= thr_act
->task
->itk_space
;
1207 entry
= space
->is_table
;
1208 size
= space
->is_table_size
;
1209 db_reset_print_entry();
1210 for (index
= 0; index
< size
; ++index
, ++entry
) {
1211 if (entry
->ie_bits
& MACH_PORT_TYPE_PORT_RIGHTS
) {
1213 db_print_one_entry(entry
,
1214 index
, (mach_port_t
)0, is_pset
);
1218 for (tentry
= ipc_splay_traverse_start(&space
->is_tree
);
1220 tentry
= ipc_splay_traverse_next(&space
->is_tree
, FALSE
)) {
1221 entry
= &tentry
->ite_entry
;
1222 if (entry
->ie_bits
& MACH_PORT_TYPE_PORT_RIGHTS
) {
1224 db_print_one_entry(entry
,
1225 0, tentry
->ite_name
, is_pset
);
1234 thread_act_t thr_act
,
1237 register ipc_space_t space
;
1238 register ipc_entry_t entry
;
1240 if (thr_act
== THR_ACT_NULL
)
1242 space
= thr_act
->task
->itk_space
;
1243 if (id
< 0 || id
>= space
->is_table_size
)
1245 entry
= &space
->is_table
[id
];
1246 if (entry
->ie_bits
& MACH_PORT_TYPE_PORT_RIGHTS
)
1247 return((ipc_port_t
)entry
->ie_object
);
1258 if (n
!= 0 && n
% 3 == 0)
1260 db_printf("\tport%d(%s,%x)", id
,
1261 (bits
& MACH_PORT_TYPE_RECEIVE
)? "r":
1262 (bits
& MACH_PORT_TYPE_SEND
)? "s": "S", port
);
1268 boolean_t have_addr
,
1272 thread_act_t thr_act
;
1275 thr_act
= current_act();
1276 if (thr_act
== THR_ACT_NULL
) {
1277 db_error("No thr_act\n");
1281 thr_act
= (thread_act_t
) addr
;
1282 if (db_lookup_act(thr_act
) < 0) {
1283 db_printf("Bad thr_act address 0x%x\n", addr
);
1287 if (db_port_iterate(thr_act
, db_option(modif
,'s'), TRUE
))
1292 * Useful system state when the world has hung.
1297 extern void db_device(void);
1298 extern void db_sched(void);
1300 extern void db_dipc_stats(void);
1301 extern void db_show_kkt(void);
1316 db_printf("current_{thread/task} 0x%x 0x%x\n",
1317 current_thread(),current_task());
1320 void db_show_one_runq(run_queue_t runq
);
1325 boolean_t have_addr
,
1329 processor_set_t pset
;
1332 boolean_t showedany
= FALSE
;
1334 queue_iterate(&all_psets
, pset
, processor_set_t
, all_psets
) {
1335 #if NCPUS > 1 /* This code has not been tested. */
1336 queue_iterate(&pset
->processors
, proc
, processor_t
, processors
) {
1338 if (runq
->count
> 0) {
1339 db_printf("PROCESSOR %x IN SET %x\n", proc
, pset
);
1340 db_show_one_runq(runq
);
1344 #endif /* NCPUS > 1 */
1346 #error NCPUS undefined
1349 if (runq
->count
> 0) {
1350 db_printf("PROCESSOR SET %x\n", pset
);
1351 db_show_one_runq(runq
);
1356 db_printf("No runnable threads\n");
1363 int i
, task_id
, thr_act_id
;
1365 thread_act_t thr_act
;
1369 printf("PRI TASK.ACTIVATION\n");
1370 for (i
= runq
->low
, q
= runq
->runq
+ i
; i
< NRQS
; i
++, q
++) {
1371 if (!queue_empty(q
)) {
1372 db_printf("%3d:", i
);
1373 queue_iterate(q
, thread
, thread_t
, links
) {
1374 thr_act
= thread
->top_act
;
1375 task
= thr_act
->task
;
1376 task_id
= db_lookup_task(task
);
1377 thr_act_id
= db_lookup_task_act(task
, thr_act
);
1378 db_printf(" %d.%d", task_id
, thr_act_id
);