[BACK]Return to db_command.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ddb

Annotation of src/sys/ddb/db_command.c, Revision 1.71.2.3

1.71.2.3! skrll       1: /*     $NetBSD: db_command.c,v 1.71.2.1 2004/08/03 10:44:46 skrll Exp $        */
1.12      cgd         2:
1.64      simonb      3: /*
1.1       cgd         4:  * Mach Operating System
                      5:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      6:  * All Rights Reserved.
1.64      simonb      7:  *
1.1       cgd         8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
1.64      simonb     13:  *
1.30      pk         14:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
1.1       cgd        15:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     16:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.64      simonb     17:  *
1.1       cgd        18:  * Carnegie Mellon requests users of this software to return to
1.64      simonb     19:  *
1.1       cgd        20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     21:  *  School of Computer Science
                     22:  *  Carnegie Mellon University
                     23:  *  Pittsburgh PA 15213-3890
1.64      simonb     24:  *
1.1       cgd        25:  * any improvements or extensions that they make and grant Carnegie the
                     26:  * rights to redistribute these changes.
                     27:  */
1.25      mrg        28:
1.63      lukem      29: /*
                     30:  * Command dispatcher.
                     31:  */
                     32:
                     33: #include <sys/cdefs.h>
1.71.2.3! skrll      34: __KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.71.2.1 2004/08/03 10:44:46 skrll Exp $");
1.63      lukem      35:
1.27      tron       36: #include "opt_ddb.h"
1.69      briggs     37: #include "opt_kgdb.h"
1.40      jhawk      38: #include "opt_inet.h"
1.5       mycroft    39:
1.7       mycroft    40: #include <sys/param.h>
1.18      christos   41: #include <sys/systm.h>
1.23      scottr     42: #include <sys/reboot.h>
1.65      simonb     43: #include <sys/device.h>
                     44: #include <sys/malloc.h>
                     45: #include <sys/namei.h>
                     46: #include <sys/pool.h>
1.7       mycroft    47: #include <sys/proc.h>
1.36      chs        48: #include <sys/vnode.h>
1.15      gwr        49:
1.1       cgd        50: #include <machine/db_machdep.h>                /* type definitions */
                     51:
1.58      mrg        52: #if defined(_KERNEL_OPT)
1.34      sommerfe   53: #include "opt_multiprocessor.h"
                     54: #endif
                     55: #ifdef MULTIPROCESSOR
                     56: #include <machine/cpu.h>
                     57: #endif
                     58:
1.1       cgd        59: #include <ddb/db_lex.h>
                     60: #include <ddb/db_output.h>
1.10      pk         61: #include <ddb/db_command.h>
1.16      christos   62: #include <ddb/db_break.h>
                     63: #include <ddb/db_watch.h>
                     64: #include <ddb/db_run.h>
                     65: #include <ddb/db_variables.h>
                     66: #include <ddb/db_interface.h>
                     67: #include <ddb/db_sym.h>
                     68: #include <ddb/db_extern.h>
1.1       cgd        69:
1.24      mrg        70: #include <uvm/uvm_extern.h>
1.26      jonathan   71: #include <uvm/uvm_ddb.h>
1.24      mrg        72:
1.46      jhawk      73: #include "arp.h"
                     74:
1.1       cgd        75: /*
1.64      simonb     76:  * Results of command search.
                     77:  */
                     78: #define        CMD_UNIQUE      0
                     79: #define        CMD_FOUND       1
                     80: #define        CMD_NONE        2
                     81: #define        CMD_AMBIGUOUS   3
                     82: #define        CMD_HELP        4
                     83:
                     84: /*
1.1       cgd        85:  * Exported global variables
                     86:  */
                     87: boolean_t      db_cmd_loop_done;
1.17      gwr        88: label_t                *db_recover;
1.64      simonb     89: db_addr_t      db_dot;
                     90: db_addr_t      db_last_addr;
                     91: db_addr_t      db_prev;
                     92: db_addr_t      db_next;
