The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_command.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: db_command.c,v 1.75.2.1 2004/04/29 04:08:15 jmc Exp $  */
    2 
    3 /*
    4  * Mach Operating System
    5  * Copyright (c) 1991,1990 Carnegie Mellon University
    6  * All Rights Reserved.
    7  *
    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.
   13  *
   14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  *
   18  * Carnegie Mellon requests users of this software to return to
   19  *
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  *
   25  * any improvements or extensions that they make and grant Carnegie the
   26  * rights to redistribute these changes.
   27  */
   28 
   29 /*
   30  * Command dispatcher.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.75.2.1 2004/04/29 04:08:15 jmc Exp $");
   35 
   36 #include "opt_ddb.h"
   37 #include "opt_kgdb.h"
   38 #include "opt_inet.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/reboot.h>
   43 #include <sys/device.h>
   44 #include <sys/malloc.h>
   45 #include <sys/namei.h>
   46 #include <sys/pool.h>
   47 #include <sys/proc.h>
   48 #include <sys/vnode.h>
   49 
   50 #include <machine/db_machdep.h>         /* type definitions */
   51 
   52 #if defined(_KERNEL_OPT)
   53 #include "opt_multiprocessor.h"
   54 #endif
   55 #ifdef MULTIPROCESSOR
   56 #include <machine/cpu.h>
   57 #endif
   58 
   59 #include <ddb/db_lex.h>
   60 #include <ddb/db_output.h>
   61 #include <ddb/db_command.h>
   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>
   69 
   70 #include <uvm/uvm_extern.h>
   71 #include <uvm/uvm_ddb.h>
   72 
   73 #include "arp.h"
   74 
   75 /*
   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 /*
   85  * Exported global variables
   86  */
   87 boolean_t       db_cmd_loop_done;
   88 label_t         *db_recover;
   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;
   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  */
   99 static boolean_t db_ed_style = TRUE;
  100 
  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 *);
  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 *);
  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 *);
  110 static void     db_map_print_cmd(db_expr_t, int, db_expr_t, char *);
  111 static void     db_namecache_print_cmd(db_expr_t, int, db_expr_t, char *);
  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 *);
  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 *);
  121 static void     db_mount_print_cmd(db_expr_t, int, db_expr_t, char *);
  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 },
  140         { "event",      db_event_print_cmd,     0,      NULL },
  141         { "malloc",     db_malloc_print_cmd,    0,      NULL },
  142         { "map",        db_map_print_cmd,       0,      NULL },
  143         { "mount",      db_mount_print_cmd,     0,      NULL },
  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 },
  149         { "sched_qs",   db_show_sched_qs,       0,      NULL },
  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[] = {
  157         { "b",          db_breakpoint_cmd,      0,              NULL },
  158         { "break",      db_breakpoint_cmd,      0,              NULL },
  159         { "bt",         db_stack_trace_cmd,     0,              NULL },
  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 },
  170 #ifdef KGDB
  171         { "kgdb",       db_kgdb_cmd,            0,              NULL },
  172 #endif
  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;
  199 
  200 /*
  201  * Utility routine - discard tokens through end-of-line.
  202  */
  203 void
  204 db_skip_to_eol(void)
  205 {
  206         int t;
  207 
  208         do {
  209                 t = db_read_token();
  210         } while (t != tEOL);
  211 }
  212 
  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 }
  260 
  261 /*
  262  * Search for command prefix.
  263  */
  264 static int
  265 db_cmd_search(const char *name, const struct db_command *table,
  266     const struct db_command **cmdp)
  267 {
  268         const struct db_command *cmd;
  269         int                     result = CMD_NONE;
  270 
  271         for (cmd = table; cmd->name != 0; cmd++) {
  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                 }
  287                 if (c == 0) {
  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                         }
  298                 }
  299         }
  300         if (result == CMD_NONE) {
  301                 /* check for 'help' */
  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 
  309 static void
  310 db_cmd_list(const struct db_command *table)
  311 {
  312         int      i, j, w, columns, lines, width=0, numcmds;
  313         const char      *p;
  314 
  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                 }
  341         }
  342 }
  343 
  344 static void
  345 db_command(const struct db_command **last_cmdp,
  346     const struct db_command *cmd_table)
  347 {
  348         const struct db_command *cmd;
  349         int             t;
  350         char            modif[TOK_STRING_SIZE];
  351         db_expr_t       addr, count;
  352         boolean_t       have_addr = FALSE;
  353         int             result;
  354 
  355         static db_expr_t last_count = 0;
  356 
  357         t = db_read_token();
  358         if ((t == tEOL) || (t == tCOMMA)) {
  359                 /*
  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
  386                  */
  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                         }
  413                 }
  414 
  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                                 }
  428                                 strlcpy(modif, db_tok_string, sizeof(modif));
  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                         }
  456                 }
  457         }
  458         *last_cmdp = cmd;
  459         last_count = count;
  460         if (cmd != 0) {
  461                 /*
  462                  * Execute the command.
  463                  */
  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;
  481                 }
  482         }
  483 }
  484 
  485 /*ARGSUSED*/
  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;
  493 
  494         if (have_addr == FALSE)
  495                 addr = (db_expr_t)(intptr_t) kernel_map;
  496 
  497         uvm_map_printit((struct vm_map *)(intptr_t) addr, full, db_printf);
  498 }
  499 
  500 /*ARGSUSED*/
  501 static void
  502 db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  503 {
  504 
  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*/
  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;
  523 
  524         uvm_object_printit((struct uvm_object *)(intptr_t) addr, full,
  525             db_printf);
  526 }
  527 
  528 /*ARGSUSED*/
  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;
  536 
  537         uvm_page_printit((struct vm_page *)(intptr_t) addr, full, db_printf);
  538 }
  539 
  540 /*ARGSUSED*/
  541 static void
  542 db_buf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  543 {
  544         boolean_t full = FALSE;
  545 
  546         if (modif[0] == 'f')
  547                 full = TRUE;
  548 
  549         vfs_buf_print((struct buf *)(intptr_t) addr, full, db_printf);
  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);
  562 }
  563 
  564 /*ARGSUSED*/
  565 static void
  566 db_vnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  567 {
  568         boolean_t full = FALSE;
  569 
  570         if (modif[0] == 'f')
  571                 full = TRUE;
  572 
  573         vfs_vnode_print((struct vnode *)(intptr_t) addr, full, db_printf);
  574 }
  575 
  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 
  587 /*ARGSUSED*/
  588 static void
  589 db_pool_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  590 {
  591 
  592         pool_printit((struct pool *)(intptr_t) addr, modif, db_printf);
  593 }
  594 
  595 /*ARGSUSED*/
  596 static void
  597 db_namecache_print_cmd(db_expr_t addr, int have_addr, db_expr_t count,
  598     char *modif)
  599 {
  600 
  601         namecache_print((struct vnode *)(intptr_t) addr, db_printf);
  602 }
  603 
  604 /*ARGSUSED*/
  605 static void
  606 db_uvmexp_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  607 {
  608 
  609         uvmexp_print(db_printf);
  610 }
  611 
  612 /*
  613  * Call random function:
  614  * !expr(arg,arg,arg)
  615  */
  616 /*ARGSUSED*/
  617 static void
  618 db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  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;
  625         db_expr_t       (*func)(db_expr_t, ...);
  626         int             t;
  627 
  628         if (!db_expression(&fn_addr)) {
  629                 db_printf("Bad function\n");
  630                 db_flush_lex();
  631                 return;
  632         }
  633         func = (db_expr_t (*)(db_expr_t, ...))(intptr_t) fn_addr;
  634 
  635         t = db_read_token();
  636         if (t == tLPAREN) {
  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");
  656                         db_flush_lex();
  657                         return;
  658                 }
  659         }
  660         db_skip_to_eol();
  661 
  662         while (nargs < MAXARGS) {
  663                 args[nargs++] = 0;
  664         }
  665 
  666         retval = (*func)(args[0], args[1], args[2], args[3], args[4],
  667                          args[5], args[6], args[7], args[8], args[9]);
  668         db_printf("%s\n", db_num_to_str(retval));
  669 }
  670 
  671 static void
  672 db_reboot_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  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) {
  680                 db_error("?\n");
  681                 /*NOTREACHED*/
  682         }
  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;
  689         cpu_reboot((int)bootflags, NULL);
  690 }
  691 
  692 static void
  693 db_sifting_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  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 
  714         if (t == tIDENT)
  715                 db_sifting(db_tok_string, mode);
  716         else {
  717                 db_printf("Bad argument (non-string)\n");
  718                 db_flush_lex();
  719         }
  720 }
  721 
  722 static void
  723 db_stack_trace_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  724 {
  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;
  733 
  734         if (count == -1)
  735                 count = 65535;
  736 
  737         db_stack_trace_print(addr, have_addr, count, modif, pr);
  738 }
  739 
  740 static void
  741 db_sync_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  742 {
  743 
  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;
  750         cpu_reboot(RB_DUMP, NULL);
  751 }

Cache object: 0d221f3cf7497c54433b19a39847de30


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.