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

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: 
1.1.1.4 ! root       56: extern unsigned long   db_maxoff;
1.1       root       57: 
                     58: /* ARGSUSED */
                     59: void
1.1.1.4 ! root       60: db_show_regs(
        !            61:        db_expr_t       addr,
        !            62:        boolean_t       have_addr,
        !            63:        db_expr_t       count,
        !            64:        char            *modif)
1.1       root       65: {
1.1.1.4 ! root       66:        struct          db_variable *regp;
1.1       root       67:        db_expr_t       value;
                     68:        db_addr_t       offset;
                     69:        char *          name;
1.1.1.4 ! root       70:        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)
1.1.1.4 ! root      130:        const thread_t  thread;
        !           131:        char            *status;
1.1       root      132: {
1.1.1.4 ! root      133:        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
1.1.1.4 ! root      147: db_print_thread(
        !           148:        thread_t thread,
        !           149:        int      thread_id,
        !           150:        int      flag)
1.1       root      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);
1.1.1.4 ! root      197:            char status[8];
        !           198:            db_printf("%s", db_thread_stat(thread, status));
1.1       root      199:            if (thread->state & TH_SWAPPED) {
                    200:                if (thread->swap_func) {
                    201:                    db_printf("(");
1.1.1.2   root      202:                    db_task_printsym((db_addr_t)thread->swap_func,
1.1       root      203:                                     DB_STGY_ANY, kernel_task);
                    204:                    db_printf(")");
                    205:                } else {
                    206:                    db_printf("(swapped)");
                    207:                }
                    208:            }
                    209:            if (thread->state & TH_WAIT) {
                    210:                db_printf(" ");
1.1.1.2   root      211:                db_task_printsym((db_addr_t)thread->wait_event,
1.1       root      212:                            DB_STGY_ANY, kernel_task);
                    213:            }
                    214:            db_printf("\n");
                    215:        }
                    216: }
                    217: 
                    218: void
1.1.1.4 ! root      219: db_print_task(
        !           220:        task_t  task,
        !           221:        int     task_id,
        !           222:        int     flag)
1.1       root      223: {
                    224:        thread_t thread;
                    225:        int thread_id;
                    226: 
                    227:        if (flag & OPTION_USER) {
                    228:            if (flag & OPTION_TASK_TITLE) {
1.1.1.2   root      229:                db_printf(" ID: TASK     MAP      THD SUS PR %s",
1.1       root      230:                          DB_TASK_NAME_TITLE);
                    231:                if ((flag & OPTION_LONG) == 0)
                    232:                    db_printf("  THREADS");
                    233:                db_printf("\n");
                    234:            }
                    235:            db_printf("%3d: %0*X %0*X %3d %3d %2d ",
                    236:                            task_id, 2*sizeof(vm_offset_t), task,
                    237:                            2*sizeof(vm_offset_t), task->map, task->thread_count,
                    238:                            task->suspend_count, task->priority);
                    239:            DB_TASK_NAME(task);
                    240:            if (flag & OPTION_LONG) {
                    241:                if (flag & OPTION_TASK_TITLE)
                    242:                    flag |= OPTION_THREAD_TITLE;
                    243:                db_printf("\n");
                    244:            } else if (task->thread_count <= 1)
                    245:                flag &= ~OPTION_INDENT;
                    246:            thread_id = 0;
                    247:            queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
                    248:                db_print_thread(thread, thread_id, flag);
                    249:                flag &= ~OPTION_THREAD_TITLE;
                    250:                thread_id++;
                    251:            }
                    252:            if ((flag & OPTION_LONG) == 0)
                    253:                db_printf("\n");
                    254:        } else {
                    255:            if (flag & OPTION_TASK_TITLE)
                    256:                db_printf("    TASK        THREADS\n");
1.1.1.4 ! root      257:            if (task->name[0])
        !           258:                db_printf("%3d %s (%0*X): ", task_id, task->name,
        !           259:                          2*sizeof(vm_offset_t), task);
        !           260:            else
        !           261:                db_printf("%3d (%0*X): ", task_id,
        !           262:                          2*sizeof(vm_offset_t), task);
1.1       root      263:            if (task->thread_count == 0) {
                    264:                db_printf("no threads\n");
                    265:            } else {
                    266:                if (task->thread_count > 1) {
                    267:                    db_printf("%d threads: \n", task->thread_count);
                    268:                    flag |= OPTION_INDENT;
                    269:                } else
                    270:                    flag &= ~OPTION_INDENT;
                    271:                thread_id = 0;
                    272:                queue_iterate(&task->thread_list, thread,
                    273:                              thread_t, thread_list)
                    274:                    db_print_thread(thread, thread_id++, flag);
                    275:            }
                    276:        }
                    277: }
                    278: 
