Annotation of Gnu-Mach/ddb/db_print.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.2   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Author: David B. Golub, Carnegie Mellon University
                     28:  *     Date:   7/90
                     29:  */
                     30: 
                     31: #if MACH_KDB
                     32: 
                     33: /*
                     34:  * Miscellaneous printing.
                     35:  */
1.1.1.3 ! root       36: #include <string.h>
1.1       root       37: #include <mach/port.h>
                     38: #include <kern/task.h>
                     39: #include <kern/thread.h>
                     40: #include <kern/queue.h>
                     41: #include <ipc/ipc_port.h>
                     42: #include <ipc/ipc_space.h>
                     43: 
1.1.1.3 ! root       44: #include <machine/db_interface.h>
1.1       root       45: #include <machine/db_machdep.h>
                     46: #include <machine/thread.h>
                     47: 
1.1.1.3 ! root       48: #include <ddb/db_command.h>
        !            49: #include <ddb/db_output.h>
1.1       root       50: #include <ddb/db_lex.h>
                     51: #include <ddb/db_variables.h>
                     52: #include <ddb/db_sym.h>
                     53: #include <ddb/db_task_thread.h>
1.1.1.3 ! root       54: #include <ddb/db_print.h>
1.1       root       55: 
                     56: extern unsigned int    db_maxoff;
                     57: 
                     58: /* ARGSUSED */
                     59: void
                     60: db_show_regs(addr, have_addr, count, modif)
                     61:        db_expr_t       addr;
                     62:        boolean_t       have_addr;
                     63:        db_expr_t       count;
                     64:        char            *modif;
                     65: {
                     66:        register struct db_variable *regp;
                     67:        db_expr_t       value;
                     68:        db_addr_t       offset;
                     69:        char *          name;
1.1.1.3 ! root       70:        register        int i;
1.1       root       71:        struct db_var_aux_param aux_param;
                     72:        task_t          task = TASK_NULL;
                     73: 
                     74:        aux_param.modif = modif;
                     75:        aux_param.thread = THREAD_NULL;
                     76:        if (db_option(modif, 't')) {
                     77:            if (have_addr) {
                     78:                if (!db_check_thread_address_valid((thread_t)addr))
                     79:                    return;
                     80:                aux_param.thread = (thread_t)addr;
                     81:            } else
                     82:                aux_param.thread = db_default_thread;
                     83:            if (aux_param.thread != THREAD_NULL)
                     84:                task = aux_param.thread->task;
                     85:        }
                     86:        for (regp = db_regs; regp < db_eregs; regp++) {
                     87:            if (regp->max_level > 1) {
                     88:                db_printf("bad multi-suffixed register %s\n", regp->name);
                     89:                continue;
                     90:            }
                     91:            aux_param.level = regp->max_level;
                     92:            for (i = regp->low; i <= regp->high; i++) {
                     93:                aux_param.suffix[0] = i;
                     94:                db_read_write_variable(regp, &value, DB_VAR_GET, &aux_param);
                     95:                if (regp->max_level > 0)
1.1.1.2   root       96:                    db_printf("%s%d%*s", regp->name, i,
1.1       root       97:                                12-strlen(regp->name)-((i<10)?1:2), "");
                     98:                else
                     99:                    db_printf("%-12s", regp->name);
                    100:                db_printf("%#*N", 2+2*sizeof(vm_offset_t), value);
1.1.1.2   root      101:                db_find_xtrn_task_sym_and_offset((db_addr_t)value, &name,
1.1       root      102:                                                        &offset, task);
                    103:                if (name != 0 && offset <= db_maxoff && offset != value) {
                    104:                    db_printf("\t%s", name);
                    105:                    if (offset != 0)
                    106:                        db_printf("+%#r", offset);
                    107:                }
                    108:                db_printf("\n");
                    109:            }
                    110:        }
                    111: }
                    112: 
                    113: #define OPTION_LONG            0x001           /* long print option */
                    114: #define OPTION_USER            0x002           /* print ps-like stuff */
                    115: #define OPTION_INDENT          0x100           /* print with indent */
                    116: #define OPTION_THREAD_TITLE    0x200           /* print thread title */
                    117: #define OPTION_TASK_TITLE      0x400           /* print thread title */
                    118: 
                    119: #ifndef        DB_TASK_NAME
                    120: #define DB_TASK_NAME(task)                     /* no task name */
                    121: #define DB_TASK_NAME_TITLE     ""              /* no task name */