1.1       cgd        93:
                     94: /*
                     95:  * if 'ed' style: 'dot' is set at start of last item printed,
                     96:  * and '+' points to next line.
                     97:  * Otherwise: 'dot' points to next item, '..' points to last.
                     98:  */
1.64      simonb     99: static boolean_t db_ed_style = TRUE;
                    100:
1.65      simonb    101: static void    db_buf_print_cmd(db_expr_t, int, db_expr_t, char *);
                    102: static void    db_cmd_list(const struct db_command *);
1.64      simonb    103: static int     db_cmd_search(const char *, const struct db_command *,
                    104:                    const struct db_command **);
                    105: static void    db_command(const struct db_command **,
                    106:                    const struct db_command *);
1.65      simonb    107: static void    db_event_print_cmd(db_expr_t, int, db_expr_t, char *);
                    108: static void    db_fncall(db_expr_t, int, db_expr_t, char *);
                    109: static void    db_malloc_print_cmd(db_expr_t, int, db_expr_t, char *);
1.64      simonb    110: static void    db_map_print_cmd(db_expr_t, int, db_expr_t, char *);
1.65      simonb    111: static void    db_namecache_print_cmd(db_expr_t, int, db_expr_t, char *);
1.64      simonb    112: static void    db_object_print_cmd(db_expr_t, int, db_expr_t, char *);
                    113: static void    db_page_print_cmd(db_expr_t, int, db_expr_t, char *);
                    114: static void    db_pool_print_cmd(db_expr_t, int, db_expr_t, char *);
                    115: static void    db_reboot_cmd(db_expr_t, int, db_expr_t, char *);
                    116: static void    db_sifting_cmd(db_expr_t, int, db_expr_t, char *);
                    117: static void    db_stack_trace_cmd(db_expr_t, int, db_expr_t, char *);
                    118: static void    db_sync_cmd(db_expr_t, int, db_expr_t, char *);
1.65      simonb    119: static void    db_uvmexp_print_cmd(db_expr_t, int, db_expr_t, char *);
                    120: static void    db_vnode_print_cmd(db_expr_t, int, db_expr_t, char *);
