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