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

1.1     ! root        1: /*
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             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.
        !            11:  * 
        !            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.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            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)
        !            93:                    db_printf("%s%d%*s", regp->name, i, 
        !            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);
        !            98:                db_find_xtrn_task_sym_and_offset((db_addr_t)value, &name, 
        !            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 */
        !           119: #endif DB_TASK_NAME
        !           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;
        !           131:        
        !           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(" ");
        !           183:                db_printf("%3d%c(%0*X,%s)", thread_id, 
        !           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("(");
        !           203:                    db_task_printsym((db_addr_t)thread->swap_func, 
        !           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(" ");
        !           212:                db_task_printsym((db_addr_t)thread->wait_event, 
        !           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) {
        !           230:                db_printf(" ID: TASK     MAP      THD SUS PR %s", 
        !           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: 
        !           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.