Annotation of XNU/osfmk/ddb/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.3  1998/05/29 23:55:12  youngwor
        !            32:  * Added infrastructure for shared port space support
        !            33:  *
        !            34:  * Revision 1.2  1998/04/29 17:35:25  mburg
        !            35:  * MK7.3 merger
        !            36:  *
        !            37:  * Revision 1.2.85.1  1998/02/03  09:24:09  gdt
        !            38:  *     Merge up to MK7.3
        !            39:  *     [1998/02/03  09:10:24  gdt]
        !            40:  *
        !            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]
        !            48:  *     [97/02/25            barbou]
        !            49:  * 
        !            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]
        !            59:  * 
        !            60:  *     Merged '64-bit safe' changes from DEC alpha port.
        !            61:  *     [1995/11/21  18:03:24  jfraser]
        !            62:  * 
        !            63:  * Revision 1.2.31.12  1995/10/09  17:03:30  devrcs
        !            64:  *     Merge forward.
        !            65:  *     [1995/08/24  20:56:42  watkins]
        !            66:  * 
        !            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]
        !            70:  * 
        !            71:  * Revision 1.2.31.11  1995/09/18  19:08:49  devrcs
        !            72:  *     Merge forward.
        !            73:  *     [1995/08/24  20:56:42  watkins]
        !            74:  * 
        !            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]
        !            78:  * 
        !            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.
        !            82:  *     [95/05/19            bernadat]
        !            83:  * 
        !            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]
        !            89:  * 
        !            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]
        !            97:  *     [94/07/27            barbou]
        !            98:  *     [95/03/08            barbou]
        !            99:  * 
        !           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]
        !           107:  * 
        !           108:  * Revision 1.2.31.6  1995/02/23  21:43:34  alanl
        !           109:  *     Fix db_show_one_task_vm for thread_act_ts.
        !           110:  *     [95/01/09            rwd]
        !           111:  * 
        !           112:  *     Merged with DIPC2_SHARED.
        !           113:  *     [95/01/04            alanl]
        !           114:  * 
        !           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]
        !           121:  * 
        !           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.
        !           126:  *     64bit cleanup.
        !           127:  *     * End1.3merge
        !           128:  *     [1994/11/04  08:49:52  dwm]
        !           129:  * 
        !           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]
        !           133:  * 
        !           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]
        !           137:  * 
        !           138:  * Revision 1.2.23.4  1994/04/15  18:41:31  paire
        !           139:  *     Changed interface of db_task_from_space routine.
        !           140:  *     [94/03/31            paire]
        !           141:  * 
        !           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]
        !           145:  * 
        !           146:  *     Enhanced pretty print routine and added db_task_from_space.
        !           147:  *     Change from NMK14.10 [93/09/24            sjs]
        !           148:  *     [94/02/21            paire]
        !           149:  * 
        !           150:  *     Exported ANSI prototype of db_port_kmsg_count routine.
        !           151:  *     Added header file include for the declaration of db_norma_ipc routine.
        !           152:  *     [94/02/15            paire]
        !           153:  * 
        !           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.
        !           156:  *     [94/02/09            paire]
        !           157:  * 
        !           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]
        !           161:  * 
        !           162:  *     Removed defintion of db_maxoff (got from <ddb/db_sym.h>).
        !           163:  *     [93/08/12            paire]
        !           164:  * 
        !           165:  *     Show ipc_space_remote msg counts only if NORMA_IPC is on
        !           166:  *     [93/07/21            bernadat]
        !           167:  * 
        !           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]
        !           172:  * 
        !           173:  * Revision 1.2.20.8  1994/06/08  19:11:15  dswartz
        !           174:  *     Preemption merge.
        !           175:  *     [1994/06/08  19:10:18  dswartz]
        !           176:  * 
        !           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]
        !           181:  * 
        !           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]
        !           185:  * 
        !           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]
        !           189:  * 
        !           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]
        !           193:  * 
        !           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]
        !           198:  * 
        !           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]
        !           202:  * 
        !           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]
        !           206:  * 
        !           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]
        !           210:  * 
        !           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]
        !           215:  * 
        !           216:  *     Removed a '#if MACH_FIXPRI' which somehow survived the purge.  CR #9131.
        !           217:  *     [1993/05/11  20:56:00  dswartz]
        !           218:  * 
        !           219:  * Revision 1.2  1993/04/19  16:02:50  devrcs
        !           220:  *     Added printout of thread scheduling policy to long form
        !           221:  *     of thread display.
        !           222:  *     [93/01/28            jat]
        !           223:  * 
        !           224:  *     Changes from mk78:
        !           225:  *     Removed unused variable from db_show_regs().
        !           226:  *     [92/05/16            jfriedl]
        !           227:  *     Converted some db_printsyms to db_task_printsyms.
        !           228:  *     [92/04/10            danner]
        !           229:  *     Changed db_print_thread so that both display formats
        !           230:  *     show the floating-point-used status of the thread.
        !           231:  *     [92/03/16            rpd]
        !           232:  *     [93/02/02            bruel]
        !           233:  * 
        !           234:  * Revision 1.1  1992/09/30  02:01:18  robert
        !           235:  *     Initial revision
        !           236:  * 
        !           237:  * $EndLog$
        !           238:  */
        !           239: /* CMU_HIST */
        !           240: /*
        !           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.
        !           243:  *     [92/04/08            sjs]
        !           244:  * 
        !           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]
        !           248:  * 
        !           249:  * Revision 2.13  92/02/20  18:34:28  elf
        !           250:  *     Fixed typo.
        !           251:  *     [92/02/20            elf]
        !           252:  * 
        !           253:  * Revision 2.12  92/02/19  15:07:47  elf
        !           254:  *     Added db_thread_fp_used, to avoid machine-dependent conditionals.
        !           255:  *     [92/02/19            rpd]
        !           256:  * 
        !           257:  *     Added 'F' flag to db_thread_stat showing if the thread has a valid
        !           258:  *     FPU context. Tested on i386 and pmax.
        !           259:  *     [92/02/17            kivinen]
        !           260:  * 
        !           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.
        !           264:  *     [91/10/31            rpd]
        !           265:  * 
        !           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.
        !           273:  *     [91/08/29            tak]
        !           274:  * 
        !           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]
        !           280:  * 
        !           281:  * Revision 2.8  91/07/31  17:30:43  dbg
        !           282:  *     Revise scheduling state machine.
        !           283:  *     [91/07/30  16:43:42  dbg]
        !           284:  * 
        !           285:  * Revision 2.7  91/07/09  23:15:57  danner
        !           286:  *     Fixed a few printf that should be db_printfs. 
        !           287:  *     [91/07/08            danner]
        !           288:  * 
        !           289:  * Revision 2.6  91/05/14  15:35:25  mrt
        !           290:  *     Correcting copyright
        !           291:  * 
        !           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]
        !           295:  * 
        !           296:  * Revision 2.4  90/10/25  14:43:54  rwd
        !           297:  *     Changed db_show_regs to print unsigned.
        !           298:  *     [90/10/19            rpd]
        !           299:  *     Generalized the watchpoint support.
        !           300:  *     [90/10/16            rwd]
        !           301:  * 
        !           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]
        !           305:  * 
        !           306:  * Revision 2.2  90/08/27  21:51:49  dbg
        !           307:  *     Insist that 'show thread' be called with an explicit address.
        !           308:  *     [90/08/22            dbg]
        !           309:  * 
        !           310:  *     Fix type for db_maxoff.
        !           311:  *     [90/08/20            dbg]
        !           312:  * 
        !           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.
        !           316:  *     [90/08/20            af]
        !           317:  *     Reduce lint.
        !           318:  *     [90/08/10  14:33:44  dbg]
        !           319:  * 
        !           320:  *     Created.
        !           321:  *     [90/07/25            dbg]
        !           322:  * 
        !           323:  */
        !           324: /* CMU_ENDHIST */
        !           325: /*
        !           326:  * Mach Operating System
        !           327:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !           328:  * All Rights Reserved.
        !           329:  * 
        !           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.
        !           335:  * 
        !           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.
        !           339:  * 
        !           340:  * Carnegie Mellon requests users of this software to return to
        !           341:  * 
        !           342:  *  Software Distribution Coordinator  or  [email protected]
        !           343:  *  School of Computer Science
        !           344:  *  Carnegie Mellon University
        !           345:  *  Pittsburgh PA 15213-3890
        !           346:  * 
        !           347:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           348:  * the rights to redistribute these changes.
        !           349:  */
        !           350: /*
        !           351:  */
        !           352: /*
        !           353:  *     Author: David B. Golub, Carnegie Mellon University
        !           354:  *     Date:   7/90
        !           355:  */
        !           356: 
        !           357: /*
        !           358:  * Miscellaneous printing.
        !           359:  */
        !           360: #include <dipc.h>
        !           361: #include <task_swapper.h>
        !           362: 
        !           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 <kern/processor.h>
        !           370: #include <ipc/ipc_port.h>
        !           371: #include <ipc/ipc_space.h>
        !           372: #include <ipc/ipc_pset.h>
        !           373: #include <vm/vm_print.h>               /* for db_vm() */
        !           374: 
        !           375: #include <machine/db_machdep.h>
        !           376: #include <machine/thread.h>
        !           377: 
        !           378: #include <ddb/db_lex.h>
        !           379: #include <ddb/db_variables.h>
        !           380: #include <ddb/db_sym.h>
        !           381: #include <ddb/db_task_thread.h>
        !           382: #include <ddb/db_command.h>
        !           383: #include <ddb/db_output.h>             /* For db_printf() */
        !           384: #include <ddb/db_print.h>
        !           385: 
        !           386: #include <kern/sf.h>
        !           387: #include <kern/mk_sp.h>        /*** ??? fix so this can be removed ***/
        !           388: 
        !           389: #if    TASK_SWAPPER
        !           390: #include <kern/task_swap.h>
        !           391: #endif /* TASK_SWAPPER */
        !           392: 
        !           393: /* Prototypes for functions local to this file.  XXX -- should be static!
        !           394:  */
        !           395: 
        !           396: char *db_act_stat(
        !           397:        register thread_act_t   thr_act,
        !           398:        char                    *status);
        !           399: 
        !           400: char *db_act_swap_stat(
        !           401:        register thread_act_t   thr_act,
        !           402:        char                    *status);
        !           403: 
        !           404: void db_print_task(
        !           405:        task_t  task,
        !           406:        int     task_id,
        !           407:        int     flag);
        !           408: 
        !           409: void db_reset_print_entry(
        !           410:        void);
        !           411: 
        !           412: void db_print_one_entry(
        !           413:        ipc_entry_t     entry,
        !           414:        int             index,
        !           415:        mach_port_name_t        name,
        !           416:        boolean_t       is_pset,
        !           417:        ipc_space_t     space);
        !           418: 
        !           419: int db_port_iterate(
        !           420:        thread_act_t    thr_act,
        !           421:        boolean_t       is_pset,
        !           422:        boolean_t       do_output);
        !           423: 
        !           424: ipc_port_t db_lookup_port(
        !           425:        thread_act_t    thr_act,
        !           426:        int             id);
        !           427: 
        !           428: static void db_print_port_id(
        !           429:        int             id,
        !           430:        ipc_port_t      port,
        !           431:        unsigned        bits,
        !           432:        int             n);
        !           433: 
        !           434: void db_print_act(
        !           435:        thread_act_t    thr_act,
        !           436:        int             act_id,
        !           437:        int             flag);
        !           438: 
        !           439: void db_print_space(
        !           440:        task_t  task,
        !           441:        int     task_id,
        !           442:        int     flag);
        !           443: 
        !           444: void db_print_task_vm(
        !           445:        task_t          task,
        !           446:        int             task_id,
        !           447:        boolean_t       title,
        !           448:        char            *modif);
        !           449: 
        !           450: void db_system_stats(void);
        !           451: 
        !           452: 
        !           453: void
        !           454: db_show_regs(
        !           455:        db_expr_t       addr,
        !           456:        boolean_t       have_addr,
        !           457:        db_expr_t       count,
        !           458:        char            *modif)
        !           459: {
        !           460:        register struct db_variable *regp;
        !           461:        db_expr_t       value;
        !           462:        db_addr_t       offset;
        !           463:        char *          name;
        !           464:        register int    i; 
        !           465:        struct db_var_aux_param aux_param;
        !           466:        task_t          task = TASK_NULL;
        !           467: 
        !           468:        aux_param.modif = modif;
        !           469:        aux_param.thr_act = THR_ACT_NULL;
        !           470:        if (db_option(modif, 't')) {
        !           471:            if (have_addr) {
        !           472:                if (!db_check_act_address_valid((thread_act_t)addr))
        !           473:                    return;
        !           474:                aux_param.thr_act = (thread_act_t)addr;
        !           475:            } else
        !           476:                aux_param.thr_act = db_default_act;
        !           477:            if (aux_param.thr_act != THR_ACT_NULL)
        !           478:                task = aux_param.thr_act->task;
        !           479:        }
        !           480:        for (regp = db_regs; regp < db_eregs; regp++) {
        !           481:            if (regp->max_level > 1) {
        !           482:                db_printf("bad multi-suffixed register %s\n", regp->name);
        !           483:                continue;
        !           484:            }
        !           485:            aux_param.level = regp->max_level;
        !           486:            for (i = regp->low; i <= regp->high; i++) {
        !           487:                aux_param.suffix[0] = i;
        !           488:                db_read_write_variable(regp, &value, DB_VAR_GET, &aux_param);
        !           489:                if (regp->max_level > 0)
        !           490:                    db_printf("%s%d%*s", regp->name, i, 
        !           491:                                12-strlen(regp->name)-((i<10)?1:2), "");
        !           492:                else
        !           493:                    db_printf("%-12s", regp->name);
        !           494:                db_printf("%#*N", 2+2*sizeof(vm_offset_t), value);
        !           495:                db_find_xtrn_task_sym_and_offset((db_addr_t)value, &name, 
        !           496:                                                        &offset, task);
        !           497:                if (name != 0 && offset <= db_maxoff && offset != value) {
        !           498:                    db_printf("\t%s", name);
        !           499:                    if (offset != 0)
        !           500:                        db_printf("+%#r", offset);
        !           501:                }
        !           502:                db_printf("\n");
        !           503:            }
        !           504:        }
        !           505: }
        !           506: 
        !           507: #define OPTION_LONG            0x001           /* long print option */
        !           508: #define OPTION_USER            0x002           /* print ps-like stuff */
        !           509: #define OPTION_INDENT          0x100           /* print with indent */
        !           510: #define OPTION_THREAD_TITLE    0x200           /* print thread title */
        !           511: #define OPTION_TASK_TITLE      0x400           /* print thread title */
        !           512: 
        !           513: #ifndef        DB_TASK_NAME
        !           514: #define DB_TASK_NAME(task)                     /* no task name */
        !           515: #define DB_TASK_NAME_TITLE     ""              /* no task name */
        !           516: #endif /* DB_TASK_NAME */
        !           517: 
        !           518: #ifndef        db_act_fp_used
        !           519: #define db_act_fp_used(thr_act)        FALSE
        !           520: #endif
        !           521: 
        !           522: char *
        !           523: db_act_stat(
        !           524:        register thread_act_t   thr_act,
        !           525:        char                    *status)
        !           526: {
        !           527:        register char *p = status;
        !           528:        
        !           529:        if (!thr_act->active) {
        !           530:                *p++ = 'D',
        !           531:                *p++ = 'y',
        !           532:                *p++ = 'i',
        !           533:                *p++ = 'n',
        !           534:                *p++ = 'g';
        !           535:                *p++ = ' ';
        !           536:        } else if (!thr_act->thread) {
        !           537:                *p++ = 'E',
        !           538:                *p++ = 'm',
        !           539:                *p++ = 'p',
        !           540:                *p++ = 't',
        !           541:                *p++ = 'y';
        !           542:                *p++ = ' ';
        !           543:        } else {
        !           544:                thread_t athread = thr_act->thread;
        !           545: 
        !           546:                *p++ = (athread->state & TH_RUN)  ? 'R' : '.';
        !           547:                *p++ = (athread->state & TH_WAIT) ? 'W' : '.';
        !           548:                *p++ = (athread->state & TH_SUSP) ? 'S' : '.';
        !           549:                *p++ = (athread->state & TH_SWAPPED_OUT) ? 'O' : '.';
        !           550:                *p++ = (athread->state & TH_UNINT) ? 'N' : '.';
        !           551:                /* show if the FPU has been used */
        !           552:                *p++ = db_act_fp_used(thr_act) ? 'F' : '.';
        !           553:        }
        !           554:        *p++ = 0;
        !           555:        return(status);
        !           556: }
        !           557: 
        !           558: char *
        !           559: db_act_swap_stat(
        !           560:        register thread_act_t   thr_act,
        !           561:        char                    *status)
        !           562: {
        !           563:        register char *p = status;
        !           564: 
        !           565: #if    THREAD_SWAPPER
        !           566:        switch (thr_act->swap_state & TH_SW_STATE) {
        !           567:            case TH_SW_UNSWAPPABLE:
        !           568:                *p++ = 'U';
        !           569:                break;
        !           570:            case TH_SW_IN:
        !           571:                *p++ = 'I';
        !           572:                break;
        !           573:            case TH_SW_GOING_OUT:
        !           574:                *p++ = 'G';
        !           575:                break;
        !           576:            case TH_SW_WANT_IN:
        !           577:                *p++ = 'W';
        !           578:                break;
        !           579:            case TH_SW_OUT:
        !           580:                *p++ = 'O';
        !           581:                break;
        !           582:            case TH_SW_COMING_IN:
        !           583:                *p++ = 'C';
        !           584:                break;
        !           585:            default:
        !           586:                *p++ = '?';
        !           587:                break;
        !           588:        }
        !           589:        *p++ = (thr_act->swap_state & TH_SW_TASK_SWAPPING) ? 'T' : '.';
        !           590: #endif /* THREAD_SWAPPER */
        !           591:        *p++ = 0;
        !           592: 
        !           593:        return status;
        !           594: }
        !           595: 
        !           596: char   *policy_list[] = { "TS", "RR", "??", "FF",
        !           597:                           "??", "??", "??", "BE"};
        !           598: 
        !           599: void
        !           600: db_print_act(
        !           601:        thread_act_t    thr_act,
        !           602:        int             act_id,
        !           603:        int             flag)
        !           604: {
        !           605:        thread_t athread;
        !           606:        char status[8];
        !           607:        char swap_status[3];
        !           608:        char *indent = "";
        !           609:        int      policy;
        !           610: 
        !           611:        if (!thr_act) {
        !           612:            db_printf("db_print_act(NULL)!\n");
        !           613:            return;
        !           614:        }
        !           615: 
        !           616:        athread = thr_act->thread;
        !           617:        if (flag & OPTION_USER) {
        !           618: 
        !           619:            if (flag & OPTION_LONG) {
        !           620:                if (flag & OPTION_INDENT)
        !           621:                    indent = "    ";
        !           622:                if (flag & OPTION_THREAD_TITLE) {
        !           623:                    db_printf("%s ID:   ACT     STAT  SW STACK    SHUTTLE", indent);
        !           624:                    db_printf("  SUS  PRI  WAIT_FUNC\n");
        !           625:                }
        !           626:                policy = (athread ? athread->policy : 2);
        !           627:                db_printf("%s%3d%c %0*X %s %s %0*X %0*X %3d %3d/%s ",
        !           628:                    indent, act_id,
        !           629:                    (thr_act == current_act())? '#': ':',
        !           630:                    2*sizeof(vm_offset_t), thr_act,
        !           631:                    db_act_stat(thr_act, status),
        !           632:                    db_act_swap_stat(thr_act, swap_status),
        !           633:                    2*sizeof(vm_offset_t), (athread ?athread->kernel_stack:0),
        !           634:                    2*sizeof(vm_offset_t), athread,
        !           635:                    thr_act->suspend_count,
        !           636:                    (athread ? athread->sched_pri : 999), /* XXX */
        !           637:                    policy_list[policy-1]);
        !           638:                if (athread) {
        !           639:                    /* no longer TH_SWAP, no continuation to print */
        !           640:                    if (athread->state & TH_WAIT)
        !           641:                        db_task_printsym((db_addr_t)athread->wait_event,
        !           642:                                                DB_STGY_ANY, kernel_task);
        !           643:                }
        !           644:                db_printf("\n");
        !           645:            } else {
        !           646:                if (act_id % 3 == 0) {
        !           647:                    if (flag & OPTION_INDENT)
        !           648:                        db_printf("\n    ");
        !           649:                } else
        !           650:                    db_printf(" ");
        !           651:                db_printf("%3d%c(%0*X,%s)", act_id, 
        !           652:                    (thr_act == current_act())? '#': ':',
        !           653:                    2*sizeof(vm_offset_t), thr_act,
        !           654:                    db_act_stat(thr_act, status));
        !           655:            }
        !           656:        } else {
        !           657:            if (flag & OPTION_INDENT)
        !           658:                db_printf("            %3d (%0*X) ", act_id,
        !           659:                          2*sizeof(vm_offset_t), thr_act);
        !           660:            else
        !           661:                db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thr_act);
        !           662:            if (athread) {
        !           663:                db_printf("%c%c%c%c%c",
        !           664:                        (athread->state & TH_RUN)  ? 'R' : ' ',
        !           665:                        (athread->state & TH_WAIT) ? 'W' : ' ',
        !           666:                        (athread->state & TH_SUSP) ? 'S' : ' ',
        !           667:                        (athread->state & TH_UNINT)? 'N' : ' ',
        !           668:                        db_act_fp_used(thr_act) ? 'F' : ' ');
        !           669:                /* Obsolete TH_STACK_HANDOFF code, left for now; might enhance
        !           670:                 * to print out safe_points instead */
        !           671:                if (athread->state & TH_STACK_HANDOFF) {
        !           672:                    if (athread->continuation) {
        !           673:                        db_printf("(");
        !           674:                        db_task_printsym((db_addr_t)athread->continuation,
        !           675:                                                DB_STGY_ANY, kernel_task);
        !           676:                        db_printf(")");
        !           677:                    } else {
        !           678:                        db_printf("(handoff)");
        !           679:                    }
        !           680:                }
        !           681:                if (athread->state & TH_WAIT) {
        !           682:                    db_printf(" ");
        !           683:                    db_task_printsym((db_addr_t)athread->wait_event,
        !           684:                                                DB_STGY_ANY, kernel_task);
        !           685:                }
        !           686:            } else
        !           687:                db_printf("Empty");
        !           688:            db_printf("\n");
        !           689:        }
        !           690: }
        !           691: 
        !           692: void
        !           693: db_print_task(
        !           694:        task_t  task,
        !           695:        int     task_id,
        !           696:        int     flag)
        !           697: {
        !           698:        thread_act_t thr_act;
        !           699:        int act_id;
        !           700:        char sstate;
        !           701: 
        !           702:        if (flag & OPTION_USER) {
        !           703:            if (flag & OPTION_TASK_TITLE) {
        !           704:                db_printf(" ID: TASK     MAP      THD RES SUS PR SW %s", 
        !           705:                          DB_TASK_NAME_TITLE);
        !           706:                if ((flag & OPTION_LONG) == 0)
        !           707:                    db_printf("  ACTS");
        !           708:                db_printf("\n");
        !           709:            }
        !           710: #if    TASK_SWAPPER
        !           711:            switch ((int) task->swap_state) {
        !           712:                case TASK_SW_IN:
        !           713:                    sstate = 'I';
        !           714:                    break;
        !           715:                case TASK_SW_OUT:
        !           716:                    sstate = 'O';
        !           717:                    break;
        !           718:                case TASK_SW_GOING_OUT:
        !           719:                    sstate = 'G';
        !           720:                    break;
        !           721:                case TASK_SW_COMING_IN:
        !           722:                    sstate = 'C';
        !           723:                    break;
        !           724:                case TASK_SW_UNSWAPPABLE:
        !           725:                    sstate = 'U';
        !           726:                    break;
        !           727:                default:
        !           728:                    sstate = '?';
        !           729:                    break;
        !           730:            }
        !           731: #else  /* TASK_SWAPPER */
        !           732:            sstate = 'I';
        !           733: #endif /* TASK_SWAPPER */
        !           734:            /*** ??? fix me ***/
        !           735:            db_printf("%3d: %0*X %0*X %3d %3d %3d %2d %c  ",
        !           736:                            task_id, 2*sizeof(vm_offset_t), task,
        !           737:                            2*sizeof(vm_offset_t), task->map,
        !           738:                            task->thr_act_count, task->res_act_count,
        !           739:                            task->suspend_count,
        !           740:                            ((mk_sp_attributes_t)(task->sp_attributes))->priority,
        !           741:                            sstate);
        !           742:            DB_TASK_NAME(task);
        !           743:            if (flag & OPTION_LONG) {
        !           744:                if (flag & OPTION_TASK_TITLE)
        !           745:                    flag |= OPTION_THREAD_TITLE;
        !           746:                db_printf("\n");
        !           747:            } else if (task->thr_act_count <= 1)
        !           748:                flag &= ~OPTION_INDENT;
        !           749:            act_id = 0;
        !           750:            queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) {
        !           751:                db_print_act(thr_act, act_id, flag);
        !           752:                flag &= ~OPTION_THREAD_TITLE;
        !           753:                act_id++;
        !           754:            }
        !           755:            if ((flag & OPTION_LONG) == 0)
        !           756:                db_printf("\n");
        !           757:        } else {
        !           758:            if (flag & OPTION_LONG) {
        !           759:                if (flag & OPTION_TASK_TITLE) {
        !           760:                    db_printf("    TASK        ACT\n");
        !           761:                    if (task->thr_act_count > 1)
        !           762:                        flag |= OPTION_THREAD_TITLE;
        !           763:                }
        !           764:            }
        !           765:            db_printf("%3d (%0*X): ", task_id, 2*sizeof(vm_offset_t), task);
        !           766:            if (task->thr_act_count == 0) {
        !           767:                db_printf("no threads\n");
        !           768:            } else {
        !           769:                if (task->thr_act_count > 1) {
        !           770:                    db_printf("%d threads: \n", task->thr_act_count);
        !           771:                    flag |= OPTION_INDENT;
        !           772:                } else
        !           773:                    flag &= ~OPTION_INDENT;
        !           774:                act_id = 0;
        !           775:                queue_iterate(&task->thr_acts, thr_act,
        !           776:                              thread_act_t, thr_acts) {
        !           777:                    db_print_act(thr_act, act_id++, flag);
        !           778:                    flag &= ~OPTION_THREAD_TITLE;
        !           779:                }
        !           780:            }
        !           781:        }
        !           782: }
        !           783: 
        !           784: void
        !           785: db_print_space(
        !           786:        task_t  task,
        !           787:        int     task_id,
        !           788:        int     flag)
        !           789: {
        !           790:        ipc_space_t space;
        !           791:        thread_act_t act = (thread_act_t)queue_first(&task->thr_acts);
        !           792:        int count;
        !           793: 
        !           794:        count = 0;
        !           795:        space = task->itk_space;
        !           796:        if (act)
        !           797:                count = db_port_iterate(act, FALSE, FALSE);
        !           798:        db_printf("%3d: %08x %08x %08x %sactive   %d\n",
        !           799:                  task_id, task, space, task->map,
        !           800:                  space->is_active? "":"!", count);
        !           801: }
        !           802: 
        !           803: void
        !           804: db_print_task_vm(
        !           805:        task_t          task,
        !           806:        int             task_id,
        !           807:        boolean_t       title,
        !           808:        char            *modif)
        !           809: {
        !           810:        vm_map_t        map;
        !           811:        pmap_t          pmap;
        !           812:        vm_size_t       size;
        !           813:        long            resident;
        !           814:        long            wired;
        !           815: 
        !           816:        if (title) {
        !           817:                db_printf("id     task      map     pmap  virtual  rss pg rss mem  wir pg wir mem\n");
        !           818:        }
        !           819: 
        !           820:        map = task->map;
        !           821:        pmap = vm_map_pmap(map);
        !           822: 
        !           823:        size = db_vm_map_total_size(map);
        !           824:        resident = pmap->stats.resident_count;
        !           825:        wired = pmap->stats.wired_count;
        !           826: 
        !           827:        db_printf("%2d %08x %08x %08x %7dK  %6d %6dK  %6d %6dK\n",
        !           828:                task_id,
        !           829:                task,
        !           830:                map,
        !           831:                pmap,
        !           832:                size / 1024,
        !           833:                resident, (resident * PAGE_SIZE) / 1024,
        !           834:                wired, (wired * PAGE_SIZE) / 1024);
        !           835: }
        !           836: 
        !           837: 
        !           838: void
        !           839: db_show_one_task_vm(
        !           840:        db_expr_t       addr,
        !           841:        boolean_t       have_addr,
        !           842:        db_expr_t       count,
        !           843:        char            *modif)
        !           844: {
        !           845:        thread_act_t    thread;
        !           846:        task_t          task;
        !           847:        int             task_id;
        !           848: 
        !           849:        if (have_addr == FALSE) {
        !           850:                if ((thread = db_default_act) == THR_ACT_NULL) {
        !           851:                        if ((thread = current_act()) == THR_ACT_NULL) {
        !           852:                                db_printf("no thread.\n");
        !           853:                                return;
        !           854:                        }
        !           855:                }
        !           856:                task = thread->task;
        !           857:        } else {
        !           858:                task = (task_t) addr;
        !           859:        }
        !           860: 
        !           861:        task_id = db_lookup_task(task);
        !           862:        if (task_id < 0) {
        !           863:                db_printf("0x%x is not a task_t\n", addr);
        !           864:                return;
        !           865:        }
        !           866: 
        !           867:        db_print_task_vm(task, task_id, TRUE, modif);
        !           868: }
        !           869: 
        !           870: void
        !           871: db_show_all_task_vm(
        !           872:        db_expr_t       addr,
        !           873:        boolean_t       have_addr,
        !           874:        db_expr_t       count,
        !           875:        char            *modif)
        !           876: {
        !           877:        task_t          task;
        !           878:        int             task_id;
        !           879:        boolean_t       title = TRUE;
        !           880:        processor_set_t pset;
        !           881: 
        !           882:        task_id = 0;
        !           883:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           884:                queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           885:                        db_print_task_vm(task, task_id, title, modif);
        !           886:                        title = FALSE;
        !           887:                        task_id++;
        !           888:                }
        !           889:        }
        !           890: }
        !           891: 
        !           892: void
        !           893: db_show_all_acts(
        !           894:        db_expr_t       addr,
        !           895:        boolean_t       have_addr,
        !           896:        db_expr_t       count,
        !           897:        char *          modif)
        !           898: {
        !           899:        task_t task;
        !           900:        int task_id;
        !           901:        int flag;
        !           902:        processor_set_t pset;
        !           903: 
        !           904:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !           905:        if (db_option(modif, 'u'))
        !           906:            flag |= OPTION_USER;
        !           907:        if (db_option(modif, 'l'))
        !           908:            flag |= OPTION_LONG;
        !           909: 
        !           910:        task_id = 0;
        !           911:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           912:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           913:                db_print_task(task, task_id, flag);
        !           914:                flag &= ~OPTION_TASK_TITLE;
        !           915:                task_id++;
        !           916:                if ((flag & (OPTION_LONG|OPTION_INDENT)) == OPTION_INDENT)
        !           917:                    db_printf("\n");
        !           918:            }
        !           919:        }
        !           920: }
        !           921: 
        !           922: void
        !           923: db_show_one_space(
        !           924:        db_expr_t       addr,
        !           925:        boolean_t       have_addr,
        !           926:        db_expr_t       count,
        !           927:        char *          modif)
        !           928: {
        !           929:        int             flag;
        !           930:        int             task_id;
        !           931:        task_t          task;
        !           932: 
        !           933:        flag = OPTION_TASK_TITLE;
        !           934:        if (db_option(modif, 'u'))
        !           935:            flag |= OPTION_USER;
        !           936:        if (db_option(modif, 'l'))
        !           937:            flag |= OPTION_LONG;
        !           938: 
        !           939:        if (!have_addr) {
        !           940:            task = db_current_task();
        !           941:            if (task == TASK_NULL) {
        !           942:                db_error("No task\n");
        !           943:                /*NOTREACHED*/
        !           944:            }
        !           945:        } else
        !           946:            task = (task_t) addr;
        !           947: 
        !           948:        if ((task_id = db_lookup_task(task)) < 0) {
        !           949:            db_printf("bad task address 0x%x\n", addr);
        !           950:            db_error(0);
        !           951:            /*NOTREACHED*/
        !           952:        }
        !           953: 
        !           954:        db_printf(" ID: TASK     SPACE    MAP               COUNT\n");
        !           955:        db_print_space(task, task_id, flag);
        !           956: }
        !           957: 
        !           958: void
        !           959: db_show_all_spaces(
        !           960:        db_expr_t       addr,
        !           961:        boolean_t       have_addr,
        !           962:        db_expr_t       count,
        !           963:        char *          modif)
        !           964: {
        !           965:        task_t task;
        !           966:        int task_id = 0;
        !           967:        int flag;
        !           968:        processor_set_t pset;
        !           969: 
        !           970:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !           971:        if (db_option(modif, 'u'))
        !           972:            flag |= OPTION_USER;
        !           973:        if (db_option(modif, 'l'))
        !           974:            flag |= OPTION_LONG;
        !           975: 
        !           976:        db_printf(" ID: TASK     SPACE    MAP               COUNT\n");
        !           977:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           978:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           979:                    db_print_space(task, task_id, flag);
        !           980:                    task_id++;
        !           981:            }
        !           982:        }
        !           983: }
        !           984: 
        !           985: db_addr_t
        !           986: db_task_from_space(
        !           987:        ipc_space_t     space,
        !           988:        int             *task_id)
        !           989: {
        !           990:        task_t task;
        !           991:        int tid = 0;
        !           992:        processor_set_t pset;
        !           993: 
        !           994:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           995:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           996:                    if (task->itk_space == space) {
        !           997:                            *task_id = tid;
        !           998:                            return (db_addr_t)task;
        !           999:                    }
        !          1000:                    tid++;
        !          1001:            }
        !          1002:        }
        !          1003:        *task_id = 0;
        !          1004:        return (0);
        !          1005: }
        !          1006: 
        !          1007: void
        !          1008: db_show_one_act(
        !          1009:        db_expr_t       addr,
        !          1010:        boolean_t       have_addr,
        !          1011:        db_expr_t       count,
        !          1012:        char *          modif)
        !          1013: {
        !          1014:        int             flag;
        !          1015:        int             act_id;
        !          1016:        thread_act_t            thr_act;
        !          1017: 
        !          1018:        flag = OPTION_THREAD_TITLE;
        !          1019:        if (db_option(modif, 'u'))
        !          1020:            flag |= OPTION_USER;
        !          1021:        if (db_option(modif, 'l'))
        !          1022:            flag |= OPTION_LONG;
        !          1023: 
        !          1024:        if (!have_addr) {
        !          1025:            thr_act = current_act();
        !          1026:            if (thr_act == THR_ACT_NULL) {
        !          1027:                db_error("No thr_act\n");
        !          1028:                /*NOTREACHED*/
        !          1029:            }
        !          1030:        } else
        !          1031:            thr_act = (thread_act_t) addr;
        !          1032: 
        !          1033:        if ((act_id = db_lookup_act(thr_act)) < 0) {
        !          1034:            db_printf("bad thr_act address %#x\n", addr);
        !          1035:            db_error(0);
        !          1036:            /*NOTREACHED*/
        !          1037:        }
        !          1038: 
        !          1039:        if (flag & OPTION_USER) {
        !          1040:            db_printf("TASK%d(%0*X):\n",
        !          1041:                      db_lookup_task(thr_act->task),
        !          1042:                      2*sizeof(vm_offset_t), thr_act->task);
        !          1043:            db_print_act(thr_act, act_id, flag);
        !          1044:        } else {
        !          1045:            db_printf("task %d(%0*Xx): thr_act    %d",
        !          1046:                      db_lookup_task(thr_act->task),
        !          1047:                      2*sizeof(vm_offset_t), thr_act->task, act_id);
        !          1048:            db_print_act(thr_act, act_id, flag);
        !          1049:        }
        !          1050:        if (db_option(modif, 'i') &&  thr_act->thread &&
        !          1051:            (thr_act->thread->state & TH_WAIT) && 
        !          1052:            thr_act->thread->kernel_stack == 0) {
        !          1053: 
        !          1054:            db_printf("Wait State: option 0x%x\n",
        !          1055:                thr_act->thread->ith_option);
        !          1056:        }
        !          1057: }
        !          1058: 
        !          1059: void
        !          1060: db_show_one_task(
        !          1061:        db_expr_t       addr,
        !          1062:        boolean_t       have_addr,
        !          1063:        db_expr_t       count,
        !          1064:        char *          modif)
        !          1065: {
        !          1066:        int             flag;
        !          1067:        int             task_id;
        !          1068:        task_t          task;
        !          1069: 
        !          1070:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
        !          1071:        if (db_option(modif, 'u'))
        !          1072:            flag |= OPTION_USER;
        !          1073:        if (db_option(modif, 'l'))
        !          1074:            flag |= OPTION_LONG;
        !          1075: 
        !          1076:        if (!have_addr) {
        !          1077:            task = db_current_task();
        !          1078:            if (task == TASK_NULL) {
        !          1079:                db_error("No task\n");
        !          1080:                /*NOTREACHED*/
        !          1081:            }
        !          1082:        } else
        !          1083:            task = (task_t) addr;
        !          1084: 
        !          1085:        if ((task_id = db_lookup_task(task)) < 0) {
        !          1086:            db_printf("bad task address 0x%x\n", addr);
        !          1087:            db_error(0);
        !          1088:            /*NOTREACHED*/
        !          1089:        }
        !          1090: 
        !          1091:        db_print_task(task, task_id, flag);
        !          1092: }
        !          1093: 
        !          1094: void
        !          1095: db_show_shuttle(
        !          1096:        db_expr_t       addr,
        !          1097:        boolean_t       have_addr,
        !          1098:        db_expr_t       count,
        !          1099:        char *          modif)
        !          1100: {
        !          1101:        thread_shuttle_t        shuttle;
        !          1102:        thread_act_t            thr_act;
        !          1103: 
        !          1104:        if (have_addr)
        !          1105:            shuttle = (thread_shuttle_t) addr;
        !          1106:        else {
        !          1107:            thr_act = current_act();
        !          1108:            if (thr_act == THR_ACT_NULL) {
        !          1109:                db_error("No thr_act\n");
        !          1110:                /*NOTREACHED*/
        !          1111:            }
        !          1112:            shuttle = thr_act->thread;
        !          1113:            if (shuttle == THREAD_NULL) {
        !          1114:                db_error("No shuttle associated with current thr_act\n");
        !          1115:                /*NOTREACHED*/
        !          1116:            }
        !          1117:        }
        !          1118:        db_printf("shuttle %x:\n", shuttle);
        !          1119:        if (shuttle->top_act == THR_ACT_NULL)
        !          1120:            db_printf("  no activations\n");
        !          1121:        else {
        !          1122:            db_printf("  activations:");
        !          1123:            for (thr_act = shuttle->top_act; thr_act != THR_ACT_NULL;
        !          1124:                 thr_act = thr_act->lower) {
        !          1125:                if (thr_act != shuttle->top_act)
        !          1126:                    printf(" from");
        !          1127:                printf(" $task%d.%d(%x)", db_lookup_task(thr_act->task),
        !          1128:                       db_lookup_act(thr_act), thr_act);
        !          1129:            }
        !          1130:            db_printf("\n");
        !          1131:        }
        !          1132: }
        !          1133: 
        !          1134: int
        !          1135: db_port_kmsg_count(
        !          1136:        ipc_port_t      port)
        !          1137: {
        !          1138:        return (port->ip_messages.imq_msgcount);
        !          1139: }
        !          1140: 
        !          1141: static int db_print_ent_cnt = 0;
        !          1142: 
        !          1143: void db_reset_print_entry(
        !          1144:        void)
        !          1145: {
        !          1146:        db_print_ent_cnt = 0;
        !          1147: }
        !          1148: 
        !          1149: void
        !          1150: db_print_one_entry(
        !          1151:        ipc_entry_t             entry,
        !          1152:        int                     index,
        !          1153:        mach_port_name_t        name,
        !          1154:        boolean_t               is_pset,
        !          1155:        ipc_space_t             space)
        !          1156: {
        !          1157:        ipc_port_t aport = (ipc_port_t)entry->ie_object;
        !          1158:        ipc_entry_bits_t bits;
        !          1159: 
        !          1160:        bits = entry->ie_bits;
        !          1161:        if (is_pset && !aport->ip_pset_count)
        !          1162:                return;
        !          1163:        if (db_print_ent_cnt && db_print_ent_cnt % 2 == 0)
        !          1164:                db_printf("\n");
        !          1165:        if (!name)
        !          1166:                db_printf("\t%s%d[%x]",
        !          1167:                        !is_pset && aport->ip_pset_count ? "pset" : "port",
        !          1168:                        index,
        !          1169:                        MACH_PORT_MAKE(index, IE_BITS_GEN(bits)));
        !          1170:        else
        !          1171:                db_printf("\t%s[%x]",
        !          1172:                        !is_pset && aport->ip_pset_count ? "pset" : "port",
        !          1173:                        name);
        !          1174:        if (!is_pset) {
        !          1175:                db_printf("(%s,%x,%d)",
        !          1176:                    (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1177:                        (bits & MACH_PORT_TYPE_SEND)? "s": "S",
        !          1178:                        aport,
        !          1179:                    db_port_kmsg_count(aport));
        !          1180:                db_print_ent_cnt++;
        !          1181:        }
        !          1182:        else {
        !          1183:                db_printf("(%s,%x,set_count=%d,%d)",
        !          1184:                        (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1185:                                (bits & MACH_PORT_TYPE_SEND)? "s": "S",
        !          1186:                        aport,
        !          1187:                        aport->ip_pset_count,
        !          1188:                        db_port_kmsg_count(aport));
        !          1189:                db_print_ent_cnt++;
        !          1190:        }
        !          1191: }
        !          1192: 
        !          1193: int
        !          1194: db_port_iterate(
        !          1195:        thread_act_t    thr_act,
        !          1196:        boolean_t       is_pset,
        !          1197:        boolean_t       do_output)
        !          1198: {
        !          1199:        ipc_entry_t entry;
        !          1200:        ipc_tree_entry_t tentry;
        !          1201:        int index;
        !          1202:        int size;
        !          1203:        int count;
        !          1204:        ipc_space_t space;
        !          1205: 
        !          1206:        count = 0;
        !          1207:        space = thr_act->task->itk_space;
        !          1208:        entry = space->is_table;
        !          1209:        size = space->is_table_size;
        !          1210:        db_reset_print_entry();
        !          1211:        for (index = 0; index < size; ++index, ++entry) {
        !          1212:                if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) {
        !          1213:                        if (do_output)
        !          1214:                                db_print_one_entry(entry,
        !          1215:                                        index, MACH_PORT_NULL, is_pset, space);
        !          1216:                        ++count;
        !          1217:                }
        !          1218:        }
        !          1219:        for (tentry = ipc_splay_traverse_start(&space->is_tree);
        !          1220:                tentry != ITE_NULL;
        !          1221:                tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
        !          1222:                entry = &tentry->ite_entry;
        !          1223:                if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) {
        !          1224:                        if (do_output)
        !          1225:                                db_print_one_entry(entry,
        !          1226:                                        0, tentry->ite_name, is_pset, space);
        !          1227:                        ++count;
        !          1228:                }
        !          1229:        }
        !          1230:        return (count);
        !          1231: }
        !          1232: 
        !          1233: ipc_port_t
        !          1234: db_lookup_port(
        !          1235:        thread_act_t    thr_act,
        !          1236:        int             id)
        !          1237: {
        !          1238:        register ipc_space_t space;
        !          1239:        register ipc_entry_t entry;
        !          1240: 
        !          1241:        if (thr_act == THR_ACT_NULL)
        !          1242:            return(0);
        !          1243:        space = thr_act->task->itk_space;
        !          1244:        if (id < 0 || id >= space->is_table_size)
        !          1245:            return(0);
        !          1246:        entry = &space->is_table[id];
        !          1247:        if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
        !          1248:            return((ipc_port_t)entry->ie_object);
        !          1249:        return(0);
        !          1250: }
        !          1251: 
        !          1252: static void
        !          1253: db_print_port_id(
        !          1254:        int             id,
        !          1255:        ipc_port_t      port,
        !          1256:        unsigned        bits,
        !          1257:        int             n)
        !          1258: {
        !          1259:        if (n != 0 && n % 3 == 0)
        !          1260:            db_printf("\n");
        !          1261:        db_printf("\tport%d(%s,%x)", id,
        !          1262:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
        !          1263:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
        !          1264: }
        !          1265: 
        !          1266: void
        !          1267: db_show_port_id(
        !          1268:        db_expr_t       addr,
        !          1269:        boolean_t       have_addr,
        !          1270:        db_expr_t       count,
        !          1271:        char *          modif)
        !          1272: {
        !          1273:        thread_act_t thr_act;
        !          1274: 
        !          1275:        if (!have_addr) {
        !          1276:            thr_act = current_act();
        !          1277:            if (thr_act == THR_ACT_NULL) {
        !          1278:                db_error("No thr_act\n");
        !          1279:                /*NOTREACHED*/
        !          1280:            }
        !          1281:        } else
        !          1282:            thr_act = (thread_act_t) addr;
        !          1283:        if (db_lookup_act(thr_act) < 0) {
        !          1284:            db_printf("Bad thr_act address 0x%x\n", addr);
        !          1285:            db_error(0);
        !          1286:            /*NOTREACHED*/
        !          1287:        }
        !          1288:        if (db_port_iterate(thr_act, db_option(modif,'s'), TRUE))
        !          1289:            db_printf("\n");
        !          1290: }
        !          1291: 
        !          1292: /*
        !          1293:  *     Useful system state when the world has hung.
        !          1294:  */
        !          1295: void
        !          1296: db_system_stats()
        !          1297: {
        !          1298:        extern void     db_sched(void);
        !          1299: #if    DIPC
        !          1300:        extern void     db_dipc_stats(void);
        !          1301:        extern void     db_show_kkt(void);
        !          1302: #endif /* DIPC */
        !          1303: 
        !          1304:        db_sched();
        !          1305:        iprintf("\n");
        !          1306:        db_vm();
        !          1307:        iprintf("\n");
        !          1308: #if    DIPC
        !          1309:        iprintf("\n");
        !          1310:        db_dipc_stats();
        !          1311:        iprintf("\n");
        !          1312:        db_show_kkt();
        !          1313: #endif /* DIPC */
        !          1314:        iprintf("\n");
        !          1315:        db_printf("current_{thread/task} 0x%x 0x%x\n",
        !          1316:                        current_thread(),current_task());
        !          1317: }
        !          1318: 
        !          1319: void db_show_one_runq(run_queue_t runq);
        !          1320: 
        !          1321: void
        !          1322: db_show_runq(
        !          1323:        db_expr_t       addr,
        !          1324:        boolean_t       have_addr,
        !          1325:        db_expr_t       count,
        !          1326:        char *          modif)
        !          1327: {
        !          1328:        processor_set_t pset;
        !          1329:        processor_t proc;
        !          1330:        run_queue_t runq;
        !          1331:        boolean_t showedany = FALSE;
        !          1332: 
        !          1333:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !          1334: #if NCPUS > 1  /* This code has not been tested. */
        !          1335:            queue_iterate(&pset->processors, proc, processor_t, processors) {
        !          1336:                runq = &proc->runq;
        !          1337:                if (runq->count > 0) {
        !          1338:                    db_printf("PROCESSOR %x IN SET %x\n", proc, pset);
        !          1339:                    db_show_one_runq(runq);
        !          1340:                    showedany = TRUE;
        !          1341:                }
        !          1342:            }
        !          1343: #endif /* NCPUS > 1 */
        !          1344: #ifndef NCPUS
        !          1345: #error NCPUS undefined
        !          1346: #endif
        !          1347:            runq = &pset->runq;
        !          1348:            if (runq->count > 0) {
        !          1349:                db_printf("PROCESSOR SET %x\n", pset);
        !          1350:                db_show_one_runq(runq);
        !          1351:                showedany = TRUE;
        !          1352:            }
        !          1353:        }
        !          1354:        if (!showedany)
        !          1355:            db_printf("No runnable threads\n");
        !          1356: }
        !          1357: 
        !          1358: void
        !          1359: db_show_one_runq(
        !          1360:        run_queue_t     runq)
        !          1361: {
        !          1362:        int i, task_id, thr_act_id;
        !          1363:        queue_t q;
        !          1364:        thread_act_t thr_act;
        !          1365:        thread_t thread;
        !          1366:        task_t task;
        !          1367: 
        !          1368:        printf("PRI  TASK.ACTIVATION\n");
        !          1369:        for (i = runq->highq, q = runq->runq + i; i >= 0; i--, q--) {
        !          1370:            if (!queue_empty(q)) {
        !          1371:                db_printf("%3d:", i);
        !          1372:                queue_iterate(q, thread, thread_t, links) {
        !          1373:                    thr_act = thread->top_act;
        !          1374:                    task = thr_act->task;
        !          1375:                    task_id = db_lookup_task(task);
        !          1376:                    thr_act_id = db_lookup_task_act(task, thr_act);
        !          1377:                    db_printf(" %d.%d", task_id, thr_act_id);
        !          1378:                }
        !          1379:                db_printf("\n");
        !          1380:            }
        !          1381:        }
        !          1382: }

unix.superglobalmegacorp.com

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