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

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 n = 0;
1.1.1.5 ! root      443:        struct rdxtree_iter iter;
        !           444:        rdxtree_for_each(&thread->task->itk_space->is_map, &iter, entry) {
1.1       root      445:            if (entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
1.1.1.5 ! root      446:                (*func)(entry->ie_name, (ipc_port_t) entry->ie_object,
1.1       root      447:                        entry->ie_bits, n++);
                    448:        }
                    449:        return(n);
                    450: }
                    451: 
                    452: ipc_port_t
1.1.1.4   root      453: db_lookup_port(
                    454:        thread_t        thread,
                    455:        int             id)
1.1       root      456: {
1.1.1.4   root      457:        ipc_entry_t entry;
1.1       root      458: 
                    459:        if (thread == THREAD_NULL)
                    460:            return(0);
1.1.1.5 ! root      461:        if (id < 0)
1.1       root      462:            return(0);
1.1.1.5 ! root      463:        entry = ipc_entry_lookup(thread->task->itk_space, (mach_port_t) id);
        !           464:        if (entry && entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS)
1.1       root      465:            return((ipc_port_t)entry->ie_object);
                    466:        return(0);
                    467: }
                    468: 
                    469: static void
                    470: db_print_port_id(id, port, bits, n)
                    471:        int id;
1.1.1.4   root      472:        const ipc_port_t port;
1.1       root      473:        unsigned bits;
                    474:        int n;
                    475: {
                    476:        if (n != 0 && n % 3 == 0)
                    477:            db_printf("\n");
                    478:        db_printf("\tport%d(%s,%x)", id,
                    479:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    480:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    481: }
                    482: 
                    483: static void
                    484: db_print_port_id_long(
                    485:        int id,
1.1.1.4   root      486:        const ipc_port_t port,
1.1       root      487:        unsigned bits,
                    488:        int n)
                    489: {
                    490:        if (n != 0)
                    491:            db_printf("\n");
                    492:        db_printf("\tport%d(%s, port=0x%x", id,
                    493:                (bits & MACH_PORT_TYPE_RECEIVE)? "r":
                    494:                (bits & MACH_PORT_TYPE_SEND)? "s": "S", port);
                    495:        db_printf(", receiver_name=0x%x)", port->ip_receiver_name);
                    496: }
                    497: 
                    498: /* ARGSUSED */
                    499: void
                    500: db_show_port_id(addr, have_addr, count, modif)
                    501:        db_expr_t       addr;
                    502:        boolean_t       have_addr;
                    503:        db_expr_t       count;
1.1.1.4   root      504:        const char *    modif;
1.1       root      505: {
                    506:        thread_t thread;
                    507: 
                    508:        if (!have_addr) {
                    509:            thread = current_thread();
                    510:            if (thread == THREAD_NULL) {
                    511:                db_error("No thread\n");
                    512:                /*NOTREACHED*/
                    513:            }
                    514:        } else
                    515:            thread = (thread_t) addr;
                    516:        if (db_lookup_thread(thread) < 0) {
                    517:            db_printf("Bad thread address %#X\n", addr);
                    518:            db_error(0);
                    519:            /*NOTREACHED*/
                    520:        }
                    521:        if (db_option(modif, 'l'))
                    522:          {
                    523:            if (db_port_iterate(thread, db_print_port_id_long))
                    524:              db_printf("\n");
                    525:            return;
                    526:          }
                    527:        if (db_port_iterate(thread, db_print_port_id))
                    528:            db_printf("\n");
                    529: }
                    530: 
1.1.1.2   root      531: #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.