1.71.2.1  skrll     121: static void    db_mount_print_cmd(db_expr_t, int, db_expr_t, char *);
1.64      simonb    122:
                    123: /*
                    124:  * 'show' commands
                    125:  */
                    126:
                    127: static const struct db_command db_show_all_cmds[] = {
                    128:        { "callout",    db_show_callout,        0, NULL },
                    129:        { "procs",      db_show_all_procs,      0, NULL },
                    130:        { NULL,         NULL,                   0, NULL }
                    131: };
                    132:
                    133: static const struct db_command db_show_cmds[] = {
                    134:        { "all",        NULL,                   0,      db_show_all_cmds },
                    135: #if defined(INET) && (NARP > 0)
                    136:        { "arptab",     db_show_arptab,         0,      NULL },
                    137: #endif
                    138:        { "breaks",     db_listbreak_cmd,       0,      NULL },
                    139:        { "buf",        db_buf_print_cmd,       0,      NULL },
1.65      simonb    140:        { "event",      db_event_print_cmd,     0,      NULL },
                    141:        { "malloc",     db_malloc_print_cmd,    0,      NULL },
1.64      simonb    142:        { "map",        db_map_print_cmd,       0,      NULL },
1.71.2.1  skrll     143:        { "mount",      db_mount_print_cmd,     0,      NULL },
1.64      simonb    144:        { "ncache",     db_namecache_print_cmd, 0,      NULL },
                    145:        { "object",     db_object_print_cmd,    0,      NULL },
                    146:        { "page",       db_page_print_cmd,      0,      NULL },
                    147:        { "pool",       db_pool_print_cmd,      0,      NULL },
                    148:        { "registers",  db_show_regs,           0,      NULL },
1.71.2.1  skrll     149:        { "sched_qs",   db_show_sched_qs,       0,      NULL },
1.64      simonb    150:        { "uvmexp",     db_uvmexp_print_cmd,    0,      NULL },
                    151:        { "vnode",      db_vnode_print_cmd,     0,      NULL },
                    152:        { "watches",    db_listwatch_cmd,       0,      NULL },
                    153:        { NULL,         NULL,                   0,      NULL }
                    154: };
                    155:
                    156: static const struct db_command db_command_table[] = {
1.71.2.1  skrll     157:        { "b",          db_breakpoint_cmd,      0,              NULL },
1.64      simonb    158:        { "break",      db_breakpoint_cmd,      0,              NULL },
1.68      jmc       159:        { "bt",         db_stack_trace_cmd,     0,              NULL },
1.64      simonb    160:        { "c",          db_continue_cmd,        0,              NULL },
                    161:        { "call",       db_fncall,              CS_OWN,         NULL },
                    162:        { "callout",    db_show_callout,        0,              NULL },
                    163:        { "continue",   db_continue_cmd,        0,              NULL },
                    164:        { "d",          db_delete_cmd,          0,              NULL },
                    165:        { "delete",     db_delete_cmd,          0,              NULL },
                    166:        { "dmesg",      db_dmesg,               0,              NULL },
                    167:        { "dwatch",     db_deletewatch_cmd,     0,              NULL },
                    168:        { "examine",    db_examine_cmd,         CS_SET_DOT,     NULL },
                    169:        { "kill",       db_kill_proc,           CS_OWN,         NULL },
1.69      briggs    170: #ifdef KGDB
                    171:        { "kgdb",       db_kgdb_cmd,            0,              NULL },
                    172: #endif
1.64      simonb    173: #ifdef DB_MACHINE_COMMANDS
                    174:        { "machine",    NULL,                   0, db_machine_command_table },
                    175: #endif
                    176:        { "match",      db_trace_until_matching_cmd,0,          NULL },
                    177:        { "next",       db_trace_until_matching_cmd,0,          NULL },
                    178:        { "p",          db_print_cmd,           0,              NULL },
                    179:        { "print",      db_print_cmd,           0,              NULL },
                    180:        { "ps",         db_show_all_procs,      0,              NULL },
                    181:        { "reboot",     db_reboot_cmd,          CS_OWN,         NULL },
                    182:        { "s",          db_single_step_cmd,     0,              NULL },
                    183:        { "search",     db_search_cmd,          CS_OWN|CS_SET_DOT, NULL },
                    184:        { "set",        db_set_cmd,             CS_OWN,         NULL },
                    185:        { "show",       NULL,                   0,              db_show_cmds },
                    186:        { "sifting",    db_sifting_cmd,         CS_OWN,         NULL },
                    187:        { "step",       db_single_step_cmd,     0,              NULL },
                    188:        { "sync",       db_sync_cmd,            CS_OWN,         NULL },
                    189:        { "trace",      db_stack_trace_cmd,     0,              NULL },
                    190:        { "until",      db_trace_until_call_cmd,0,              NULL },
                    191:        { "w",          db_write_cmd,           CS_MORE|CS_SET_DOT, NULL },
                    192:        { "watch",      db_watchpoint_cmd,      CS_MORE,        NULL },
                    193:        { "write",      db_write_cmd,           CS_MORE|CS_SET_DOT, NULL },
                    194:        { "x",          db_examine_cmd,         CS_SET_DOT,     NULL },
                    195:        { NULL,         NULL,                   0,              NULL }
                    196: };
                    197:
                    198: static const struct db_command *db_last_command = NULL;
1.1       cgd       199:
                    200: /*
                    201:  * Utility routine - discard tokens through end-of-line.
                    202:  */
                    203: void
1.64      simonb    204: db_skip_to_eol(void)
1.1       cgd       205: {
1.64      simonb    206:        int t;
                    207:
1.1       cgd       208:        do {
1.64      simonb    209:                t = db_read_token();
1.1       cgd       210:        } while (t != tEOL);
                    211: }
                    212:
