Annotation of XNU/osfmk/ddb/db_print.c, revision 1.1.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.