1.1.1.4 ! root      279: void
        !           280: db_show_all_tasks(db_expr_t addr,
        !           281:                  boolean_t have_addr,
        !           282:                  db_expr_t count,
        !           283:                  const char *modif)
        !           284: {
        !           285:        task_t task;
        !           286:        int task_id = 0;
        !           287:        processor_set_t pset;
        !           288: 
        !           289:        db_printf(" ID %-*s NAME [THREADS]\n", 2*sizeof(vm_offset_t), "TASK");
        !           290: 
        !           291:        queue_iterate(&all_psets, pset, processor_set_t, all_psets)
        !           292:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           293:                db_printf("%3d %0*X %s [%d]\n",
        !           294:                          task_id,
        !           295:                          2*sizeof(vm_offset_t),
        !           296:                          task,
        !           297:                          task->name,
        !           298:                          task->thread_count);
        !           299:                task_id++;
        !           300:            }
        !           301: }
        !           302: 
1.1       root      303: /*ARGSUSED*/
                    304: void
                    305: db_show_all_threads(addr, have_addr, count, modif)
                    306:        db_expr_t       addr;
                    307:        boolean_t       have_addr;
                    308:        db_expr_t       count;
1.1.1.4 ! root      309:        const char *    modif;
1.1       root      310: {
                    311:        task_t task;
                    312:        int task_id;
                    313:        int flag;
                    314:        processor_set_t pset;
                    315: 
                    316:        flag = OPTION_TASK_TITLE|OPTION_INDENT;
                    317:        if (db_option(modif, 'u'))
                    318:            flag |= OPTION_USER;
                    319:        if (db_option(modif, 'l'))
                    320:            flag |= OPTION_LONG;
                    321: 
                    322:        task_id = 0;
                    323:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                    324:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                    325:                db_print_task(task, task_id, flag);
                    326:                flag &= ~OPTION_TASK_TITLE;
                    327:                task_id++;
                    328:            }
                    329:        }
                    330: }
                    331: 
                    332: db_addr_t
                    333: db_task_from_space(
                    334:        ipc_space_t     space,
                    335:        int             *task_id)
                    336: {
                    337:        task_t task;
                    338:        int tid = 0;
                    339:        processor_set_t pset;
                    340: 
                    341:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                    342:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                    343:                    if (task->itk_space == space) {
                    344:                            *task_id = tid;
                    345:                            return (db_addr_t)task;
                    346:                    }
                    347:                    tid++;
                    348:            }
                    349:        }
                    350:        *task_id = 0;
                    351:        return (0);
                    352: }
                    353: 
                    354: /*ARGSUSED*/
                    355: void
                    356: db_show_one_thread(addr, have_addr, count, modif)
                    357:        db_expr_t       addr;
                    358:        boolean_t       have_addr;
                    359:        db_expr_t       count;
1.1.1.4 ! root      360:        const char *    modif;
1.1       root      361: {
                    362:        int             flag;
                    363:        int             thread_id;
                    364:        thread_t        thread;
                    365: 
                    366:        flag = OPTION_THREAD_TITLE;
                    367:        if (db_option(modif, 'u'))
                    368:            flag |= OPTION_USER;
                    369:        if (db_option(modif, 'l'))
                    370:            flag |= OPTION_LONG;
                    371: 
                    372:        if (!have_addr) {
                    373:            thread = current_thread();
                    374:            if (thread == THREAD_NULL) {
                    375:                db_error("No thread\n");
                    376:                /*NOTREACHED*/
                    377:            }
                    378:        } else
                    379:            thread = (thread_t) addr;
                    380: 
                    381:        if ((thread_id = db_lookup_thread(thread)) < 0) {
                    382:            db_printf("bad thread address %#X\n", addr);
                    383:            db_error(0);
                    384:            /*NOTREACHED*/
                    385:        }
                    386: 
                    387:        if (flag & OPTION_USER) {
                    388:            db_printf("TASK%d(%0*X):\n",
                    389:                      db_lookup_task(thread->task),
                    390:                      2*sizeof(vm_offset_t), thread->task);
                    391:            db_print_thread(thread, thread_id, flag);
                    392:        } else {
                    393:            db_printf("task %d(%0*X): thread %d",
                    394:                      db_lookup_task(thread->task),
                    395:                      2*sizeof(vm_offset_t), thread->task, thread_id);
                    396:            db_print_thread(thread, thread_id, flag);
                    397:        }
                    398: }
                    399: 
                    400: /*ARGSUSED*/
                    401: void
                    402: db_show_one_task(addr, have_addr, count, modif)
                    403:        db_expr_t       addr;
                    404:        boolean_t       have_addr;
                    405:        db_expr_t       count;
