|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.