Annotation of XNU/osfmk/ddb/orig/db_print.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  */
        !            25: /*
        !            26:  * HISTORY
        !            27:  * 
        !            28:  * Revision 1.1.1.1  1998/09/22 21:05:48  wsanchez
        !            29:  * Import of Mac OS X kernel (~semeria)
        !            30:  *
        !            31:  * Revision 1.2  1998/04/29 17:35:25  mburg
        !            32:  * MK7.3 merger
        !            33:  *
        !            34:  * Revision 1.2.85.1  1998/02/03  09:24:09  gdt
        !            35:  *     Merge up to MK7.3
        !            36:  *     [1998/02/03  09:10:24  gdt]
        !            37:  *
        !            38:  * Revision 1.2.81.1  1997/03/27  18:46:38  barbou
        !            39:  *     ri-osc CR1565 - clean up db_print_act, removing old !USER code
        !            40:  *     which had gotten stale (the option made little sense here anyway).
        !            41:  *     Added routine db_show_one_thread() to take either act/shuttle and
        !            42:  *     do something sensible. [dwm]  Also rationalize plain, /u and /l
        !            43:  *     output for "show act", "show task" and "show all acts".
        !            44:  *     [1995/08/28  15:47:00  bolinger]
        !            45:  *     [97/02/25            barbou]
        !            46:  * 
        !            47:  * Revision 1.2.31.13  1996/01/09  19:16:02  devrcs
        !            48:  *     Alpha kdebug Changes:
        !            49:  *       Correct various header spacing to account for 64-bit addresses.
        !            50:  *       Modify db_show_all_*() functions, so the can be called from kdebug.
        !            51:  *       ( There's no way to call with "char *modif", so added NULL check. )
        !            52:  *       Changed db_error() calls to DB_ERROR() macro, so we return on error
        !            53:  *       on Alpha (we gotta return to kdebug).
        !            54:  *     Changed declarations of 'register foo' to 'register int foo'.
        !            55:  *     [1995/12/01  21:42:20  jfraser]
        !            56:  * 
        !            57:  *     Merged '64-bit safe' changes from DEC alpha port.
        !            58:  *     [1995/11/21  18:03:24  jfraser]
        !            59:  * 
        !            60:  * Revision 1.2.31.12  1995/10/09  17:03:30  devrcs
        !            61:  *     Merge forward.
        !            62:  *     [1995/08/24  20:56:42  watkins]
        !            63:  * 
        !            64:  * Revision 1.2.59.1  1995/08/04  17:03:17  watkins
        !            65:  *     Change to stack per shuttle model.
        !            66:  *     [1995/07/19  20:26:13  watkins]
        !            67:  * 
        !            68:  * Revision 1.2.31.11  1995/09/18  19:08:49  devrcs
        !            69:  *     Merge forward.
        !            70:  *     [1995/08/24  20:56:42  watkins]
        !            71:  * 
        !            72:  * Revision 1.2.59.1  1995/08/04  17:03:17  watkins
        !            73:  *     Change to stack per shuttle model.
        !            74:  *     [1995/07/19  20:26:13  watkins]
        !            75:  * 
        !            76:  * Revision 1.2.31.10  1995/05/19  15:43:04  bernadat
        !            77:  *     Fixed db_print_act for empty activations.
        !            78:  *     Let thread swapping be configurable.
        !            79:  *     [95/05/19            bernadat]
        !            80:  * 
        !            81:  * Revision 1.2.31.9  1995/05/14  18:10:25  dwm
        !            82:  *     ri-osc CR1304 - merge (nmk19_latest - nmk19b1) diffs into mainline.
        !            83:  *     mk6 CR938 - restore mach_msg hot path
        !            84:  *     remove use of now-defunct fields in thread [mmp,dwm]
        !            85:  *     [1995/05/14  17:25:05  dwm]
        !            86:  * 
        !            87:  * Revision 1.2.31.8  1995/04/07  18:53:00  barbou
        !            88:  *     VM Merge - Task Swapper.
        !            89:  *     Renamed TH_SWAPPED to TH_STACK_HANDOFF and swap_func to continuation
        !            90:  *     to resolve name conflict.
        !            91:  *     From kernel/kdb/kdb_mach.c:
        !            92:  *     Put in changes for swapping.
        !            93:  *     [1991/11/21  20:32:15  mmp]
        !            94:  *     [94/07/27            barbou]
        !            95:  *     [95/03/08            barbou]
        !            96:  * 
        !            97:  * Revision 1.2.31.7  1995/02/28  01:58:38  dwm
        !            98:  *     mk6 CR1120 - Merge mk6pro_shared into cnmk_shared
        !            99:  *     * Rev1.2.43.1  1995/01/27  22:01:26  bolinger
        !           100:  *     * Fix ri-osc CR977:  Make "show space" and "show ipc_port" give
        !           101:  *     * accurate count of ports active in IPC space.  Make "show ipc_port"
        !           102:  *     * output task-visible port name.
        !           103:  *     [1995/02/28  01:12:46  dwm]
        !           104:  * 
        !           105:  * Revision 1.2.31.6  1995/02/23  21:43:34  alanl
        !           106:  *     Fix db_show_one_task_vm for thread_act_ts.
        !           107:  *     [95/01/09            rwd]
        !           108:  * 
        !           109:  *     Merged with DIPC2_SHARED.
        !           110:  *     [95/01/04            alanl]
        !           111:  * 
        !           112:  * Revision 1.2.31.5  1995/01/10  04:49:52  devrcs
        !           113:  *     mk6 CR801 - merge up from nmk18b4 to nmk18b7
        !           114:  *     Fix "sh thr/ul"; no cont. to print, fix pri/policy format.
        !           115:  *     * Rev 1.2.31.4  1994/10/11  16:35:58  emcmanus
        !           116:  *       Added "show runq" and "show shuttle".
        !           117:  *     [1994/12/09  20:36:49  dwm]
        !           118:  * 
        !           119:  *     mk6 CR668 - 1.3b26 merge
        !           120:  *     * Revision 1.2.8.6  1994/05/06  18:39:37  tmt
        !           121:  *     Merged osc1.3dec/shared with osc1.3b19
        !           122:  *     Merge Alpha changes into osc1.312b source code.
        !           123:  *     64bit cleanup.
        !           124:  *     * End1.3merge
        !           125:  *     [1994/11/04  08:49:52  dwm]
        !           126:  * 
        !           127:  * Revision 1.2.31.3  1994/09/23  01:20:51  ezf
        !           128:  *     change marker to not FREE
        !           129:  *     [1994/09/22  21:10:41  ezf]
        !           130:  * 
        !           131:  * Revision 1.2.31.2  1994/06/14  17:21:05  bolinger
        !           132:  *     Merge up to NMK17.2.
        !           133:  *     [1994/06/14  17:20:35  bolinger]
        !           134:  * 
        !           135:  * Revision 1.2.23.4  1994/04/15  18:41:31  paire
        !           136:  *     Changed interface of db_task_from_space routine.
        !           137:  *     [94/03/31            paire]
        !           138:  * 
        !           139:  * Revision 1.2.23.3  1994/03/07  16:37:48  paire
        !           140:  *     Merge with Intel R1_1
        !           141:  *     Change from NMK14.10 [1993/11/15  16:06:21  rwd]
        !           142:  * 
        !           143:  *     Enhanced pretty print routine and added db_task_from_space.
        !           144:  *     Change from NMK14.10 [93/09/24            sjs]
        !           145:  *     [94/02/21            paire]
        !           146:  * 
        !           147:  *     Exported ANSI prototype of db_port_kmsg_count routine.
        !           148:  *     Added header file include for the declaration of db_norma_ipc routine.
        !           149:  *     [94/02/15            paire]
        !           150:  * 
        !           151:  * Revision 1.2.23.2  1994/02/11  14:21:58  paire
        !           152:  *     Added new vm_print.h header file for db_vm declaration.
        !           153:  *     [94/02/09            paire]
        !           154:  * 
        !           155:  * Revision 1.2.23.1  1994/02/08  10:58:19  bernadat
        !           156:  *     print out msgcount for each port in db_port_iterate
        !           157:  *     Change from NORMA_MK14.6(August 93) [1993/07/27  12:35:17  mmp]
        !           158:  * 
        !           159:  *     Removed defintion of db_maxoff (got from <ddb/db_sym.h>).
        !           160:  *     [93/08/12            paire]
        !           161:  * 
        !           162:  *     Show ipc_space_remote msg counts only if NORMA_IPC is on
        !           163:  *     [93/07/21            bernadat]
        !           164:  * 
        !           165:  *     Add /s option to "show ipc_port" to pick out port sets.
        !           166:  *     Change from NORMA_MK14.6 [1993/02/17  16:29:54  dwm]
        !           167:  *     [93/07/16            bernadat]
        !           168:  *     [94/02/07            bernadat]
        !           169:  * 
        !           170:  * Revision 1.2.20.8  1994/06/08  19:11:15  dswartz
        !           171:  *     Preemption merge.
        !           172:  *     [1994/06/08  19:10:18  dswartz]
        !           173:  * 
        !           174:  * Revision 1.2.20.7  1994/04/30  21:28:24  bolinger
        !           175:  *     Thread control ops synchronization:  now that TH_SUSP is back,
        !           176:  *     enable ddb to show it when printing thread state.
        !           177:  *     [1994/04/28  21:55:42  bolinger]
        !           178:  * 
        !           179:  * Revision 1.2.20.6  1994/03/17  22:35:31  dwm
        !           180:  *     The infamous name change:  thread_activation + thread_shuttle = thread.
        !           181:  *     [1994/03/17  21:25:46  dwm]
        !           182:  * 
        !           183:  * Revision 1.2.20.5  1994/01/26  15:43:37  bolinger
        !           184:  *     Move kernel_stack from thread to activation.
        !           185:  *     [1994/01/25  21:53:11  bolinger]
        !           186:  * 
        !           187:  * Revision 1.2.20.4  1994/01/12  17:50:44  dwm
        !           188:  *     Coloc: initial restructuring to follow Utah model.
        !           189:  *     [1994/01/12  17:13:12  dwm]
        !           190:  * 
        !           191:  * Revision 1.2.20.3  1993/11/18  18:11:47  dwm
        !           192:  *     Coloc: remove continuations entirely; they are incompatible
        !           193:  *     with migration, and their volume is obfuscatory.
        !           194:  *     [1993/11/18  18:06:27  dwm]
        !           195:  * 
        !           196:  * Revision 1.2.20.2  1993/10/12  16:38:50  dwm
        !           197:  *     CoLoc: neuter continuations, ifdef USE_CONTINUATIONS.
        !           198:  *     [1993/10/12  16:14:46  dwm]
        !           199:  * 
        !           200:  * Revision 1.2.8.4  1993/08/11  20:38:06  elliston
        !           201:  *     Add ANSI Prototypes.  CR #9523.
        !           202:  *     [1993/08/11  03:33:51  elliston]
        !           203:  * 
        !           204:  * Revision 1.2.8.3  1993/07/27  18:27:55  elliston
        !           205:  *     Add ANSI prototypes.  CR #9523.
        !           206:  *     [1993/07/27  18:12:39  elliston]
        !           207:  * 
        !           208:  * Revision 1.2.8.2  1993/06/09  02:20:35  gm
        !           209:  *     CR9176 - ANSI C violations: trailing tokens on CPP
        !           210:  *     directives, extra semicolons after decl_ ..., asm keywords
        !           211:  *     [1993/06/07  18:57:22  jeffc]
        !           212:  * 
        !           213:  *     Removed a '#if MACH_FIXPRI' which somehow survived the purge.  CR #9131.
        !           214:  *     [1993/05/11  20:56:00  dswartz]
        !           215:  * 
        !           216:  * Revision 1.2  1993/04/19  16:02:50  devrcs
        !           217:  *     Added printout of thread scheduling policy to long form
        !           218:  *     of thread display.
        !           219:  *     [93/01/28            jat]
        !           220:  * 
        !           221:  *     Changes from mk78:
        !           222:  *     Removed unused variable from db_show_regs().
        !           223:  *     [92/05/16            jfriedl]
        !           224:  *     Converted some db_printsyms to db_task_printsyms.
        !           225:  *     [92/04/10            danner]
        !           226:  *     Changed db_print_thread so that both display formats
        !           227:  *     show the floating-point-used status of the thread.
        !           228:  *     [92/03/16            rpd]
        !           229:  *     [93/02/02            bruel]
        !           230:  * 
        !           231:  * Revision 1.1  1992/09/30  02:01:18  robert
        !           232:  *     Initial revision
        !           233:  * 
        !           234:  * $EndLog$
        !           235:  */
        !           236: /* CMU_HIST */
        !           237: /*
        !           238:  * Revision 2.11.3.2  92/04/08  15:43:10  jeffreyh
        !           239:  *     Added i option to show thread. This gives wait state information.
        !           240:  *     [92/04/08            sjs]
        !           241:  * 
        !           242:  * Revision 2.11.3.1  92/03/03  16:13:34  jeffreyh
        !           243:  *     Pick up changes from TRUNK
        !           244:  *     [92/02/26  11:00:01  jeffreyh]
        !           245:  * 
        !           246:  * Revision 2.13  92/02/20  18:34:28  elf
        !           247:  *     Fixed typo.
        !           248:  *     [92/02/20            elf]
        !           249:  * 
        !           250:  * Revision 2.12  92/02/19  15:07:47  elf
        !           251:  *     Added db_thread_fp_used, to avoid machine-dependent conditionals.
        !           252:  *     [92/02/19            rpd]
        !           253:  * 
        !           254:  *     Added 'F' flag to db_thread_stat showing if the thread has a valid
        !           255:  *     FPU context. Tested on i386 and pmax.
        !           256:  *     [92/02/17            kivinen]
        !           257:  * 
        !           258:  * Revision 2.11  91/11/12  11:50:32  rvb
        !           259:  *     Added OPTION_USER ("/u") to db_show_all_threads, db_show_one_thread,
        !           260:  *     db_show_one_task.  Without it, we display old-style information.
        !           261:  *     [91/10/31            rpd]
        !           262:  * 
        !           263:  * Revision 2.10  91/10/09  16:01:48  af
        !           264:  *     Supported "show registers" for non current thread.
        !           265:  *     Changed display format of thread and task information.
        !           266:  *     Changed "show thread" to print current thread information 
        !           267:  *       if no thread is specified.
        !           268:  *     Added "show_one_task" for "show task" command.
        !           269:  *     Added IPC port print routines for "show ipc_port" command.
        !           270:  *     [91/08/29            tak]
        !           271:  * 
        !           272:  * Revision 2.9  91/08/03  18:17:19  jsb
        !           273:  *     In db_print_thread, if the thread is swapped and there is a
        !           274:  *     continuation function, print the function name in parentheses
        !           275:  *     instead of '(swapped)'.
        !           276:  *     [91/07/04  09:59:27  jsb]
        !           277:  * 
        !           278:  * Revision 2.8  91/07/31  17:30:43  dbg
        !           279:  *     Revise scheduling state machine.
        !           280:  *     [91/07/30  16:43:42  dbg]
        !           281:  * 
        !           282:  * Revision 2.7  91/07/09  23:15:57  danner
        !           283:  *     Fixed a few printf that should be db_printfs. 
        !           284:  *     [91/07/08            danner]
        !           285:  * 
        !           286:  * Revision 2.6  91/05/14  15:35:25  mrt
        !           287:  *     Correcting copyright
        !           288:  * 
        !           289:  * Revision 2.5  91/02/05  17:06:53  mrt
        !           290:  *     Changed to new Mach copyright
        !           291:  *     [91/01/31  16:18:56  mrt]
        !           292:  * 
        !           293:  * Revision 2.4  90/10/25  14:43:54  rwd
        !           294:  *     Changed db_show_regs to print unsigned.
        !           295:  *     [90/10/19            rpd]
        !           296:  *     Generalized the watchpoint support.
        !           297:  *     [90/10/16            rwd]
        !           298:  * 
        !           299:  * Revision 2.3  90/09/09  23:19:52  rpd
        !           300:  *     Avoid totally incorrect guesses of symbol names for small values.
        !           301:  *     [90/08/30  17:39:08  af]
        !           302:  * 
        !           303:  * Revision 2.2  90/08/27  21:51:49  dbg
        !           304:  *     Insist that 'show thread' be called with an explicit address.
        !           305:  *     [90/08/22            dbg]
        !           306:  * 
        !           307:  *     Fix type for db_maxoff.
        !           308:  *     [90/08/20            dbg]
        !           309:  * 
        !           310:  *     Do not dereference the "valuep" field of a variable directly,
        !           311:  *     call the new db_read/write_variable functions instead.
        !           312:  *     Reflected changes in symbol lookup functions.
        !           313:  *     [90/08/20            af]
        !           314:  *     Reduce lint.
        !           315:  *     [90/08/10  14:33:44  dbg]
        !           316:  * 
        !           317:  *     Created.
        !           318:  *     [90/07/25            dbg]
        !           319:  * 
        !           320:  */
        !           321: /* CMU_ENDHIST */
        !           322: /*
        !           323:  * Mach Operating System
        !           324:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !           325:  * All Rights Reserved.
        !           326:  * 
        !           327:  * Permission to use, copy, modify and distribute this software and its
        !           328:  * documentation is hereby granted, provided that both the copyright
        !           329:  * notice and this permission notice appear in all copies of the
        !           330:  * software, derivative works or modified versions, and any portions
        !           331:  * thereof, and that both notices appear in supporting documentation.
        !           332:  * 
        !           333:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !           334:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !           335:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !           336:  * 
        !           337:  * Carnegie Mellon requests users of this software to return to
        !           338:  * 
        !           339:  *  Software Distribution Coordinator  or  [email protected]
        !           340:  *  School of Computer Science
        !           341:  *  Carnegie Mellon University
        !           342:  *  Pittsburgh PA 15213-3890
        !           343:  * 
        !           344:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           345:  * the rights to redistribute these changes.
        !           346:  */
        !           347: /*
        !           348:  */
        !           349: /*
        !           350:  *     Author: David B. Golub, Carnegie Mellon University
        !           351:  *     Date:   7/90
        !           352:  */
        !           353: 
        !           354: /*
        !           355:  * Miscellaneous printing.
        !           356:  */
        !           357: #include <dipc.h>
        !           358: #include <task_swapper.h>
        !           359: 
        !           360: #include <string.h>                    /* For strlen() */
        !           361: #include <mach/port.h>
        !           362: #include <kern/task.h>
        !           363: #include <kern/thread.h>
        !           364: #include <kern/thread_swap.h>
        !           365: #include <kern/queue.h>
        !           366: #include <ipc/ipc_port.h>
        !           367: #include <ipc/ipc_space.h>
        !           368: #include <ipc/ipc_pset.h>
        !           369: #include <vm/vm_print.h>               /* for db_vm() */
        !           370: 
        !           371: #include <machine/db_machdep.h>
        !           372: #include <machine/thread.h>
        !           373: 
        !           374: #include <ddb/db_lex.h>
        !           375: #include <ddb/db_variables.h>
        !           376: #include <ddb/db_sym.h>
        !           377: #include <ddb/db_task_thread.h>
        !           378: #include <ddb/db_command.h>
        !           379: #include <ddb/db_output.h>             /* For db_printf() */
        !           380: #include <ddb/db_print.h>
        !           381: 
        !           382: #include <kern/sf.h>
        !           383: #include <kern/sp_mk.h>        /*** ??? fix so this can be removed ***/
        !           384: 
        !           385: #if    TASK_SWAPPER
        !           386: #include <kern/task_swap.h>
        !           387: #endif /* TASK_SWAPPER */
        !           388: 
        !           389: /* Prototypes for functions local to this file.  XXX -- should be static!
        !           390:  */
        !           391: 
        !           392: char *db_act_stat(
        !           393:        register thread_act_t   thr_act,
        !           394:        char                    *status);
        !           395: 
        !           396: char *db_act_swap_stat(
        !           397:        register thread_act_t   thr_act,
        !           398:        char                    *status);
        !           399: 
        !           400: void db_print_task(
        !           401:        task_t  task,
        !           402:        int     task_id,
        !           403:        int     flag);
        !           404: 
        !           405: void db_reset_print_entry(
        !           406:        void);
        !           407: 
        !           408: void db_print_one_entry(
        !           409:        ipc_entry_t     entry,
        !           410:        int             index,
        !           411:        mach_port_name_t        name,
        !           412:        boolean_t       is_pset);
        !           413: 
        !           414: int db_port_iterate(
        !           415:        thread_act_t    thr_act,
        !           416:        boolean_t       is_pset,
        !           417:        boolean_t       do_output);
        !           418: 
        !           419: ipc_port_t db_lookup_port(
        !           420:        thread_act_t    thr_act,
        !           421:        int             id);
        !           422: 
        !           423: static void db_print_port_id(
        !           424:        int             id,
        !           425:        ipc_port_t      port,
        !           426:        unsigned        bits,
        !           427:        int             n);
        !           428: 
        !           429: void db_print_act(
        !           430:        thread_act_t    thr_act,
        !           431:        int             act_id,
        !           432:        int             flag);
        !           433: 
        !           434: void db_print_space(
        !           435:        task_t  task,
        !           436:        int     task_id,
        !           437:        int     flag);
        !           438: 
        !           439: void db_print_task_vm(
        !           440:        task_t          task,
        !           441:        int             task_id,
        !           442:        boolean_t       title,
        !           443:        char            *modif);
        !           444: 
        !           445: void db_system_stats(void);
        !           446: 
        !           447: 
        !           448: void
        !           449: db_show_regs(
        !           450:        db_expr_t       addr,
        !           451:        boolean_t       have_addr,
        !           452:        db_expr_t       count,
        !           453:        char            *modif)
        !           454: {
        !           455:        register struct db_variable *regp;
        !           456:        db_expr_t       value;
        !           457:        db_addr_t       offset;
        !           458:        char *          name;
        !           459:        register int    i; 
        !           460:        struct db_var_aux_param aux_param;
        !           461:        task_t          task = TASK_NULL;
        !           462: 
        !           463:        aux_param.modif = modif;
        !           464:        aux_param.thr_act = THR_ACT_NULL;
        !           465:        if (db_option(modif, 't')) {
        !           466:            if (have_addr) {
        !           467:                if (!db_check_act_address_valid((thread_act_t)addr))
        !           468:                    return;
        !           469:                aux_param.thr_act = (thread_act_t)addr;
        !           470:            } else
        !           471:                aux_param.thr_act = db_default_act;
        !           472:            if (aux_param.thr_act != THR_ACT_NULL)
        !           473:                task = aux_param.thr_act->task;
        !           474:        }
        !           475:        for (regp = db_regs; regp < db_eregs; regp++) {
        !           476:            if (regp->max_level > 1) {
        !           477:                db_printf("bad multi-suffixed register %s\n", regp->name);
        !           478:                continue;
        !           479:            }
        !           480:            aux_param.level = regp->max_level;
        !           481:            for (i = regp->low; i <= regp->high; i++) {
        !           482:                aux_param.suffix[0] = i;
        !           483:                db_read_write_variable(regp, &value, DB_VAR_GET, &aux_param);
        !           484:                if (regp->max_level > 0)
        !           485:                    db_printf("%s%d%*s", regp->name, i, 
        !           486:                                12-strlen(regp->name)-((i<10)?1:2), "");
        !           487:                else
        !           488:                    db_printf("%-12s", regp->name);
        !           489:                db_printf("%#*N", 2+2*sizeof(vm_offset_t), value);
        !           490:                db_find_xtrn_task_sym_and_offset((db_addr_t)value, &name, 
        !           491:                                                        &offset, task);
        !           492:                if (name != 0 && offset <= db_maxoff && offset != value) {
        !           493:                    db_printf("\t%s", name);
        !           494:                    if (offset != 0)
        !           495:                        db_printf("+%#r", offset);
        !           496:                }
        !           497:                db_printf("\n");
        !           498:            }
        !           499:        }
        !           500: }
        !           501: 
        !           502: #define OPTION_LONG            0x001           /* long print option */
        !           503: #define OPTION_USER            0x002           /* print ps-like stuff */
        !           504: #define OPTION_INDENT          0x100           /* print with indent */
        !           505: #define OPTION_THREAD_TITLE    0x200           /* print thread title */
        !           506: #define OPTION_TASK_TITLE      0x400           /* print thread title */
        !           507: 
        !           508: #ifndef        DB_TASK_NAME
        !           509: #define DB_TASK_NAME(task)                     /* no task name */
        !           510: #define DB_TASK_NAME_TITLE     ""              /* no task name */
        !           511: #endif /* DB_TASK_NAME */
        !           512: 
        !           513: #ifndef        db_act_fp_used
        !           514: #define db_act_fp_used(thr_act)        FALSE
        !           515: #endif
        !           516: 
        !           517: char *
        !           518: db_act_stat(
        !           519:        register thread_act_t   thr_act,
        !           520:        char                    *status)
        !           521: {
        !           522:        register char *p = status;
        !           523:        
        !           524:        if (!thr_act->active) {
        !           525:                *p++ = 'D',
        !           526:                *p++ = 'y',
        !           527:                *p++ = 'i',
        !           528:                *p++ = 'n',
        !           529:                *p++ = 'g';
        !           530:                *p++ = ' ';
        !           531:        } else if (!thr_act->thread) {
        !           532:                *p++ = 'E',
        !           533:                *p++ = 'm',
        !           534:                *p++ = 'p',
        !           535:                *p++ = 't',
        !           536:                *p++ = 'y';
        !           537:                *p++ = ' ';
        !           538:        } else {
        !           539:                thread_t athread = thr_act->thread;
        !           540: 
        !           541:                *p++ = (athread->state & TH_RUN)  ? 'R' : '.';
        !           542:                *p++ = (athread->state & TH_WAIT) ? 'W' : '.';
        !           543:                *p++ = (athread->state & TH_SUSP) ? 'S' : '.';
        !           544:                *p++ = (athread->state & TH_SWAPPED_OUT) ? 'O' : '.';
        !           545:                *p++ = (athread->state & TH_UNINT) ? 'N' : '.';
        !           546:                /* show if the FPU has been used */
        !           547:                *p++ = db_act_fp_used(thr_act) ? 'F' : '.';
        !           548:        }
        !           549:        *p++ = 0;
        !           550:        return(status);
        !           551: }
        !           552: 
        !           553: char *
        !           554: db_act_swap_stat(
        !           555:        register thread_act_t   thr_act,
        !           556:        char                    *status)
        !           557: {
        !           558:        register char *p = status;
        !           559: 
        !           560: #if    THREAD_SWAPPER
        !           561:        switch (thr_act->swap_state & TH_SW_STATE) {
        !           562:            case TH_SW_UNSWAPPABLE:
        !           563:                *p++ = 'U';
        !           564:                break;
        !           565:            case TH_SW_IN:
        !           566:                *p++ = 'I';
        !           567:                break;
        !           568:            case TH_SW_GOING_OUT:
        !           569:                *p++ = 'G';
        !           570:                break;
        !           571:            case TH_SW_WANT_IN:
        !           572:                *p++ = 'W';
        !           573:                break;
        !           574:            case TH_SW_OUT:
        !           575:                *p++ = 'O';
        !           576:                break;
        !           577:            case TH_SW_COMING_IN:
        !           578:                *p++ = 'C';
        !           579:                break;
        !           580:            default:
        !           581:                *p++ = '?';
        !           582:                break;
        !           583:        }
        !           584:        *p++ = (thr_act->swap_state & TH_SW_TASK_SWAPPING) ? 'T' : '.';
        !           585: #endif /* THREAD_SWAPPER */
        !           586:        *p++ = 0;
        !           587: 
        !           588:        return status;
        !           589: }
        !           590: 
        !           591: char   *policy_list[] = { "TS", "RR", "??", "FF",
        !           592:                           "??", "??", "??", "BE"};
        !           593: 
        !           594: void
        !           595: db_print_act(
        !           596:        thread_act_t    thr_act,
        !           597:        int             act_id,
        !           598:        int             flag)
        !           599: {
        !           600:        thread_t athread;
        !           601:        char status[8];
        !           602:        char swap_status[3];
        !           603:        char *indent = "";
        !           604:        int      policy;
        !           605: 
        !           606:        if (!thr_act) {
        !           607:            db_printf("db_print_act(NULL)!\n");
        !           608:            return;
        !           609:        }
        !           610: 
        !           611:        athread = thr_act->thread;
        !           612:        if (flag & OPTION_USER) {
        !           613: 
        !           614:            if (flag & OPTION_LONG) {
        !           615:                if (flag & OPTION_INDENT)
        !           616:                    indent = "    ";
        !           617:                if (flag & OPTION_THREAD_TITLE) {
        !           618:                    db_printf("%s ID:   ACT     STAT  SW STACK    SHUTTLE", indent);
        !           619:                    db_printf("  SUS  PRI  WAIT_FUNC\n");
        !           620:                }
        !           621:                policy = (athread ? athread->policy : 2);
        !           622:                db_printf("%s%3d%c %0*X %s %s %0*X %0*X %3d %3d/%s ",
        !           623:                    indent, act_id,
        !           624:                    (thr_act == current_act())? '#': ':',
        !           625:                    2*sizeof(vm_offset_t), thr_act,
        !           626:                    db_act_stat(thr_act, status),
        !           627:                    db_act_swap_stat(thr_act, swap_status),
        !           628:                    2*sizeof(vm_offset_t), (athread ?athread->kernel_stack:0),
        !           629:                    2*sizeof(vm_offset_t), athread,
        !           630:                    thr_act->suspend_count,
        !           631:                    (athread ? athread->sched_pri : 999), /* XXX */
        !           632:                    policy_list[policy-1]);
        !           633:                if (athread) {
        !           634:                    /* no longer TH_SWAP, no continuation to print */
        !           635:                    if (athread->state & TH_WAIT)
        !           636:                        db_task_printsym((db_addr_t)athread->wait_event,
        !           637:                                                DB_STGY_ANY, kernel_task);
        !           638:                }
        !           639:                db_printf("\n");
        !           640:            } else {
        !           641:                if (act_id % 3 == 0) {
        !           642:                    if (flag & OPTION_INDENT)
        !           643:                        db_printf("\n    ");
        !           644:                } else
        !           645:                    db_printf(" ");
        !           646:                db_printf("%3d%c(%0*X,%s)", act_id, 
        !           647:                    (thr_act == current_act())? '#': ':',
        !           648:                    2*sizeof(vm_offset_t), thr_act,
        !           649:                    db_act_stat(thr_act, status));
        !           650:            }
        !           651:        } else {
        !           652:            if (flag & OPTION_INDENT)
        !           653:                db_printf("            %3d (%0*X) ", act_id,
        !           654:                          2*sizeof(vm_offset_t), thr_act);
        !           655:            else
        !           656:                db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thr_act);
        !           657:            if (athread) {
        !           658:                db_printf("%c%c%c%c%c",
        !           659:                        (athread->state & TH_RUN)  ? 'R' : ' ',
        !           660:                        (athread->state & TH_WAIT) ? 'W' : ' ',
        !           661:                        (athread->state & TH_SUSP) ? 'S' : ' ',
        !           662:                        (athread->state & TH_UNINT)? 'N' : ' ',
        !           663:                        db_act_fp_used(thr_act) ? 'F' : ' ');
        !           664:                /* Obsolete TH_STACK_HANDOFF code, left for now; might enhance
        !           665:                 * to print out safe_points instead */
        !           666:                if (athread->state & TH_STACK_HANDOFF) {
        !           667:                    if (athread->continuation) {
        !           668:                        db_printf("(");
        !           669:                        db_task_printsym((db_addr_t)athread->continuation,
        !           670:                                                DB_STGY_ANY, kernel_task);
        !           671:                        db_printf(")");
        !           672:                    } else {
        !           673:                        db_printf("(handoff)");
        !           674:                    }
        !           675:                }
        !           676:                if (athread->state & TH_WAIT) {
        !           677:                    db_printf(" ");
        !           678:                    db_task_printsym((db_addr_t)athread->wait_event,
        !           679:                                                DB_STGY_ANY, kernel_task);
        !           680:                }
        !           681:            } else
        !           682:                db_printf("Empty");
        !           683:            db_printf("\n");
        !           684:        }
        !           685: }
        !           686: 
        !           687: void
        !           688: db_print_task(
        !           689:        task_t  task,
        !           690:        int     task_id,
        !           691:        int     flag)
        !           692: {
        !           693:        thread_act_t thr_act;
        !           694:        int act_id;
        !           695:        char sstate;
        !           696: 
        !           697:        if (flag & OPTION_USER) {
        !           698:            if (flag & OPTION_TASK_TITLE) {
        !           699:                db_printf(" ID: TASK     MAP      THD RES SUS PR SW %s", 
        !           700:                          DB_TASK_NAME_TITLE);
        !           701:                if ((flag & OPTION_LONG) == 0)
        !           702:                    db_printf("  ACTS");
        !           703:                db_printf("\n");
        !           704:            }
        !           705: #if    TASK_SWAPPER
        !           706:            switch ((int) task->swap_state) {
        !           707:                case TASK_SW_IN:
        !           708:                    sstate = 'I';
        !           709:                    break;
        !           710:                case TASK_SW_OUT:
        !           711:                    sstate = 'O';
        !           712:                    break;
        !           713:                case TASK_SW_GOING_OUT:
        !           714:                    sstate = 'G';
        !           715:                    break;
        !           716:                case TASK_SW_COMING_IN:
        !           717:                    sstate = 'C';
        !           718:                    break;
        !           719:                case TASK_SW_UNSWAPPABLE:
        !           720:                    sstate = 'U';
        !           721:                    break;
        !           722:                default:
        !           723:                    sstate = '?';
        !           724:                    break;
        !           725:            }
        !           726: #else  /* TASK_SWAPPER */
        !           727:            sstate = 'I';
        !           728: #endif /* TASK_SWAPPER */
        !           729:            /*** ??? fix me ***/
        !           730:            db_printf("%3d: %0*X %0*X %3d %3d %3d %2d %c  ",
        !           731:                            task_id, 2*sizeof(vm_offset_t), task,
        !           732:                            2*sizeof(vm_offset_t), task->map,
        !           733:                            task->thr_act_count, task->res_act_count,
        !           734:                            task->suspend_count,
        !           735:                            ((mk_sp_attributes_t)(task->sp_attributes))->priority,
        !           736:                            sstate);
        !           737:            DB_TASK_NAME(task);
        !           738:            if (flag & OPTION_LONG) {
        !           739:                if (flag & OPTION_TASK_TITLE)
        !           740:                    flag |= OPTION_THREAD_TITLE;
        !           741:                db_printf("\n");
        !           742:            } else if (task->thr_act_count <= 1)
        !           743:                flag &= ~OPTION_INDENT;
        !           744:            act_id = 0;
        !           745:            queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) {
        !           746:                db_print_act(thr_act, act_id, flag);
        !           747:                flag &= ~OPTION_THREAD_TITLE;
        !           748:                act_id++;
        !           749:            }
        !           750:            if ((flag & OPTION_LONG) == 0)
        !           751:                db_printf("\n");
        !           752:        } else {
        !           753:            if (flag & OPTION_LONG) {
        !           754:                if (flag & OPTION_TASK_TITLE) {
        !           755:                    db_printf("    TASK        ACT\n");
        !           756:                    if (task->thr_act_count > 1)
        !           757:                        flag |= OPTION_THREAD_TITLE;
        !           758:                }
        !           759:            }
        !           760:            db_printf("%3d (%0*X): ", task_id, 2*sizeof(vm_offset_t), task);
        !           761:            if (task->thr_act_count == 0) {
        !           762:                db_printf("no threads\n");
        !           763:            } else {
        !           764:                if (task->thr_act_count > 1) {
        !           765:                    db_printf("%d threads: \n", task->thr_act_count);
        !           766:                    flag |= OPTION_INDENT;
        !           767:                } else
        !           768:                    flag &= ~OPTION_INDENT;
        !           769:                act_id = 0;
        !           770:                queue_iterate(&task->thr_acts, thr_act,
        !           771:                              thread_act_t, thr_acts) {
        !           772:                    db_print_act(thr_act, act_id++, flag);
        !           773:                    flag &= ~OPTION_THREAD_TITLE;
        !           774:                }
        !           775:            }
        !           776:        }
        !           777: }
        !           778: 
        !           779: void
        !           780: db_print_space(
        !           781:        task_t  task,
        !           782:        int     task_id,
        !           783:        int     flag)
        !           784: {
        !           785:        ipc_space_t space;
        !           786:        thread_act_t act = (thread_act_t)queue_first(&task->thr_acts);
        !           787:        int count;
        !           788: 
        !           789:        count = 0;
        !           790:        space = task->itk_space;
        !           791:        if (act)
        !           792:                count = db_port_iterate(act, FALSE, FALSE);
        !           793:        db_printf("%3d: %08x %08x %08x %sactive   %d\n",
        !           794:                  task_id, task, space, task->map,
        !           795:                  space->is_active? "":"!", count);
        !           796: }
        !           797: 
        !           798: void
        !           799: db_print_task_vm(
        !           800:        task_t          task,
        !           801:        int             task_id,
        !           802:        boolean_t       title,
        !           803:        char            *modif)
        !           804: {
        !           805:        vm_map_t        map;
        !           806:        pmap_t          pmap;
        !           807:        vm_size_t       size;
        !           808:        long            resident;
        !           809:        long            wired;
        !           810: 
        !           811:        if (title) {
        !           812:                db_printf("id     task      map     pmap  virtual  rss pg rss mem  wir pg wir mem\n");
        !           813:        }
        !           814: 
        !           815:        map = task->map;
        !           816:        pmap = vm_map_pmap(map);
        !           817: 
        !           818:        size = db_vm_map_total_size(map);
        !           819:        resident = pmap->stats.resident_count;
        !           820:        wired = pmap->stats.wired_count;
        !           821: 
        !           822:        db_printf("%2d %08x %08x %08x %7dK  %6d %6dK  %6d %6dK\n",
        !           823:                task_id,
        !           824:                task,
        !           825:                map,
        !           826:                pmap,
        !           827:                size / 1024,
        !           828:                resident, (resident * PAGE_SIZE) / 1024,
        !           829:                wired, (wired * PAGE_SIZE) / 1024);
        !           830: }
        !           831: 
        !           832: 
        !           833: void
        !           834: db_show_one_task_vm(
        !           835:        db_expr_t       addr,
        !           836:        boolean_t       have_addr,
        !           837:        db_expr_t       count,
        !           838:        char            *modif)
        !           839: {
        !           840:        thread_act_t    thread;
        !           841:        task_t          task;
        !           842:        int             task_id;
        !           843: 
        !           844:        if (have_addr == FALSE) {
        !           845:                if ((thread = db_default_act) == THR_ACT_NULL) {
        !           846:                        if ((thread = current_act()) == THR_ACT_NULL) {
        !           847:                                db_printf("no thread.\n");
        !           848:                                return;
        !           849:                        }
        !           850:                }
        !           851:                task = thread->task;
        !           852:        } else {
        !           853:                task = (task_t) addr;
        !           854:        }
        !           855: 
        !           856:        task_id = db_lookup_task(task);
        !           857:        if (task_id < 0) {
        !           858:                db_printf("0x%x is not a task_t\n", addr);
        !           859:                return;
        !           860:        }
        !           861: 
        !           862:        db_print_task_vm(task, task_id, TRUE, modif);
        !           863: }
        !           864: 
        !           865: void
        !           866: db_show_all_task_vm(
        !           867:        db_expr_t       addr,
        !           868:        boolean_t       have_addr,
        !           869:        db_expr_t       count,
        !           870:        char            *modif)
        !           871: {
        !           872:        task_t          task;
        !           873:        int             task_id;
        !           874:        boolean_t       title = TRUE;
        !           875:        processor_set_t pset;
        !           876: 
        !           877:        task_id = 0;
        !           878:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           879:                queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           880:                        db_print_task_vm(task, task_id, title, modif);
        !           881:                        title = FALSE;
        !           882:                        task_id++;
        !           883:                }
        !           884:        }
        !           885: }
        !           886: 
        !           887: void
        !           888: db_show_all_acts(
        !           889:        db_expr_t       addr,
        !           890:        boolean_t       have_addr,
        !           891:        db_expr_t       count,
        !           892:        char *          modif)
        !           893: {
        !           894:        task_t task;
        !           895:        int task_id;
        !           896:        int flag;
        !           897:        processor_set_t pset;
        !           898: 
        !           899:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !           900:        if (db_option(modif, 'u'))
        !           901:            flag |= OPTION_USER;
        !           902:        if (db_option(modif, 'l'))
        !           903:            flag |= OPTION_LONG;
        !           904: 
        !           905:        task_id = 0;
        !           906:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           907:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           908:                db_print_task(task, task_id, flag);
        !           909:                flag &= ~OPTION_TASK_TITLE;
        !           910:                task_id++;
        !           911:                if ((flag & (OPTION_LONG|OPTION_INDENT)) == OPTION_INDENT)
        !           912:                    db_printf("\n");
        !           913:            }
        !           914:        }
        !           915: }
        !           916: 
        !           917: void
        !           918: db_show_one_space(
        !           919:        db_expr_t       addr,
        !           920:        boolean_t       have_addr,
        !           921:        db_expr_t       count,
        !           922:        char *          modif)
        !           923: {
        !           924:        int             flag;
        !           925:        int             task_id;
        !           926:        task_t          task;
        !           927: 
        !           928:        flag = OPTION_TASK_TITLE;
        !           929:        if (db_option(modif, 'u'))
        !           930:            flag |= OPTION_USER;
        !           931:        if (db_option(modif, 'l'))
        !           932:            flag |= OPTION_LONG;
        !           933: 
        !           934:        if (!have_addr) {
        !           935:            task = db_current_task();
        !           936:            if (task == TASK_NULL) {
        !           937:                db_error("No task\n");
        !           938:                /*NOTREACHED*/
        !           939:            }
        !           940:        } else
        !           941:            task = (task_t) addr;
        !           942: 
        !           943:        if ((task_id = db_lookup_task(task)) < 0) {
        !           944:            db_printf("bad task address 0x%x\n", addr);
        !           945:            db_error(0);
        !           946:            /*NOTREACHED*/
        !           947:        }
        !           948: 
        !           949:        db_printf(" ID: TASK     SPACE    MAP               COUNT\n");
        !           950:        db_print_space(task, task_id, flag);
        !           951: }
        !           952: 
        !           953: void
        !           954: db_show_all_spaces(
        !           955:        db_expr_t       addr,
        !           956:        boolean_t       have_addr,
        !           957:        db_expr_t       count,
        !           958:        char *          modif)
        !           959: {
        !           960:        task_t task;
        !           961:        int task_id = 0;
        !           962:        int flag;
        !           963:        processor_set_t pset;
        !           964: 
        !           965:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !           966:        if (db_option(modif, 'u'))
        !           967:            flag |= OPTION_USER;
        !           968:        if (db_option(modif, 'l'))
        !           969:            flag |= OPTION_LONG;
        !           970: 
        !           971:        db_printf(" ID: TASK     SPACE    MAP               COUNT\n");
        !           972:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           973:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           974:                    db_print_space(task, task_id, flag);
        !           975:                    task_id++;
        !           976:            }
        !           977:        }
        !           978: }
        !           979: 
        !           980: db_addr_t
        !           981: db_task_from_space(
        !           982:        ipc_space_t     space,
        !           983:        int             *task_id)
        !           984: {
        !           985:        task_t task;
        !           986:        int tid = 0;
        !           987:        processor_set_t pset;
        !           988: 
        !           989:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           990:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           991:                    if (task->itk_space == space) {
        !           992:                            *task_id = tid;
        !           993:                            return (db_addr_t)task;
        !           994:                    }
        !           995:                    tid++;
        !           996:            }
        !           997:        }
        !           998:        *task_id = 0;
        !           999:        return (0);
        !          1000: }
        !          1001: 
        !          1002: void
        !          1003: db_show_one_act(
        !          1004:        db_expr_t       addr,
        !          1005:        boolean_t       have_addr,
        !          1006:        db_expr_t       count,
        !          1007:        char *          modif)
        !          1008: {
        !          1009:        int             flag;
        !          1010:        int             act_id;
        !          1011:        thread_act_t            thr_act;
        !          1012: 
        !          1013:        flag = OPTION_THREAD_TITLE;
        !          1014:        if (db_option(modif, 'u'))
        !          1015:            flag |= OPTION_USER;
        !          1016:        if (db_option(modif, 'l'))
        !          1017:            flag |= OPTION_LONG;
        !          1018: 
        !          1019:        if (!have_addr) {
        !          1020:            thr_act = current_act();
        !          1021:            if (thr_act == THR_ACT_NULL) {
        !          1022:                db_error("No thr_act\n");
        !          1023:                /*NOTREACHED*/
        !          1024:            }
        !          1025:        } else
        !          1026:            thr_act = (thread_act_t) addr;
        !          1027: 
        !          1028:        if ((act_id = db_lookup_act(thr_act)) < 0) {
        !          1029:            db_printf("bad thr_act address %#x\n", addr);
        !          1030:            db_error(0);
        !          1031:            /*NOTREACHED*/
        !          1032:        }
        !          1033: 
        !          1034:        if (flag & OPTION_USER) {
        !          1035:            db_printf("TASK%d(%0*X):\n",
        !          1036:                      db_lookup_task(thr_act->task),
        !          1037:                      2*sizeof(vm_offset_t), thr_act->task);
        !          1038:            db_print_act(thr_act, act_id, flag);
        !          1039:        } else {
        !          1040:            db_printf("task %d(%0*Xx): thr_act    %d",
        !          1041:                      db_lookup_task(thr_act->task),
        !          1042:                      2*sizeof(vm_offset_t), thr_act->task, act_id);
        !          1043:            db_print_act(thr_act, act_id, flag);
        !          1044:        }
        !          1045:        if (db_option(modif, 'i') &&  thr_act->thread &&
        !          1046:            (thr_act->thread->state & TH_WAIT) && 
        !          1047:            thr_act->thread->kernel_stack == 0) {
        !          1048: 
        !          1049:            db_printf("Wait State: option 0x%x\n",
        !          1050:                thr_act->thread->ith_option);
        !          1051:        }
        !          1052: }
        !          1053: 
        !          1054: void
        !          1055: db_show_one_task(
        !          1056:        db_expr_t       addr,
        !          1057:        boolean_t       have_addr,
        !          1058:        db_expr_t       count,
        !          1059:        char *          modif)
        !          1060: {
        !          1061:        int             flag;
        !          1062:        int             task_id;
        !          1063:        task_t          task;
        !          1064: 
        !          1065:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !          1066:        if (db_option(modif, 'u'))
        !          1067:            flag |= OPTION_USER;
        !          1068:        if (db_option(modif, 'l'))
        !          1069:            flag |= OPTION_LONG;
        !          1070: 
        !          1071:        if (!have_addr) {
        !          1072:            task = db_current_task();
        !          1073:            if (task == TASK_NULL) {
        !          1074:                db_error("No task\n");
        !          1075:                /*NOTREACHED*/
        !          1076:            }
        !          1077:        } else
        !          1078:            task = (task_t) addr;
        !          1079: 
        !          1080:        if ((task_id = db_lookup_task(task)) < 0) {
        !          1081:            db_printf("bad task address 0x%x\n", addr);
        !          1082:            db_error(0);
        !          1083:            /*NOTREACHED*/
        !          1084:        }
        !          1085: 
        !          1086:        db_print_task(task, task_id, flag);
        !          1087: }
        !          1088: 
        !          1089: void
        !          1090: db_show_shuttle(
        !          1091:        db_expr_t       addr,
        !          1092:        boolean_t       have_addr,
        !          1093:        db_expr_t       count,
        !          1094:        char *          modif)
        !          1095: {
        !          1096:        thread_shuttle_t        shuttle;
        !          1097:        thread_act_t            thr_act;
        !          1098: 
        !          1099:        if (have_addr)
        !          1100:            shuttle = (thread_shuttle_t) addr;
        !          1101:        else {
        !          1102:            thr_act = current_act();
        !          1103:            if (thr_act == THR_ACT_NULL) {
        !          1104:                db_error("No thr_act\n");
        !          1105:                /*NOTREACHED*/
        !          1106:            }
        !          1107:            shuttle = thr_act->thread;
        !          1108:            if (shuttle == THREAD_NULL) {
        !          1109:                db_error("No shuttle associated with current thr_act\n");
        !          1110:                /*NOTREACHED*/
        !          1111:            }
        !          1112:        }
        !          1113:        db_printf("shuttle %x:\n", shuttle);
        !          1114:        if (shuttle->top_act == THR_ACT_NULL)
        !          1115:            db_printf("  no activations\n");
        !          1116:        else {
        !          1117:            db_printf("  activations:");
        !          1118:            for (thr_act = shuttle->top_act; thr_act != THR_ACT_NULL;
        !          1119:                 thr_act = thr_act->lower) {
        !          1120:                if (thr_act != shuttle->top_act)
        !          1121:                    printf(" from");
        !          1122:                printf(" $task%d.%d(%x)", db_lookup_task(thr_act->task),
        !          1123:                       db_lookup_act(thr_act), thr_act);
        !          1124:            }
        !          1125:            db_printf("\n");
        !          1126:        }
        !          1127: }
        !          1128: 
        !          1129: #define        db_pset_kmsg_count(port) \
        !          1130:        (ipc_list_count((port)->ip_pset->ips_messages.imq_messages.ikmq_base))
        !          1131: 
        !          1132: int
        !          1133: db_port_kmsg_count(
        !          1134:        ipc_port_t      port)
        !          1135: {
        !          1136:        return (port->ip_pset ? db_pset_kmsg_count(port) : port->ip_msgcount);
        !          1137: }
        !          1138: 
        !          1139: static int db_print_ent_cnt = 0;
        !          1140: 
        !          1141: void db_reset_print_entry(
        !          1142:        void)
        !          1143: {
        !          1144:        db_print_ent_cnt = 0;
        !          1145: }
        !          1146: 
        !          1147: void
        !          1148: db_print_one_entry(
        !          1149:        ipc_entry_t     entry,
        !          1150:        int             index,
        !          1151:        mach_port_t     name,
        !          1152:        boolean_t       is_pset)
        !          1153: {
        !          1154:        ipc_port_t aport = (ipc_port_t)entry->ie_object;
        !          1155:        unsigned bits = entry->ie_bits;
        !          1156: 
        !          1157:        if (is_pset && !aport->ip_pset)
        !          1158:                return;
        !          1159:        if (db_print_ent_cnt && db_print_ent_cnt % 2 == 0)
        !          1160:                db_printf("\n");
        !          1161:        if (!name)
        !          1162:                db_printf("\t%s%d[%x]",
        !          1163:                        !is_pset && aport->ip_pset ? "pset" : "port",
        !          1164:                        index,
        !          1165:                        MACH_PORT_MAKE(index, IE_BITS_GEN(bits)));
        !          1166:        else
        !          1167:                db_printf("\t%s[%x]",
        !          1168:                        !is_pset && aport->ip_pset ? "pset" : "port",
        !          1169:                        name);
        !          1170:        if (!is_pset) {
        !          1171:                db_printf("(%s,%x,%d)",
        !          1172:                    (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1173:                        (bits & MACH_PORT_TYPE_SEND)? "s": "S",
        !          1174:                        aport,
        !          1175:                    db_port_kmsg_count(aport));
        !          1176:                db_print_ent_cnt++;
        !          1177:        }
        !          1178:        else {
        !          1179:                db_printf("(%s,%x,set=%x,%d)",
        !          1180:                        (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1181:                                (bits & MACH_PORT_TYPE_SEND)? "s": "S",
        !          1182:                        aport,
        !          1183:                        aport->ip_pset,
        !          1184:                        db_pset_kmsg_count(aport));
        !          1185:                db_print_ent_cnt++;
        !          1186:        }
        !          1187: }
        !          1188: 
        !          1189: int
        !          1190: db_port_iterate(
        !          1191:        thread_act_t    thr_act,
        !          1192:        boolean_t       is_pset,
        !          1193:        boolean_t       do_output)
        !          1194: {
        !          1195:        ipc_entry_t entry;
        !          1196:        ipc_tree_entry_t tentry;
        !          1197:        int index;
        !          1198:        int size;
        !          1199:        int count;
        !          1200:        ipc_space_t space;
        !          1201: 
        !          1202:        count = 0;
        !          1203:        space = thr_act->task->itk_space;
        !          1204:        entry = space->is_table;
        !          1205:        size = space->is_table_size;
        !          1206:        db_reset_print_entry();
        !          1207:        for (index = 0; index < size; ++index, ++entry) {
        !          1208:                if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) {
        !          1209:                        if (do_output)
        !          1210:                                db_print_one_entry(entry,
        !          1211:                                        index, (mach_port_t)0, is_pset);
        !          1212:                        ++count;
        !          1213:                }
        !          1214:        }
        !          1215:        for (tentry = ipc_splay_traverse_start(&space->is_tree);
        !          1216:                tentry != ITE_NULL;
        !          1217:                tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
        !          1218:                entry = &tentry->ite_entry;
        !          1219:                if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) {
        !          1220:                        if (do_output)
        !          1221:                                db_print_one_entry(entry,
        !          1222:                                        0, tentry->ite_name, is_pset);
        !          1223:                        ++count;
        !          1224:                }
        !          1225:        }
        !          1226:        return (count);
        !          1227: }
        !          1228: 
        !          1229: ipc_port_t
        !          1230: db_lookup_port(
        !          1231:        thread_act_t    thr_act,
        !          1232:        int             id)
        !          1233: {
        !          1234:        register ipc_space_t space;
        !          1235:        register ipc_entry_t entry;
        !          1236: 
        !          1237:        if (thr_act == THR_ACT_NULL)
        !          1238:            return(0);
        !          1239:        space = thr_act->task->itk_space;
        !          1240:        if (id < 0 || id >= space->is_table_size)
        !          1241:            return(0);
        !          1242:        entry = &space->is_table[id];
        !          1243:        if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
        !          1244:            return((ipc_port_t)entry->ie_object);
        !          1245:        return(0);
        !          1246: }
        !          1247: 
        !          1248: static void
        !          1249: db_print_port_id(
        !          1250:        int             id,
        !          1251:        ipc_port_t      port,
        !          1252:        unsigned        bits,
        !          1253:        int             n)
        !          1254: {
        !          1255:        if (n != 0 && n % 3 == 0)
        !          1256:            db_printf("\n");
        !          1257:        db_printf("\tport%d(%s,%x)", id,
        !          1258:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1259:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
        !          1260: }
        !          1261: 
        !          1262: void
        !          1263: db_show_port_id(
        !          1264:        db_expr_t       addr,
        !          1265:        boolean_t       have_addr,
        !          1266:        db_expr_t       count,
        !          1267:        char *          modif)
        !          1268: {
        !          1269:        thread_act_t thr_act;
        !          1270: 
        !          1271:        if (!have_addr) {
        !          1272:            thr_act = current_act();
        !          1273:            if (thr_act == THR_ACT_NULL) {
        !          1274:                db_error("No thr_act\n");
        !          1275:                /*NOTREACHED*/
        !          1276:            }
        !          1277:        } else
        !          1278:            thr_act = (thread_act_t) addr;
        !          1279:        if (db_lookup_act(thr_act) < 0) {
        !          1280:            db_printf("Bad thr_act address 0x%x\n", addr);
        !          1281:            db_error(0);
        !          1282:            /*NOTREACHED*/
        !          1283:        }
        !          1284:        if (db_port_iterate(thr_act, db_option(modif,'s'), TRUE))
        !          1285:            db_printf("\n");
        !          1286: }
        !          1287: 
        !          1288: /*
        !          1289:  *     Useful system state when the world has hung.
        !          1290:  */
        !          1291: void
        !          1292: db_system_stats()
        !          1293: {
        !          1294:        extern void     db_device(void);
        !          1295:        extern void     db_sched(void);
        !          1296: #if    DIPC
        !          1297:        extern void     db_dipc_stats(void);
        !          1298:        extern void     db_show_kkt(void);
        !          1299: #endif /* DIPC */
        !          1300: 
        !          1301:        db_sched();
        !          1302:        iprintf("\n");
        !          1303:        db_vm();
        !          1304:        iprintf("\n");
        !          1305:        db_device();
        !          1306: #if    DIPC
        !          1307:        iprintf("\n");
        !          1308:        db_dipc_stats();
        !          1309:        iprintf("\n");
        !          1310:        db_show_kkt();
        !          1311: #endif /* DIPC */
        !          1312:        iprintf("\n");
        !          1313:        db_printf("current_{thread/task} 0x%x 0x%x\n",
        !          1314:                        current_thread(),current_task());
        !          1315: }
        !          1316: 
        !          1317: void db_show_one_runq(run_queue_t runq);
        !          1318: 
        !          1319: void
        !          1320: db_show_runq(
        !          1321:        db_expr_t       addr,
        !          1322:        boolean_t       have_addr,
        !          1323:        db_expr_t       count,
        !          1324:        char *          modif)
        !          1325: {
        !          1326:        processor_set_t pset;
        !          1327:        processor_t proc;
        !          1328:        run_queue_t runq;
        !          1329:        boolean_t showedany = FALSE;
        !          1330: 
        !          1331:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !          1332: #if NCPUS > 1  /* This code has not been tested. */
        !          1333:            queue_iterate(&pset->processors, proc, processor_t, processors) {
        !          1334:                runq = &proc->runq;
        !          1335:                if (runq->count > 0) {
        !          1336:                    db_printf("PROCESSOR %x IN SET %x\n", proc, pset);
        !          1337:                    db_show_one_runq(runq);
        !          1338:                    showedany = TRUE;
        !          1339:                }
        !          1340:            }
        !          1341: #endif /* NCPUS > 1 */
        !          1342: #ifndef NCPUS
        !          1343: #error NCPUS undefined
        !          1344: #endif
        !          1345:            runq = &pset->runq;
        !          1346:            if (runq->count > 0) {
        !          1347:                db_printf("PROCESSOR SET %x\n", pset);
        !          1348:                db_show_one_runq(runq);
        !          1349:                showedany = TRUE;
        !          1350:            }
        !          1351:        }
        !          1352:        if (!showedany)
        !          1353:            db_printf("No runnable threads\n");
        !          1354: }
        !          1355: 
        !          1356: void
        !          1357: db_show_one_runq(
        !          1358:        run_queue_t     runq)
        !          1359: {
        !          1360:        int i, task_id, thr_act_id;
        !          1361:        queue_t q;
        !          1362:        thread_act_t thr_act;
        !          1363:        thread_t thread;
        !          1364:        task_t task;
        !          1365: 
        !          1366:        printf("PRI  TASK.ACTIVATION\n");
        !          1367:        for (i = runq->low, q = runq->runq + i; i < NRQS; i++, q++) {
        !          1368:            if (!queue_empty(q)) {
        !          1369:                db_printf("%3d:", i);
        !          1370:                queue_iterate(q, thread, thread_t, links) {
        !          1371:                    thr_act = thread->top_act;
        !          1372:                    task = thr_act->task;
        !          1373:                    task_id = db_lookup_task(task);
        !          1374:                    thr_act_id = db_lookup_task_act(task, thr_act);
        !          1375:                    db_printf(" %d.%d", task_id, thr_act_id);
        !          1376:                }
        !          1377:                db_printf("\n");
        !          1378:            }
        !          1379:        }
        !          1380: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.