1.64      simonb    213: void
                    214: db_error(s)
                    215:        char *s;
                    216: {
                    217:
                    218:        if (s)
                    219:                db_printf("%s", s);
                    220:        db_flush_lex();
                    221:        longjmp(db_recover);
                    222: }
                    223:
                    224: void
                    225: db_command_loop(void)
                    226: {
                    227:        label_t db_jmpbuf;
                    228:        label_t *savejmp;
                    229:
                    230:        /*
                    231:         * Initialize 'prev' and 'next' to dot.
                    232:         */
                    233:        db_prev = db_dot;
                    234:        db_next = db_dot;
                    235:
                    236:        db_cmd_loop_done = 0;
                    237:
                    238:        savejmp = db_recover;
                    239:        db_recover = &db_jmpbuf;
                    240:        (void) setjmp(&db_jmpbuf);
                    241:
                    242:        while (!db_cmd_loop_done) {
                    243:                if (db_print_position() != 0)
                    244:                        db_printf("\n");
                    245:                db_output_line = 0;
                    246:
                    247:
                    248: #ifdef MULTIPROCESSOR
                    249:                db_printf("db{%ld}> ", (long)cpu_number());
                    250: #else
                    251:                db_printf("db> ");
                    252: #endif
                    253:                (void) db_read_line();
                    254:
                    255:                db_command(&db_last_command, db_command_table);
                    256:        }
                    257:
                    258:        db_recover = savejmp;
                    259: }
1.1       cgd       260:
                    261: /*
                    262:  * Search for command prefix.
                    263:  */
1.64      simonb    264: static int
                    265: db_cmd_search(const char *name, const struct db_command *table,
                    266:     const struct db_command **cmdp)
1.1       cgd       267: {
1.53      jdolecek  268:        const struct db_command *cmd;
1.10      pk        269:        int                     result = CMD_NONE;
1.1       cgd       270:
                    271:        for (cmd = table; cmd->name != 0; cmd++) {
1.64      simonb    272:                const char *lp;
                    273:                const char *rp;
                    274:                int  c;
                    275:
                    276:                lp = name;
                    277:                rp = cmd->name;
                    278:                while ((c = *lp) == *rp) {
                    279:                        if (c == 0) {
                    280:                                /* complete match */
                    281:                                *cmdp = cmd;
                    282:                                return (CMD_UNIQUE);
                    283:                        }
                    284:                        lp++;
                    285:                        rp++;
                    286:                }
1.1       cgd       287:                if (c == 0) {
1.64      simonb    288:                        /* end of name, not end of command -
                    289:                           partial match */
                    290:                        if (result == CMD_FOUND) {
                    291:                                result = CMD_AMBIGUOUS;
                    292:                                /* but keep looking for a full match -
                    293:                                   this lets us match single letters */
                    294:                        } else {
                    295:                                *cmdp = cmd;
                    296:                                result = CMD_FOUND;
                    297:                        }
1.1       cgd       298:                }
                    299:        }
                    300:        if (result == CMD_NONE) {
1.64      simonb    301:                /* check for 'help' */
1.1       cgd       302:                if (name[0] == 'h' && name[1] == 'e'
                    303:                    && name[2] == 'l' && name[3] == 'p')
                    304:                        result = CMD_HELP;
                    305:        }
                    306:        return (result);
                    307: }
                    308:
1.64      simonb    309: static void
                    310: db_cmd_list(const struct db_command *table)
1.1       cgd       311: {
1.67      simonb    312:        int      i, j, w, columns, lines, width=0, numcmds;
1.53      jdolecek  313:        const char      *p;
1.1       cgd       314:
1.32      lukem     315:        for (numcmds = 0; table[numcmds].name != NULL; numcmds++) {
                    316:                w = strlen(table[numcmds].name);
                    317:                if (w > width)
                    318:                        width = w;
                    319:        }
                    320:        width = DB_NEXT_TAB(width);
                    321:
                    322:        columns = db_max_width / width;
                    323:        if (columns == 0)
                    324:                columns = 1;
                    325:        lines = (numcmds + columns - 1) / columns;
                    326:        for (i = 0; i < lines; i++) {
                    327:                for (j = 0; j < columns; j++) {
                    328:                        p = table[j * lines + i].name;
                    329:                        if (p)
                    330:                                db_printf("%s", p);
                    331:                        if (j * lines + i + lines >= numcmds) {
                    332:                                db_putchar('\n');
                    333:                                break;
                    334:                        }
                    335:                        w = strlen(p);
                    336:                        while (w < width) {
                    337:                                w = DB_NEXT_TAB(w);
                    338:                                db_putchar('\t');
                    339:                        }
                    340:                }
1.1       cgd       341:        }
                    342: }
                    343:
