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

unix.superglobalmegacorp.com

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