1.1.1.4 ! root      406:        const char *    modif;
1.1       root      407: {
                    408:        int             flag;
                    409:        int             task_id;
                    410:        task_t          task;
                    411: 
                    412:        flag = OPTION_TASK_TITLE;
                    413:        if (db_option(modif, 'u'))
                    414:            flag |= OPTION_USER;
                    415:        if (db_option(modif, 'l'))
                    416:            flag |= OPTION_LONG;
                    417: 
                    418:        if (!have_addr) {
                    419:            task = db_current_task();
                    420:            if (task == TASK_NULL) {
                    421:                db_error("No task\n");
                    422:                /*NOTREACHED*/
                    423:            }
                    424:        } else
                    425:            task = (task_t) addr;
                    426: 
                    427:        if ((task_id = db_lookup_task(task)) < 0) {
                    428:            db_printf("bad task address %#X\n", addr);
                    429:            db_error(0);
                    430:            /*NOTREACHED*/
                    431:        }
                    432: 
                    433:        db_print_task(task, task_id, flag);
                    434: }
                    435: 
                    436: int
                    437: db_port_iterate(thread, func)
1.1.1.4 ! root      438:        const thread_t thread;
1.1       root      439:        void (*func)();
                    440: {
                    441:        ipc_entry_t entry;
                    442:        int index;
                    443:        int n = 0;
                    444:        int size;
                    445:        ipc_space_t space;
                    446: 
                    447:        space = thread->task->itk_space;
                    448:        entry = space->is_table;
                    449:        size = space->is_table_size;
                    450:        for (index = 0; index < size; index++, entry++) {
                    451:            if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
                    452:                (*func)(index, (ipc_port_t) entry->ie_object,
                    453:                        entry->ie_bits, n++);
                    454:        }
                    455:        return(n);
                    456: }
                    457: 
                    458: ipc_port_t
1.1.1.4 ! root      459: db_lookup_port(
        !           460:        thread_t        thread,
        !           461:        int             id)
1.1       root      462: {
1.1.1.4 ! root      463:        ipc_space_t space;
        !           464:        ipc_entry_t entry;
1.1       root      465: 
                    466:        if (thread == THREAD_NULL)
                    467:            return(0);
                    468:        space = thread->task->itk_space;
                    469:        if (id < 0 || id >= space->is_table_size)
                    470:            return(0);
                    471:        entry = &space->is_table[id];
                    472:        if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
                    473:            return((ipc_port_t)entry->ie_object);
                    474:        return(0);
                    475: }
                    476: 
                    477: static void
                    478: db_print_port_id(id, port, bits, n)
                    479:        int id;
1.1.1.4 ! root      480:        const ipc_port_t port;
1.1       root      481:        unsigned bits;
                    482:        int n;
                    483: {
                    484:        if (n != 0 && n % 3 == 0)
                    485:            db_printf("\n");
                    486:        db_printf("\tport%d(%s,%x)", id,
                    487:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    488:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    489: }
                    490: 
                    491: static void
                    492: db_print_port_id_long(
                    493:        int id,
1.1.1.4 ! root      494:        const ipc_port_t port,
1.1       root      495:        unsigned bits,
                    496:        int n)
                    497: {
                    498:        if (n != 0)
                    499:            db_printf("\n");
                    500:        db_printf("\tport%d(%s, port=0x%x", id,
                    501:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    502:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    503:        db_printf(", receiver_name=0x%x)", port->ip_receiver_name);
                    504: }
                    505: 
                    506: /* ARGSUSED */
                    507: void
                    508: db_show_port_id(addr, have_addr, count, modif)
                    509:        db_expr_t       addr;
                    510:        boolean_t       have_addr;
                    511:        db_expr_t       count;
1.1.1.4 ! root      512:        const char *    modif;
1.1       root      513: {
                    514:        thread_t thread;
                    515: 
                    516:        if (!have_addr) {
                    517:            thread = current_thread();
                    518:            if (thread == THREAD_NULL) {
                    519:                db_error("No thread\n");
                    520:                /*NOTREACHED*/
                    521:            }
                    522:        } else
                    523:            thread = (thread_t) addr;
                    524:        if (db_lookup_thread(thread) < 0) {
                    525:            db_printf("Bad thread address %#X\n", addr);
                    526:            db_error(0);
                    527:            /*NOTREACHED*/
                    528:        }
                    529:        if (db_option(modif, 'l'))
                    530:          {
                    531:            if (db_port_iterate(thread, db_print_port_id_long))
                    532:              db_printf("\n");
                    533:            return;
                    534:          }
                    535:        if (db_port_iterate(thread, db_print_port_id))
                    536:            db_printf("\n");
                    537: }
                    538: 
1.1.1.2   root      539: #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.