1.64      simonb    344: static void
                    345: db_command(const struct db_command **last_cmdp,
                    346:     const struct db_command *cmd_table)
1.1       cgd       347: {
1.53      jdolecek  348:        const struct db_command *cmd;
1.1       cgd       349:        int             t;
                    350:        char            modif[TOK_STRING_SIZE];
                    351:        db_expr_t       addr, count;
1.16      christos  352:        boolean_t       have_addr = FALSE;
1.1       cgd       353:        int             result;
                    354:
1.64      simonb    355:        static db_expr_t last_count = 0;
1.38      jhawk     356:
1.1       cgd       357:        t = db_read_token();
1.38      jhawk     358:        if ((t == tEOL) || (t == tCOMMA)) {
1.1       cgd       359:                /*
1.64      simonb    360:                 * An empty line repeats last command, at 'next'.
                    361:                 * Only a count repeats the last command with the new count.
                    362:                 */
                    363:                cmd = *last_cmdp;
                    364:                addr = (db_expr_t)db_next;
                    365:                if (t == tCOMMA) {
                    366:                        if (!db_expression(&count)) {
                    367:                                db_printf("Count missing\n");
                    368:                                db_flush_lex();
                    369:                                return;
                    370:                        }
                    371:                } else
                    372:                        count = last_count;
                    373:                have_addr = FALSE;
                    374:                modif[0] = '\0';
                    375:                db_skip_to_eol();
                    376:        } else if (t == tEXCL) {
                    377:                db_fncall(0, 0, 0, NULL);
                    378:                return;
                    379:        } else if (t != tIDENT) {
                    380:                db_printf("?\n");
                    381:                db_flush_lex();
                    382:                return;
                    383:        } else {
                    384:                /*
                    385:                 * Search for command
1.1       cgd       386:                 */
1.64      simonb    387:                while (cmd_table) {
                    388:                        result = db_cmd_search(db_tok_string, cmd_table, &cmd);
                    389:                        switch (result) {
                    390:                        case CMD_NONE:
                    391:                                db_printf("No such command\n");
                    392:                                db_flush_lex();
                    393:                                return;
                    394:                        case CMD_AMBIGUOUS:
                    395:                                db_printf("Ambiguous\n");
                    396:                                db_flush_lex();
                    397:                                return;
                    398:                        case CMD_HELP:
                    399:                                db_cmd_list(cmd_table);
                    400:                                db_flush_lex();
                    401:                                return;
                    402:                        default:
                    403:                                break;
                    404:                        }
                    405:                        if ((cmd_table = cmd->more) != 0) {
                    406:                                t = db_read_token();
                    407:                                if (t != tIDENT) {
                    408:                                        db_cmd_list(cmd_table);
                    409:                                        db_flush_lex();
                    410:                                        return;
                    411:                                }
                    412:                        }
1.1       cgd       413:                }
                    414:
1.64      simonb    415:                if ((cmd->flag & CS_OWN) == 0) {
                    416:                        /*
                    417:                         * Standard syntax:
                    418:                         * command [/modifier] [addr] [,count]
                    419:                         */
                    420:                        t = db_read_token();
                    421:                        if (t == tSLASH) {
                    422:                                t = db_read_token();
                    423:                                if (t != tIDENT) {
                    424:                                        db_printf("Bad modifier\n");
                    425:                                        db_flush_lex();
                    426:                                        return;
                    427:                                }
1.71      itojun    428:                                strlcpy(modif, db_tok_string, sizeof(modif));
1.64      simonb    429:                        } else {
                    430:                                db_unread_token(t);
                    431:                                modif[0] = '\0';
                    432:                        }
                    433:
                    434:                        if (db_expression(&addr)) {
                    435:                                db_dot = (db_addr_t) addr;
                    436:                                db_last_addr = db_dot;
                    437:                                have_addr = TRUE;
                    438:                        } else {
                    439:                                addr = (db_expr_t) db_dot;
                    440:                                have_addr = FALSE;
                    441:                        }
                    442:                        t = db_read_token();
                    443:                        if (t == tCOMMA) {
                    444:                                if (!db_expression(&count)) {
                    445:                                        db_printf("Count missing\n");
                    446:                                        db_flush_lex();
                    447:                                        return;
                    448:                                }
                    449:                        } else {
                    450:                                db_unread_token(t);
                    451:                                count = -1;
                    452:                        }
                    453:                        if ((cmd->flag & CS_MORE) == 0) {
                    454:                                db_skip_to_eol();
                    455:                        }
1.1       cgd       456:                }
                    457:        }
                    458:        *last_cmdp = cmd;
1.38      jhawk     459:        last_count = count;
1.1       cgd       460:        if (cmd != 0) {
                    461:                /*
1.64      simonb    462:                 * Execute the command.
1.1       cgd       463:                 */
1.64      simonb    464:                (*cmd->fcn)(addr, have_addr, count, modif);
                    465:
                    466:                if (cmd->flag & CS_SET_DOT) {
                    467:                        /*
                    468:                         * If command changes dot, set dot to
                    469:                         * previous address displayed (if 'ed' style).
                    470:                         */
                    471:                        if (db_ed_style)
                    472:                                db_dot = db_prev;
                    473:                        else
                    474:                                db_dot = db_next;
                    475:                } else {
                    476:                        /*
                    477:                         * If command does not change dot,
                    478:                         * set 'next' location to be the same.
                    479:                         */
                    480:                        db_next = db_dot;
1.1       cgd       481:                }
                    482:        }
                    483: }
                    484:
