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

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