1.1.1.2   root      122: #endif /* DB_TASK_NAME */
1.1       root      123: 
                    124: #ifndef        db_thread_fp_used
                    125: #define db_thread_fp_used(thread)      FALSE
                    126: #endif
                    127: 
                    128: char *
                    129: db_thread_stat(thread, status)
                    130:        register thread_t thread;
                    131:        char     *status;
                    132: {
                    133:        register char *p = status;
1.1.1.2   root      134: 
1.1       root      135:        *p++ = (thread->state & TH_RUN)  ? 'R' : '.';
                    136:        *p++ = (thread->state & TH_WAIT) ? 'W' : '.';
                    137:        *p++ = (thread->state & TH_SUSP) ? 'S' : '.';
                    138:        *p++ = (thread->state & TH_SWAPPED) ? 'O' : '.';
                    139:        *p++ = (thread->state & TH_UNINT) ? 'N' : '.';
                    140:        /* show if the FPU has been used */
                    141:        *p++ = db_thread_fp_used(thread) ? 'F' : '.';
                    142:        *p++ = 0;
                    143:        return(status);
                    144: }
                    145: 
                    146: void
                    147: db_print_thread(thread, thread_id, flag)
                    148:        thread_t thread;
                    149:        int      thread_id;
                    150:        int      flag;
                    151: {
                    152:        if (flag & OPTION_USER) {
                    153:            char status[8];
                    154:            char *indent = "";
                    155: 
                    156:            if (flag & OPTION_LONG) {
                    157:                if (flag & OPTION_INDENT)
                    158:                    indent = "    ";
                    159:                if (flag & OPTION_THREAD_TITLE) {
                    160:                    db_printf("%s ID: THREAD   STAT   STACK    PCB", indent);
                    161:                    db_printf("      SUS PRI CONTINUE,WAIT_FUNC\n");
                    162:                }
                    163:                db_printf("%s%3d%c %0*X %s %0*X %0*X %3d %3d ",
                    164:                    indent, thread_id,
                    165:                    (thread == current_thread())? '#': ':',
                    166:                    2*sizeof(vm_offset_t), thread,
                    167:                    db_thread_stat(thread, status),
                    168:                    2*sizeof(vm_offset_t), thread->kernel_stack,
                    169:                    2*sizeof(vm_offset_t), thread->pcb,
                    170:                    thread->suspend_count, thread->sched_pri);
                    171:                if ((thread->state & TH_SWAPPED) && thread->swap_func) {
                    172:                    db_task_printsym((db_addr_t)thread->swap_func,
                    173:                                     DB_STGY_ANY, kernel_task);
                    174:                    db_printf(", ");
                    175:                }
                    176:                if (thread->state & TH_WAIT)
                    177:                    db_task_printsym((db_addr_t)thread->wait_event,
                    178:                                     DB_STGY_ANY, kernel_task);
                    179:                db_printf("\n");
                    180:            } else {
                    181:                if (thread_id % 3 == 0) {
                    182:                    if (flag & OPTION_INDENT)
                    183:                        db_printf("\n    ");
                    184:                } else
                    185:                    db_printf(" ");
1.1.1.2   root      186:                db_printf("%3d%c(%0*X,%s)", thread_id,
1.1       root      187:                    (thread == current_thread())? '#': ':',
                    188:                    2*sizeof(vm_offset_t), thread,
                    189:                    db_thread_stat(thread, status));
                    190:            }
                    191:        } else {
                    192:            if (flag & OPTION_INDENT)
                    193:                db_printf("            %3d (%0*X) ", thread_id,
                    194:                          2*sizeof(vm_offset_t), thread);
                    195:            else
                    196:                db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thread);
                    197:            db_printf("%c%c%c%c%c",
                    198:                      (thread->state & TH_RUN)  ? 'R' : ' ',
                    199:                      (thread->state & TH_WAIT) ? 'W' : ' ',
                    200:                      (thread->state & TH_SUSP) ? 'S' : ' ',
                    201:                      (thread->state & TH_UNINT)? 'N' : ' ',
                    202:                      db_thread_fp_used(thread) ? 'F' : ' ');
                    203:            if (thread->state & TH_SWAPPED) {
                    204:                if (thread->swap_func) {
                    205:                    db_printf("(");
1.1.1.2   root      206:                    db_task_printsym((db_addr_t)thread->swap_func,
1.1       root      207:                                     DB_STGY_ANY, kernel_task);
                    208:                    db_printf(")");
                    209:                } else {
                    210:                    db_printf("(swapped)");
                    211:                }
                    212:            }
                    213:            if (thread->state & TH_WAIT) {
                    214:                db_printf(" ");
1.1.1.2   root      215:                db_task_printsym((db_addr_t)thread->wait_event,
1.1       root      216:                            DB_STGY_ANY, kernel_task);
                    217:            }
                    218:            db_printf("\n");
                    219:        }
                    220: }
                    221: 
                    222: void
                    223: db_print_task(task, task_id, flag)
                    224:        task_t  task;
                    225:        int     task_id;
                    226:        int     flag;
                    227: {
                    228:        thread_t thread;
                    229:        int thread_id;
                    230: 
                    231:        if (flag & OPTION_USER) {
                    232:            if (flag & OPTION_TASK_TITLE) {
1.1.1.2   root      233:                db_printf(" ID: TASK     MAP      THD SUS PR %s",
1.1       root      234:                          DB_TASK_NAME_TITLE);
                    235:                if ((flag & OPTION_LONG) == 0)
                    236:                    db_printf("  THREADS");
                    237:                db_printf("\n");
                    238:            }
                    239:            db_printf("%3d: %0*X %0*X %3d %3d %2d ",
                    240:                            task_id, 2*sizeof(vm_offset_t), task,
                    241:                            2*sizeof(vm_offset_t), task->map, task->thread_count,
                    242:                            task->suspend_count, task->priority);
                    243:            DB_TASK_NAME(task);
                    244:            if (flag & OPTION_LONG) {
                    245:                if (flag & OPTION_TASK_TITLE)
                    246:                    flag |= OPTION_THREAD_TITLE;
                    247:                db_printf("\n");
                    248:            } else if (task->thread_count <= 1)
                    249:                flag &= ~OPTION_INDENT;
                    250:            thread_id = 0;
                    251:            queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
                    252:                db_print_thread(thread, thread_id, flag);
                    253:                flag &= ~OPTION_THREAD_TITLE;
                    254:                thread_id++;
                    255:            }
                    256:            if ((flag & OPTION_LONG) == 0)
                    257:                db_printf("\n");
                    258:        } else {
                    259:            if (flag & OPTION_TASK_TITLE)
                    260:                db_printf("    TASK        THREADS\n");
                    261:            db_printf("%3d (%0*X): ", task_id, 2*sizeof(vm_offset_t), task);
                    262:            if (task->thread_count == 0) {
                    263:                db_printf("no threads\n");
                    264:            } else {
                    265:                if (task->thread_count > 1) {
                    266:                    db_printf("%d threads: \n", task->thread_count);
                    267:                    flag |= OPTION_INDENT;
                    268:                } else
                    269:                    flag &= ~OPTION_INDENT;
                    270:                thread_id = 0;
                    271:                queue_iterate(&task->thread_list, thread,
                    272:                              thread_t, thread_list)
                    273:                    db_print_thread(thread, thread_id++, flag);
                    274:            }
                    275:        }
                    276: }
                    277: 
                    278: /*ARGSUSED*/
                    279: void
                    280: db_show_all_threads(addr, have_addr, count, modif)
                    281:        db_expr_t       addr;
                    282:        boolean_t       have_addr;
                    283:        db_expr_t       count;
                    284:        char *          modif;
                    285: {
                    286:        task_t task;
                    287:        int task_id;
                    288:        int flag;
                    289:        processor_set_t pset;
                    290: 
                    291:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
                    292:        if (db_option(modif, 'u'))
                    293:            flag |= OPTION_USER;
                    294:        if (db_option(modif, 'l'))
                    295:            flag |= OPTION_LONG;
                    296: 
                    297:        task_id = 0;
                    298:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                    299:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                    300:                db_print_task(task, task_id, flag);
                    301:                flag &= ~OPTION_TASK_TITLE;
                    302:                task_id++;
                    303:            }
                    304:        }
                    305: }
                    306: 
                    307: db_addr_t
                    308: db_task_from_space(
                    309:        ipc_space_t     space,
                    310:        int             *task_id)
                    311: {
                    312:        task_t task;
                    313:        int tid = 0;
                    314:        processor_set_t pset;
                    315: 
                    316:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                    317:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                    318:                    if (task->itk_space == space) {
                    319:                            *task_id = tid;
                    320:                            return (db_addr_t)task;
                    321:                    }
                    322:                    tid++;
                    323:            }
                    324:        }
                    325:        *task_id = 0;
                    326:        return (0);
                    327: }
                    328: 
                    329: /*ARGSUSED*/
                    330: void
                    331: db_show_one_thread(addr, have_addr, count, modif)
                    332:        db_expr_t       addr;
                    333:        boolean_t       have_addr;
                    334:        db_expr_t       count;
                    335:        char *          modif;
                    336: {
                    337:        int             flag;
                    338:        int             thread_id;
                    339:        thread_t        thread;
                    340: 
                    341:        flag = OPTION_THREAD_TITLE;
                    342:        if (db_option(modif, 'u'))
                    343:            flag |= OPTION_USER;
                    344:        if (db_option(modif, 'l'))
                    345:            flag |= OPTION_LONG;
                    346: 
                    347:        if (!have_addr) {
                    348:            thread = current_thread();
                    349:            if (thread == THREAD_NULL) {
                    350:                db_error("No thread\n");
                    351:                /*NOTREACHED*/
                    352:            }
                    353:        } else
                    354:            thread = (thread_t) addr;
                    355: 
                    356:        if ((thread_id = db_lookup_thread(thread)) < 0) {
                    357:            db_printf("bad thread address %#X\n", addr);
                    358:            db_error(0);
                    359:            /*NOTREACHED*/
                    360:        }
                    361: 
                    362:        if (flag & OPTION_USER) {
                    363:            db_printf("TASK%d(%0*X):\n",
                    364:                      db_lookup_task(thread->task),
                    365:                      2*sizeof(vm_offset_t), thread->task);
                    366:            db_print_thread(thread, thread_id, flag);
                    367:        } else {
                    368:            db_printf("task %d(%0*X): thread %d",
                    369:                      db_lookup_task(thread->task),
                    370:                      2*sizeof(vm_offset_t), thread->task, thread_id);
                    371:            db_print_thread(thread, thread_id, flag);
                    372:        }
                    373: }
                    374: 
                    375: /*ARGSUSED*/
                    376: void
                    377: db_show_one_task(addr, have_addr, count, modif)
                    378:        db_expr_t       addr;
                    379:        boolean_t       have_addr;
                    380:        db_expr_t       count;
                    381:        char *          modif;
                    382: {
                    383:        int             flag;
                    384:        int             task_id;
                    385:        task_t          task;
                    386: 
                    387:        flag = OPTION_TASK_TITLE;
                    388:        if (db_option(modif, 'u'))
                    389:            flag |= OPTION_USER;
                    390:        if (db_option(modif, 'l'))
                    391:            flag |= OPTION_LONG;
                    392: 
                    393:        if (!have_addr) {
                    394:            task = db_current_task();
                    395:            if (task == TASK_NULL) {
                    396:                db_error("No task\n");
                    397:                /*NOTREACHED*/
                    398:            }
                    399:        } else
                    400:            task = (task_t) addr;
                    401: 
                    402:        if ((task_id = db_lookup_task(task)) < 0) {
                    403:            db_printf("bad task address %#X\n", addr);
                    404:            db_error(0);
                    405:            /*NOTREACHED*/
                    406:        }
                    407: 
                    408:        db_print_task(task, task_id, flag);
                    409: }
                    410: 
                    411: int
                    412: db_port_iterate(thread, func)
                    413:        thread_t thread;
                    414:        void (*func)();
                    415: {
                    416:        ipc_entry_t entry;
                    417:        int index;
                    418:        int n = 0;
                    419:        int size;
                    420:        ipc_space_t space;
                    421: 
                    422:        space = thread->task->itk_space;
                    423:        entry = space->is_table;
                    424:        size = space->is_table_size;
                    425:        for (index = 0; index < size; index++, entry++) {
                    426:            if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
                    427:                (*func)(index, (ipc_port_t) entry->ie_object,
                    428:                        entry->ie_bits, n++);
                    429:        }
                    430:        return(n);
                    431: }
                    432: 
                    433: ipc_port_t
                    434: db_lookup_port(thread, id)
                    435:        thread_t thread;
                    436:        int id;
                    437: {
                    438:        register ipc_space_t space;
                    439:        register ipc_entry_t entry;
                    440: 
                    441:        if (thread == THREAD_NULL)
                    442:            return(0);
                    443:        space = thread->task->itk_space;
                    444:        if (id < 0 || id >= space->is_table_size)
                    445:            return(0);
                    446:        entry = &space->is_table[id];
                    447:        if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
                    448:            return((ipc_port_t)entry->ie_object);
                    449:        return(0);
                    450: }
                    451: 
                    452: static void
                    453: db_print_port_id(id, port, bits, n)
                    454:        int id;
                    455:        ipc_port_t port;
                    456:        unsigned bits;
                    457:        int n;
                    458: {
                    459:        if (n != 0 && n % 3 == 0)
                    460:            db_printf("\n");
                    461:        db_printf("\tport%d(%s,%x)", id,
                    462:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    463:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    464: }
                    465: 
                    466: static void
                    467: db_print_port_id_long(
                    468:        int id,
                    469:        ipc_port_t port,
                    470:        unsigned bits,
                    471:        int n)
                    472: {
                    473:        if (n != 0)
                    474:            db_printf("\n");
                    475:        db_printf("\tport%d(%s, port=0x%x", id,
                    476:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    477:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    478:        db_printf(", receiver_name=0x%x)", port->ip_receiver_name);
                    479: }
                    480: 
                    481: /* ARGSUSED */
                    482: void
                    483: db_show_port_id(addr, have_addr, count, modif)
                    484:        db_expr_t       addr;
                    485:        boolean_t       have_addr;
                    486:        db_expr_t       count;
                    487:        char *          modif;
                    488: {
                    489:        thread_t thread;
                    490: 
                    491:        if (!have_addr) {
                    492:            thread = current_thread();
                    493:            if (thread == THREAD_NULL) {
                    494:                db_error("No thread\n");
                    495:                /*NOTREACHED*/
                    496:            }
                    497:        } else
                    498:            thread = (thread_t) addr;
                    499:        if (db_lookup_thread(thread) < 0) {
                    500:            db_printf("Bad thread address %#X\n", addr);
                    501:            db_error(0);
                    502:            /*NOTREACHED*/
                    503:        }
                    504:        if (db_option(modif, 'l'))
                    505:          {
                    506:            if (db_port_iterate(thread, db_print_port_id_long))
                    507:              db_printf("\n");
                    508:            return;
                    509:          }
                    510:        if (db_port_iterate(thread, db_print_port_id))
                    511:            db_printf("\n");
                    512: }
                    513: 
1.1.1.2   root      514: #endif /* MACH_KDB */

unix.superglobalmegacorp.com

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