1.4       brezak    485: /*ARGSUSED*/
1.64      simonb    486: static void
                    487: db_map_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    488: {
                    489:        boolean_t full = FALSE;
                    490:
                    491:        if (modif[0] == 'f')
                    492:                full = TRUE;
1.60      matt      493:
                    494:        if (have_addr == FALSE)
1.66      scw       495:                addr = (db_expr_t)(intptr_t) kernel_map;
1.4       brezak    496:
1.66      scw       497:        uvm_map_printit((struct vm_map *)(intptr_t) addr, full, db_printf);
1.4       brezak    498: }
                    499:
                    500: /*ARGSUSED*/
1.64      simonb    501: static void
                    502: db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.62      thorpej   503: {
1.64      simonb    504:
1.62      thorpej   505: #ifdef MALLOC_DEBUG
                    506:        if (!have_addr)
                    507:                addr = 0;
                    508:
                    509:        debug_malloc_printit(db_printf, (vaddr_t) addr);
                    510: #else
                    511:        db_printf("The kernel is not built with the MALLOC_DEBUG option.\n");
                    512: #endif /* MALLOC_DEBUG */
                    513: }
                    514:
                    515: /*ARGSUSED*/
1.64      simonb    516: static void
                    517: db_object_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    518: {
                    519:        boolean_t full = FALSE;
                    520:
                    521:        if (modif[0] == 'f')
                    522:                full = TRUE;
1.4       brezak    523:
1.66      scw       524:        uvm_object_printit((struct uvm_object *)(intptr_t) addr, full,
                    525:            db_printf);
1.24      mrg       526: }
                    527:
                    528: /*ARGSUSED*/
1.64      simonb    529: static void
                    530: db_page_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    531: {
                    532:        boolean_t full = FALSE;
                    533:
                    534:        if (modif[0] == 'f')
                    535:                full = TRUE;
1.24      mrg       536:
1.66      scw       537:        uvm_page_printit((struct vm_page *)(intptr_t) addr, full, db_printf);
1.36      chs       538: }
                    539:
                    540: /*ARGSUSED*/
1.64      simonb    541: static void
                    542: db_buf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.36      chs       543: {
                    544:        boolean_t full = FALSE;
1.64      simonb    545:
1.36      chs       546:        if (modif[0] == 'f')
                    547:                full = TRUE;
                    548:
1.66      scw       549:        vfs_buf_print((struct buf *)(intptr_t) addr, full, db_printf);
1.65      simonb    550: }
                    551:
                    552: /*ARGSUSED*/
                    553: static void
                    554: db_event_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    555: {
                    556:        boolean_t full = FALSE;
                    557:
                    558:        if (modif[0] == 'f')
                    559:                full = TRUE;
                    560:
                    561:        event_print(full, db_printf);
1.36      chs       562: }
                    563:
                    564: /*ARGSUSED*/
1.64      simonb    565: static void
                    566: db_vnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.36      chs       567: {
                    568:        boolean_t full = FALSE;
1.64      simonb    569:
1.36      chs       570:        if (modif[0] == 'f')
                    571:                full = TRUE;
                    572:
1.66      scw       573:        vfs_vnode_print((struct vnode *)(intptr_t) addr, full, db_printf);
1.4       brezak    574: }
                    575:
1.71.2.1  skrll     576: static void
                    577: db_mount_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    578: {
                    579:        boolean_t full = FALSE;
                    580:
                    581:        if (modif[0] == 'f')
                    582:                full = TRUE;
                    583:
                    584:        vfs_mount_print((struct mount *)(intptr_t) addr, full, db_printf);
                    585: }
                    586:
1.31      thorpej   587: /*ARGSUSED*/
1.64      simonb    588: static void
                    589: db_pool_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.31      thorpej   590: {
1.64      simonb    591:
1.66      scw       592:        pool_printit((struct pool *)(intptr_t) addr, modif, db_printf);
1.51      chs       593: }
1.31      thorpej   594:
1.51      chs       595: /*ARGSUSED*/
1.64      simonb    596: static void
                    597: db_namecache_print_cmd(db_expr_t addr, int have_addr, db_expr_t count,
                    598:     char *modif)
1.51      chs       599: {
1.64      simonb    600:
1.66      scw       601:        namecache_print((struct vnode *)(intptr_t) addr, db_printf);
1.51      chs       602: }
                    603:
                    604: /*ARGSUSED*/
1.64      simonb    605: static void
                    606: db_uvmexp_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.51      chs       607: {
1.64      simonb    608:
1.51      chs       609:        uvmexp_print(db_printf);
1.31      thorpej   610: }
                    611:
1.1       cgd       612: /*
                    613:  * Call random function:
                    614:  * !expr(arg,arg,arg)
                    615:  */
1.16      christos  616: /*ARGSUSED*/
1.64      simonb    617: static void
                    618: db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.1       cgd       619: {
                    620:        db_expr_t       fn_addr;
                    621: #define        MAXARGS         11
                    622:        db_expr_t       args[MAXARGS];
                    623:        int             nargs = 0;
                    624:        db_expr_t       retval;
1.64      simonb    625:        db_expr_t       (*func)(db_expr_t, ...);
1.1       cgd       626:        int             t;
                    627:
                    628:        if (!db_expression(&fn_addr)) {
1.64      simonb    629:                db_printf("Bad function\n");
                    630:                db_flush_lex();
                    631:                return;
1.1       cgd       632:        }
1.66      scw       633:        func = (db_expr_t (*)(db_expr_t, ...))(intptr_t) fn_addr;
1.1       cgd       634:
                    635:        t = db_read_token();
                    636:        if (t == tLPAREN) {
1.64      simonb    637:                if (db_expression(&args[0])) {
                    638:                        nargs++;
                    639:                        while ((t = db_read_token()) == tCOMMA) {
                    640:                                if (nargs == MAXARGS) {
                    641:                                        db_printf("Too many arguments\n");
                    642:                                        db_flush_lex();
                    643:                                        return;
                    644:                                }
                    645:                                if (!db_expression(&args[nargs])) {
                    646:                                        db_printf("Argument missing\n");
                    647:                                        db_flush_lex();
                    648:                                        return;
                    649:                                }
                    650:                                nargs++;
                    651:                        }
                    652:                        db_unread_token(t);
                    653:                }
                    654:                if (db_read_token() != tRPAREN) {
                    655:                        db_printf("?\n");
1.1       cgd       656:                        db_flush_lex();
                    657:                        return;
                    658:                }
                    659:        }
                    660:        db_skip_to_eol();
                    661:
                    662:        while (nargs < MAXARGS) {
1.64      simonb    663:                args[nargs++] = 0;
1.1       cgd       664:        }
                    665:
                    666:        retval = (*func)(args[0], args[1], args[2], args[3], args[4],
1.20      christos  667:                         args[5], args[6], args[7], args[8], args[9]);
1.45      jhawk     668:        db_printf("%s\n", db_num_to_str(retval));
1.23      scottr    669: }
                    670:
1.64      simonb    671: static void
                    672: db_reboot_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.23      scottr    673: {
                    674:        db_expr_t bootflags;
                    675:
                    676:        /* Flags, default to RB_AUTOBOOT */
                    677:        if (!db_expression(&bootflags))
                    678:                bootflags = (db_expr_t)RB_AUTOBOOT;
                    679:        if (db_read_token() != tEOL) {
1.64      simonb    680:                db_error("?\n");
                    681:                /*NOTREACHED*/
1.23      scottr    682:        }
1.47      sommerfe  683:        /*
                    684:         * We are leaving DDB, never to return upward.
                    685:         * Clear db_recover so that we can debug faults in functions
                    686:         * called from cpu_reboot.
                    687:         */
                    688:        db_recover = 0;
1.23      scottr    689:        cpu_reboot((int)bootflags, NULL);
1.41      jhawk     690: }
                    691:
1.64      simonb    692: static void
                    693: db_sifting_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.41      jhawk     694: {
                    695:        int     mode, t;
                    696:
                    697:        t = db_read_token();
                    698:        if (t == tSLASH) {
                    699:                t = db_read_token();
                    700:                if (t != tIDENT) {
                    701:                        bad_modifier:
                    702:                        db_printf("Bad modifier\n");
                    703:                        db_flush_lex();
                    704:                        return;
                    705:                }
                    706:                if (!strcmp(db_tok_string, "F"))
                    707:                        mode = 'F';
                    708:                else
                    709:                        goto bad_modifier;
                    710:                t = db_read_token();
                    711:        } else
                    712:                mode = 0;
                    713:
1.51      chs       714:        if (t == tIDENT)
1.41      jhawk     715:                db_sifting(db_tok_string, mode);
                    716:        else {
                    717:                db_printf("Bad argument (non-string)\n");
                    718:                db_flush_lex();
                    719:        }
1.43      jhawk     720: }
                    721:
1.64      simonb    722: static void
                    723: db_stack_trace_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.43      jhawk     724: {
1.70      atatat    725:        register char *cp = modif;
                    726:        register char c;
                    727:        void (*pr)(const char *, ...);
                    728:
                    729:        pr = db_printf;
                    730:        while ((c = *cp++) != 0)
                    731:                if (c == 'l')
                    732:                        pr = printf;
1.64      simonb    733:
1.43      jhawk     734:        if (count == -1)
                    735:                count = 65535;
                    736:
1.70      atatat    737:        db_stack_trace_print(addr, have_addr, count, modif, pr);
1.32      lukem     738: }
                    739:
1.64      simonb    740: static void
                    741: db_sync_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
1.32      lukem     742: {
1.64      simonb    743:
1.47      sommerfe  744:        /*
                    745:         * We are leaving DDB, never to return upward.
                    746:         * Clear db_recover so that we can debug faults in functions
                    747:         * called from cpu_reboot.
                    748:         */
                    749:        db_recover = 0;
1.32      lukem     750:        cpu_reboot(RB_DUMP, NULL);
1.1       cgd       751: }

CVSweb <webmaster@jp.NetBSD.org>