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 /*      $OpenBSD: db_command.c,v 1.97 2022/11/05 19:29:45 cheloha Exp $ */
    2 /*      $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
    3 
    4 /*
    5  * Mach Operating System
    6  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    7  * All Rights Reserved.
    8  *
    9  * Permission to use, copy, modify and distribute this software and its
   10  * documentation is hereby granted, provided that both the copyright
   11  * notice and this permission notice appear in all copies of the
   12  * software, derivative works or modified versions, and any portions
   13  * thereof, and that both notices appear in supporting documentation.
   14  *
   15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   17  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   18  *
   19  * Carnegie Mellon requests users of this software to return to
   20  *
   21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   22  *  School of Computer Science
   23  *  Carnegie Mellon University
   24  *  Pittsburgh PA 15213-3890
   25  *
   26  * any improvements or extensions that they make and grant Carnegie Mellon
   27  * the rights to redistribute these changes.
   28  */
   29 
   30 /*
   31  * Command dispatcher.
   32  */
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/proc.h>
   36 #include <sys/reboot.h>
   37 #include <sys/extent.h>
   38 #include <sys/pool.h>
   39 #include <sys/msgbuf.h>
   40 #include <sys/malloc.h>
   41 #include <sys/mount.h>
   42 
   43 #include <uvm/uvm_extern.h>
   44 #include <machine/db_machdep.h>         /* type definitions */
   45 
   46 #include <ddb/db_access.h>
   47 #include <ddb/db_lex.h>
   48 #include <ddb/db_output.h>
   49 #include <ddb/db_command.h>
   50 #include <ddb/db_break.h>
   51 #include <ddb/db_watch.h>
   52 #include <ddb/db_run.h>
   53 #include <ddb/db_sym.h>
   54 #include <ddb/db_var.h>
   55 #include <ddb/db_variables.h>
   56 #include <ddb/db_interface.h>
   57 #include <ddb/db_extern.h>
   58 
   59 #include <netinet/ip_ipsp.h>
   60 #include <uvm/uvm_ddb.h>
   61 
   62 /*
   63  * Exported global variables
   64  */
   65 int             db_cmd_loop_done;
   66 label_t         *db_recover;
   67 
   68 /*
   69  * if 'ed' style: 'dot' is set at start of last item printed,
   70  * and '+' points to next line.
   71  * Otherwise: 'dot' points to next item, '..' points to last.
   72  */
   73 int             db_ed_style = 1;
   74 
   75 vaddr_t         db_dot;         /* current location */
   76 vaddr_t         db_last_addr;   /* last explicit address typed */
   77 vaddr_t         db_prev;        /* last address examined
   78                                    or written */
   79 vaddr_t         db_next;        /* next address to be examined
   80                                    or written */
   81 
   82 int     db_cmd_search(char *, const struct db_command *,
   83             const struct db_command **);
   84 void    db_cmd_list(const struct db_command *);
   85 void    db_ctf_pprint_cmd(db_expr_t, int, db_expr_t,char *);
   86 void    db_map_print_cmd(db_expr_t, int, db_expr_t, char *);
   87 void    db_buf_print_cmd(db_expr_t, int, db_expr_t, char *);
   88 void    db_malloc_print_cmd(db_expr_t, int, db_expr_t, char *);
   89 void    db_mbuf_print_cmd(db_expr_t, int, db_expr_t, char *);
   90 void    db_mount_print_cmd(db_expr_t, int, db_expr_t, char *);
   91 void    db_show_all_mounts(db_expr_t, int, db_expr_t, char *);
   92 void    db_show_all_vnodes(db_expr_t, int, db_expr_t, char *);
   93 void    db_show_all_bufs(db_expr_t, int, db_expr_t, char *);
   94 void    db_show_all_tdbs(db_expr_t, int, db_expr_t, char *);
   95 void    db_object_print_cmd(db_expr_t, int, db_expr_t, char *);
   96 void    db_page_print_cmd(db_expr_t, int, db_expr_t, char *);
   97 void    db_extent_print_cmd(db_expr_t, int, db_expr_t, char *);
   98 void    db_pool_print_cmd(db_expr_t, int, db_expr_t, char *);
   99 void    db_proc_print_cmd(db_expr_t, int, db_expr_t, char *);
  100 void    db_uvmexp_print_cmd(db_expr_t, int, db_expr_t, char *);
  101 void    db_tdb_print_cmd(db_expr_t, int, db_expr_t, char *);
  102 void    db_vnode_print_cmd(db_expr_t, int, db_expr_t, char *);
  103 void    db_nfsreq_print_cmd(db_expr_t, int, db_expr_t, char *);
  104 void    db_nfsnode_print_cmd(db_expr_t, int, db_expr_t, char *);
  105 void    db_swap_print_cmd(db_expr_t, int, db_expr_t, char *);
  106 void    db_help_cmd(db_expr_t, int, db_expr_t, char *);
  107 void    db_fncall(db_expr_t, int, db_expr_t, char *);
  108 void    db_boot_sync_cmd(db_expr_t, int, db_expr_t, char *);
  109 void    db_boot_crash_cmd(db_expr_t, int, db_expr_t, char *);
  110 void    db_boot_dump_cmd(db_expr_t, int, db_expr_t, char *);
  111 void    db_boot_halt_cmd(db_expr_t, int, db_expr_t, char *);
  112 void    db_boot_reboot_cmd(db_expr_t, int, db_expr_t, char *);
  113 void    db_boot_poweroff_cmd(db_expr_t, int, db_expr_t, char *);
  114 void    db_stack_trace_cmd(db_expr_t, int, db_expr_t, char *);
  115 void    db_dmesg_cmd(db_expr_t, int, db_expr_t, char *);
  116 void    db_show_panic_cmd(db_expr_t, int, db_expr_t, char *);
  117 void    db_bcstats_print_cmd(db_expr_t, int, db_expr_t, char *);
  118 void    db_struct_offset_cmd(db_expr_t, int, db_expr_t, char *);
  119 void    db_ctf_show_struct(db_expr_t, int, db_expr_t, char *);
  120 void    db_show_regs(db_expr_t, int, db_expr_t, char *);
  121 void    db_write_cmd(db_expr_t, int, db_expr_t, char *);
  122 void    db_witness_display(db_expr_t, int, db_expr_t, char *);
  123 void    db_witness_list(db_expr_t, int, db_expr_t, char *);
  124 void    db_witness_list_all(db_expr_t, int, db_expr_t, char *);
  125 
  126 
  127 /*
  128  * Utility routine - discard tokens through end-of-line.
  129  */
  130 void
  131 db_skip_to_eol(void)
  132 {
  133         int     t;
  134         do {
  135                 t = db_read_token();
  136         } while (t != tEOL);
  137 }
  138 
  139 /*
  140  * Results of command search.
  141  */
  142 #define CMD_UNIQUE      0
  143 #define CMD_FOUND       1
  144 #define CMD_NONE        2
  145 #define CMD_AMBIGUOUS   3
  146 
  147 /*
  148  * Search for command prefix.
  149  */
  150 int
  151 db_cmd_search(char *name, const struct db_command *table,
  152     const struct db_command **cmdp)
  153 {
  154         const struct db_command *cmd;
  155         int                     result = CMD_NONE;
  156 
  157         for (cmd = table; cmd->name != 0; cmd++) {
  158                 char *lp = name, *rp = cmd->name;
  159                 int  c;
  160 
  161                 while ((c = *lp) == *rp) {
  162                         if (c == 0) {
  163                                 /* complete match */
  164                                 *cmdp = cmd;
  165                                 return (CMD_UNIQUE);
  166                         }
  167                         lp++;
  168                         rp++;
  169                 }
  170                 if (c == 0) {
  171                         /* end of name, not end of command - partial match */
  172                         if (result == CMD_FOUND) {
  173                                 result = CMD_AMBIGUOUS;
  174                                 /* but keep looking for a full match -
  175                                    this lets us match single letters */
  176                         } else {
  177                                 *cmdp = cmd;
  178                                 result = CMD_FOUND;
  179                         }
  180                 }
  181         }
  182         return (result);
  183 }
  184 
  185 void
  186 db_cmd_list(const struct db_command *table)
  187 {
  188         const struct db_command *cmd;
  189 
  190         for (cmd = table; cmd->name != 0; cmd++) {
  191                 db_printf("%-12s", cmd->name);
  192                 db_end_line(12);
  193         }
  194 }
  195 
  196 void
  197 db_command(const struct db_command **last_cmdp,
  198     const struct db_command *cmd_table)
  199 {
  200         const struct db_command *cmd;
  201         char            modif[TOK_STRING_SIZE];
  202         db_expr_t       addr, count;
  203         int             t, result, have_addr = 0;
  204 
  205         t = db_read_token();
  206         if (t == tEOL) {
  207                 /* empty line repeats last command, at 'next' */
  208                 cmd = *last_cmdp;
  209                 addr = (db_expr_t)db_next;
  210                 have_addr = 0;
  211                 count = 1;
  212                 modif[0] = '\0';
  213         } else if (t == tEXCL) {
  214                 db_fncall(0, 0, 0, NULL);
  215                 return;
  216         } else if (t != tIDENT) {
  217                 db_printf("?\n");
  218                 db_flush_lex();
  219                 return;
  220         } else {
  221                 /* Search for command */
  222                 while (cmd_table) {
  223                         result = db_cmd_search(db_tok_string,
  224                             cmd_table, &cmd);
  225                         switch (result) {
  226                         case CMD_NONE:
  227                                 db_printf("No such command\n");
  228                                 db_flush_lex();
  229                                 return;
  230                         case CMD_AMBIGUOUS:
  231                                 db_printf("Ambiguous\n");
  232                                 db_flush_lex();
  233                                 return;
  234                         default:
  235                                 break;
  236                         }
  237                         if ((cmd_table = cmd->more) != 0) {
  238                                 t = db_read_token();
  239                                 if (t != tIDENT) {
  240                                         db_cmd_list(cmd_table);
  241                                         db_flush_lex();
  242                                         return;
  243                                 }
  244                         }
  245                 }
  246 
  247                 if ((cmd->flag & CS_OWN) == 0) {
  248                         /*
  249                          * Standard syntax:
  250                          * command [/modifier] [addr] [,count]
  251                          */
  252                         t = db_read_token();
  253                         if (t == tSLASH) {
  254                                 t = db_read_token();
  255                                 if (t != tIDENT) {
  256                                         db_printf("Bad modifier\n");
  257                                         db_flush_lex();
  258                                         return;
  259                                 }
  260                                 db_strlcpy(modif, db_tok_string, sizeof(modif));
  261                         } else {
  262                                 db_unread_token(t);
  263                                 modif[0] = '\0';
  264                         }
  265 
  266                         if (db_expression(&addr)) {
  267                                 db_dot = (vaddr_t) addr;
  268                                 db_last_addr = db_dot;
  269                                 have_addr = 1;
  270                         } else {
  271                                 addr = (db_expr_t) db_dot;
  272                                 have_addr = 0;
  273                         }
  274                         t = db_read_token();
  275                         if (t == tCOMMA) {
  276                                 if (!db_expression(&count)) {
  277                                         db_printf("Count missing\n");
  278                                         db_flush_lex();
  279                                         return;
  280                                 }
  281                         } else {
  282                                 db_unread_token(t);
  283                                 count = -1;
  284                         }
  285                         if ((cmd->flag & CS_MORE) == 0)
  286                                 db_skip_to_eol();
  287                 }
  288         }
  289         *last_cmdp = cmd;
  290         if (cmd != 0) {
  291                 /* Execute the command. */
  292                 (*cmd->fcn)(addr, have_addr, count, modif);
  293 
  294                 if (cmd->flag & CS_SET_DOT) {
  295                         /*
  296                          * If command changes dot, set dot to
  297                          * previous address displayed (if 'ed' style).
  298                          */
  299                         if (db_ed_style)
  300                                 db_dot = db_prev;
  301                         else
  302                                 db_dot = db_next;
  303                 }
  304         } else {
  305                 /*
  306                  * If command does not change dot,
  307                  * set 'next' location to be the same.
  308                  */
  309                 db_next = db_dot;
  310         }
  311 }
  312 
  313 /*ARGSUSED*/
  314 void
  315 db_buf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  316 {
  317         int full = 0;
  318 
  319         if (modif[0] == 'f')
  320                 full = 1;
  321 
  322         vfs_buf_print((void *) addr, full, db_printf);
  323 }
  324 
  325 /*ARGSUSED*/
  326 void
  327 db_map_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  328 {
  329         int full = 0;
  330 
  331         if (modif[0] == 'f')
  332                 full = 1;
  333 
  334         uvm_map_printit((struct vm_map *) addr, full, db_printf);
  335 }
  336 
  337 /*ARGSUSED*/
  338 void
  339 db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  340 {
  341         malloc_printit(db_printf);
  342 }
  343 
  344 /*ARGSUSED*/
  345 void
  346 db_mbuf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  347 {
  348         m_print((void *)addr, db_printf);
  349 }
  350 
  351 /*ARGSUSED*/
  352 void
  353 db_socket_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  354 {
  355         so_print((void *)addr, db_printf);
  356 }
  357 
  358 /*ARGSUSED*/
  359 void
  360 db_mount_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  361 {
  362         int full = 0;
  363 
  364         if (modif[0] == 'f')
  365                 full = 1;
  366 
  367         vfs_mount_print((struct mount *) addr, full, db_printf);
  368 }
  369 
  370 void
  371 db_show_all_mounts(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  372 {
  373         int full = 0;
  374         struct mount *mp;
  375 
  376         if (modif[0] == 'f')
  377                 full = 1;
  378 
  379         TAILQ_FOREACH(mp, &mountlist, mnt_list) {
  380                 db_printf("mountpoint %p\n", mp);
  381                 vfs_mount_print(mp, full, db_printf);
  382         }
  383 }
  384 
  385 extern struct pool vnode_pool;
  386 void
  387 db_show_all_vnodes(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  388 {
  389         int full = 0;
  390 
  391         if (modif[0] == 'f')
  392                 full = 1;
  393 
  394         pool_walk(&vnode_pool, full, db_printf, vfs_vnode_print);
  395 }
  396 
  397 extern struct pool bufpool;
  398 void
  399 db_show_all_bufs(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  400 {
  401         int full = 0;
  402 
  403         if (modif[0] == 'f')
  404                 full = 1;
  405 
  406         pool_walk(&bufpool, full, db_printf, vfs_buf_print);
  407 }
  408 
  409 #ifdef IPSEC
  410 void
  411 db_show_all_tdbs(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  412 {
  413         int full = 0;
  414 
  415         if (modif[0] == 'f')
  416                 full = 1;
  417 
  418         pool_walk(&tdb_pool, full, db_printf, tdb_printit);
  419 }
  420 #endif
  421 
  422 void
  423 db_show_all_routes(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  424 {
  425         u_int rtableid = 0;
  426 
  427         if (have_addr)
  428                 rtableid = addr;
  429         if (count == -1)
  430                 count = 1;
  431 
  432         while (count--) {
  433                 if (modif[0] != 'I')
  434                         db_show_rtable(AF_INET, rtableid);
  435                 if (modif[0] != 'i')
  436                         db_show_rtable(AF_INET6, rtableid);
  437                 rtableid++;
  438         }
  439 }
  440 
  441 void
  442 db_show_route(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  443 {
  444         db_show_rtentry((void *)addr, NULL, -1);
  445 }
  446 
  447 /*ARGSUSED*/
  448 void
  449 db_object_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  450 {
  451         int full = 0;
  452 
  453         if (modif[0] == 'f')
  454                 full = 1;
  455 
  456         uvm_object_printit((struct uvm_object *) addr, full, db_printf);
  457 }
  458 
  459 /*ARGSUSED*/
  460 void
  461 db_page_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  462 {
  463         int full = 0;
  464 
  465         if (modif[0] == 'f')
  466                 full = 1;
  467 
  468         uvm_page_printit((struct vm_page *) addr, full, db_printf);
  469 }
  470 
  471 /*ARGSUSED*/
  472 void
  473 db_vnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  474 {
  475         int full = 0;
  476 
  477         if (modif[0] == 'f')
  478                 full = 1;
  479 
  480         vfs_vnode_print((void *)addr, full, db_printf);
  481 }
  482 
  483 #ifdef NFSCLIENT
  484 /*ARGSUSED*/
  485 void
  486 db_nfsreq_print_cmd(db_expr_t addr, int have_addr, db_expr_t count,
  487     char *modif)
  488 {
  489         int full = 0;
  490 
  491         if (modif[0] == 'f')
  492                 full = 1;
  493 
  494         nfs_request_print((void *)addr, full, db_printf);
  495 }
  496 
  497 /*ARGSUSED*/
  498 void
  499 db_nfsnode_print_cmd(db_expr_t addr, int have_addr, db_expr_t count,
  500     char *modif)
  501 {
  502         int full = 0;
  503 
  504         if (modif[0] == 'f')
  505                 full = 1;
  506 
  507         nfs_node_print((void *)addr, full, db_printf);
  508 }
  509 #endif
  510 
  511 /*ARGSUSED*/
  512 void
  513 db_swap_print_cmd(db_expr_t addr, int have_addr, db_expr_t count,
  514     char *modif)
  515 {
  516         swap_print_all(db_printf);
  517 }
  518 
  519 /*ARGSUSED*/
  520 void
  521 db_show_panic_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  522 {
  523         struct cpu_info *ci;
  524         char *prefix;
  525         CPU_INFO_ITERATOR cii;
  526         int panicked = 0;
  527 
  528         CPU_INFO_FOREACH(cii, ci) {
  529                 if (ci->ci_panicbuf[0] != '\0') {
  530                         prefix = (panicstr == ci->ci_panicbuf) ? "*" : " ";
  531                         db_printf("%scpu%d: %s\n",
  532                             prefix, CPU_INFO_UNIT(ci), ci->ci_panicbuf);
  533                         panicked = 1;
  534                 }
  535         }
  536         if (!panicked)
  537                 db_printf("the kernel did not panic\n");        /* yet */
  538 }
  539 
  540 /*ARGSUSED*/
  541 void
  542 db_extent_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  543 {
  544         extent_print_all();
  545 }
  546 
  547 /*ARGSUSED*/
  548 void
  549 db_pool_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  550 {
  551         pool_printit((struct pool *)addr, modif, db_printf);
  552 }
  553 
  554 /*ARGSUSED*/
  555 void
  556 db_proc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  557 {
  558         if (!have_addr)
  559                 addr = (db_expr_t)curproc;
  560 
  561         proc_printit((struct proc *)addr, modif, db_printf);
  562 }
  563 
  564 #ifdef IPSEC
  565 void
  566 db_tdb_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  567 {
  568         int full = 0;
  569 
  570         if (modif[0] == 'f')
  571                 full = 1;
  572 
  573         tdb_printit((void *)addr, full, db_printf);
  574 }
  575 #endif
  576 
  577 /*ARGSUSED*/
  578 void
  579 db_uvmexp_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  580 {
  581         uvmexp_print(db_printf);
  582 }
  583 
  584 void    bcstats_print(int (*)(const char *, ...));
  585 
  586 /*ARGSUSED*/
  587 void
  588 db_bcstats_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  589 {
  590         bcstats_print(db_printf);
  591 }
  592 
  593 /*
  594  * 'show' commands
  595  */
  596 
  597 const struct db_command db_show_all_cmds[] = {
  598         { "procs",      db_show_all_procs,      0, NULL },
  599         { "callout",    db_show_callout,        0, NULL },
  600 #ifdef __HAVE_CLOCKINTR
  601         { "clockintr",  db_show_all_clockintr,  0, NULL },
  602 #endif
  603         { "pools",      db_show_all_pools,      0, NULL },
  604         { "mounts",     db_show_all_mounts,     0, NULL },
  605         { "vnodes",     db_show_all_vnodes,     0, NULL },
  606         { "bufs",       db_show_all_bufs,       0, NULL },
  607         { "routes",     db_show_all_routes,     0, NULL },
  608 #ifdef NFSCLIENT
  609         { "nfsreqs",    db_show_all_nfsreqs,    0, NULL },
  610         { "nfsnodes",   db_show_all_nfsnodes,   0, NULL },
  611 #endif
  612 #ifdef IPSEC
  613         { "tdbs",       db_show_all_tdbs,       0, NULL },
  614 #endif
  615 #ifdef WITNESS
  616         { "locks",      db_witness_list_all,    0, NULL },
  617 #endif
  618         { NULL,         NULL,                   0, NULL }
  619 };
  620 
  621 const struct db_command db_show_cmds[] = {
  622         { "all",        NULL,                   0,      db_show_all_cmds },
  623         { "bcstats",    db_bcstats_print_cmd,   0,      NULL },
  624         { "breaks",     db_listbreak_cmd,       0,      NULL },
  625         { "buf",        db_buf_print_cmd,       0,      NULL },
  626         { "extents",    db_extent_print_cmd,    0,      NULL },
  627 #ifdef WITNESS
  628         { "locks",      db_witness_list,        0,      NULL },
  629 #endif
  630         { "malloc",     db_malloc_print_cmd,    0,      NULL },
  631         { "map",        db_map_print_cmd,       0,      NULL },
  632         { "mbuf",       db_mbuf_print_cmd,      0,      NULL },
  633         { "mount",      db_mount_print_cmd,     0,      NULL },
  634 #ifdef NFSCLIENT
  635         { "nfsreq",     db_nfsreq_print_cmd,    0,      NULL },
  636         { "nfsnode",    db_nfsnode_print_cmd,   0,      NULL },
  637 #endif
  638         { "object",     db_object_print_cmd,    0,      NULL },
  639         { "page",       db_page_print_cmd,      0,      NULL },
  640         { "panic",      db_show_panic_cmd,      0,      NULL },
  641         { "pool",       db_pool_print_cmd,      0,      NULL },
  642         { "proc",       db_proc_print_cmd,      0,      NULL },
  643         { "registers",  db_show_regs,           0,      NULL },
  644         { "route",      db_show_route,          0,      NULL },
  645         { "socket",     db_socket_print_cmd,    0,      NULL },
  646         { "struct",     db_ctf_show_struct,     CS_OWN, NULL },
  647         { "swap",       db_swap_print_cmd,      0,      NULL },
  648 #ifdef IPSEC
  649         { "tdb",        db_tdb_print_cmd,       0,      NULL },
  650 #endif
  651         { "uvmexp",     db_uvmexp_print_cmd,    0,      NULL },
  652         { "vnode",      db_vnode_print_cmd,     0,      NULL },
  653         { "watches",    db_listwatch_cmd,       0,      NULL },
  654 #ifdef WITNESS
  655         { "witness",    db_witness_display,     0,      NULL },
  656 #endif
  657         { NULL,         NULL,                   0,      NULL }
  658 };
  659 
  660 const struct db_command db_boot_cmds[] = {
  661         { "sync",       db_boot_sync_cmd,       0,      0 },
  662         { "crash",      db_boot_crash_cmd,      0,      0 },
  663         { "dump",       db_boot_dump_cmd,       0,      0 },
  664         { "halt",       db_boot_halt_cmd,       0,      0 },
  665         { "reboot",     db_boot_reboot_cmd,     0,      0 },
  666         { "poweroff",   db_boot_poweroff_cmd,   0,      0 },
  667         { NULL, }
  668 };
  669 
  670 const struct db_command db_command_table[] = {
  671 #ifdef DB_MACHINE_COMMANDS
  672   /* this must be the first entry, if it exists */
  673         { "machine",    NULL,                   0, db_machine_command_table },
  674 #endif
  675         { "kill",       db_kill_cmd,            0,              NULL },
  676         { "print",      db_print_cmd,           0,              NULL },
  677         { "p",          db_print_cmd,           0,              NULL },
  678         { "pprint",     db_ctf_pprint_cmd,      CS_OWN,         NULL },
  679         { "examine",    db_examine_cmd,         CS_SET_DOT,     NULL },
  680         { "x",          db_examine_cmd,         CS_SET_DOT,     NULL },
  681         { "search",     db_search_cmd,          CS_OWN|CS_SET_DOT, NULL },
  682         { "set",        db_set_cmd,             CS_OWN,         NULL },
  683         { "write",      db_write_cmd,           CS_MORE|CS_SET_DOT, NULL },
  684         { "w",          db_write_cmd,           CS_MORE|CS_SET_DOT, NULL },
  685         { "delete",     db_delete_cmd,          0,              NULL },
  686         { "d",          db_delete_cmd,          0,              NULL },
  687         { "break",      db_breakpoint_cmd,      0,              NULL },
  688         { "dwatch",     db_deletewatch_cmd,     0,              NULL },
  689         { "watch",      db_watchpoint_cmd,      CS_MORE,        NULL },
  690         { "step",       db_single_step_cmd,     0,              NULL },
  691         { "s",          db_single_step_cmd,     0,              NULL },
  692         { "continue",   db_continue_cmd,        0,              NULL },
  693         { "c",          db_continue_cmd,        0,              NULL },
  694         { "until",      db_trace_until_call_cmd,0,              NULL },
  695         { "next",       db_trace_until_matching_cmd,0,          NULL },
  696         { "match",      db_trace_until_matching_cmd,0,          NULL },
  697         { "trace",      db_stack_trace_cmd,     0,              NULL },
  698         { "bt",         db_stack_trace_cmd,     0,              NULL },
  699         { "call",       db_fncall,              CS_OWN,         NULL },
  700         { "ps",         db_show_all_procs,      0,              NULL },
  701         { "callout",    db_show_callout,        0,              NULL },
  702         { "reboot",     db_boot_reboot_cmd,     0,              NULL },
  703         { "show",       NULL,                   0,              db_show_cmds },
  704         { "boot",       NULL,                   0,              db_boot_cmds },
  705         { "help",       db_help_cmd,            0,              NULL },
  706         { "hangman",    db_hangman,             0,              NULL },
  707         { "dmesg",      db_dmesg_cmd,           0,              NULL },
  708         { NULL,         NULL,                   0,              NULL }
  709 };
  710 
  711 const struct db_command *db_last_command = NULL;
  712 
  713 void
  714 db_help_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  715 {
  716         db_cmd_list(db_command_table);
  717 }
  718 
  719 void
  720 db_command_loop(void)
  721 {
  722         label_t         db_jmpbuf;
  723         label_t         *savejmp;
  724         extern int      db_output_line;
  725 
  726         /*
  727          * Initialize 'prev' and 'next' to dot.
  728          */
  729         db_prev = db_dot;
  730         db_next = db_dot;
  731 
  732         db_cmd_loop_done = 0;
  733 
  734         savejmp = db_recover;
  735         db_recover = &db_jmpbuf;
  736         (void) setjmp(&db_jmpbuf);
  737 
  738         while (!db_cmd_loop_done) {
  739 
  740                 if (db_print_position() != 0)
  741                         db_printf("\n");
  742                 db_output_line = 0;
  743 
  744 #ifdef MULTIPROCESSOR
  745                 db_printf("ddb{%d}> ", CPU_INFO_UNIT(curcpu()));
  746 #else
  747                 db_printf("ddb> ");
  748 #endif
  749                 (void) db_read_line();
  750 
  751                 db_command(&db_last_command, db_command_table);
  752         }
  753 
  754         db_recover = savejmp;
  755 }
  756 
  757 void
  758 db_error(char *s)
  759 {
  760         if (s)
  761                 db_printf("%s", s);
  762         db_flush_lex();
  763         if (db_recover != NULL)
  764                 longjmp(db_recover);
  765 }
  766 
  767 
  768 /*
  769  * Call random function:
  770  * !expr(arg,arg,arg)
  771  */
  772 /*ARGSUSED*/
  773 void
  774 db_fncall(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  775 {
  776         db_expr_t       fn_addr;
  777 #define MAXARGS         11
  778         db_expr_t       args[MAXARGS];
  779         int             nargs = 0;
  780         db_expr_t       retval;
  781         db_expr_t       (*func)(db_expr_t, ...);
  782         int             t;
  783         char            tmpfmt[28];
  784 
  785         if (!db_expression(&fn_addr)) {
  786                 db_printf("Bad function\n");
  787                 db_flush_lex();
  788                 return;
  789         }
  790         func = (db_expr_t (*)(db_expr_t, ...)) fn_addr;
  791 
  792         t = db_read_token();
  793         if (t == tLPAREN) {
  794                 if (db_expression(&args[0])) {
  795                         nargs++;
  796                         while ((t = db_read_token()) == tCOMMA) {
  797                                 if (nargs == MAXARGS) {
  798                                         db_printf("Too many arguments\n");
  799                                         db_flush_lex();
  800                                         return;
  801                                 }
  802                                 if (!db_expression(&args[nargs])) {
  803                                         db_printf("Argument missing\n");
  804                                         db_flush_lex();
  805                                         return;
  806                                 }
  807                                 nargs++;
  808                         }
  809                         db_unread_token(t);
  810                 }
  811                 if (db_read_token() != tRPAREN) {
  812                         db_printf("?\n");
  813                         db_flush_lex();
  814                         return;
  815                 }
  816         }
  817         db_skip_to_eol();
  818 
  819         while (nargs < MAXARGS)
  820                 args[nargs++] = 0;
  821 
  822         retval = (*func)(args[0], args[1], args[2], args[3], args[4],
  823             args[5], args[6], args[7], args[8], args[9]);
  824         db_printf("%s\n", db_format(tmpfmt, sizeof tmpfmt, retval,
  825             DB_FORMAT_N, 1, 0));
  826 }
  827 
  828 void
  829 db_reboot(int howto)
  830 {
  831         spl0();
  832         if (!curproc)
  833                 curproc = &proc0;
  834         reboot(howto);
  835 }
  836 
  837 void
  838 db_boot_sync_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  839 {
  840         db_reboot(RB_AUTOBOOT | RB_TIMEBAD | RB_USERREQ);
  841 }
  842 
  843 void
  844 db_boot_crash_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  845 {
  846         db_reboot(RB_NOSYNC | RB_DUMP | RB_TIMEBAD | RB_USERREQ);
  847 }
  848 
  849 void
  850 db_boot_dump_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  851 {
  852         db_reboot(RB_DUMP | RB_TIMEBAD | RB_USERREQ);
  853 }
  854 
  855 void
  856 db_boot_halt_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  857 {
  858         db_reboot(RB_NOSYNC | RB_HALT | RB_TIMEBAD | RB_USERREQ);
  859 }
  860 
  861 void
  862 db_boot_reboot_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  863 {
  864         boot(RB_RESET | RB_AUTOBOOT | RB_NOSYNC | RB_TIMEBAD | RB_USERREQ);
  865 }
  866 
  867 void
  868 db_boot_poweroff_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  869 {
  870         db_reboot(RB_NOSYNC | RB_HALT | RB_POWERDOWN | RB_TIMEBAD | RB_USERREQ);
  871 }
  872 
  873 void
  874 db_dmesg_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
  875 {
  876         int i, off;
  877         char *p;
  878 
  879         if (!msgbufp || msgbufp->msg_magic != MSG_MAGIC)
  880                 return;
  881         off = msgbufp->msg_bufx;
  882         if (off > msgbufp->msg_bufs)
  883                 off = 0;
  884         for (i = 0, p = msgbufp->msg_bufc + off;
  885             i < msgbufp->msg_bufs; i++, p++) {
  886                 if (p >= msgbufp->msg_bufc + msgbufp->msg_bufs)
  887                         p = msgbufp->msg_bufc;
  888                 if (*p != '\0')
  889                         db_putchar(*p);
  890         }
  891         db_putchar('\n');
  892 }
  893 
  894 void
  895 db_stack_trace_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  896 {
  897         db_stack_trace_print(addr, have_addr, count, modif, db_printf);
  898 }
  899 
  900 void
  901 db_show_regs(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  902 {
  903         struct db_variable *regp;
  904         db_expr_t       value, offset;
  905         char *          name;
  906         char            tmpfmt[28];
  907 
  908         for (regp = db_regs; regp < db_eregs; regp++) {
  909                 db_read_variable(regp, &value);
  910                 db_printf("%-12s%s", regp->name,
  911                     db_format(tmpfmt, sizeof tmpfmt,
  912                     (long)value, DB_FORMAT_N, 1, sizeof(long) * 3));
  913                 db_find_xtrn_sym_and_offset((vaddr_t)value, &name, &offset);
  914                 if (name != 0 && offset <= db_maxoff && offset != value) {
  915                         db_printf("\t%s", name);
  916                         if (offset != 0)
  917                                 db_printf("+%s",
  918                                     db_format(tmpfmt, sizeof tmpfmt,
  919                                     (long)offset, DB_FORMAT_R, 1, 0));
  920                 }
  921                 db_printf("\n");
  922         }
  923         db_print_loc_and_inst(PC_REGS(&ddb_regs));
  924 }
  925 
  926 /*
  927  * Write to file.
  928  */
  929 /*ARGSUSED*/
  930 void
  931 db_write_cmd(db_expr_t address, int have_addr, db_expr_t count, char *modif)
  932 {
  933         vaddr_t         addr;
  934         db_expr_t       old_value;
  935         db_expr_t       new_value;
  936         int             size, wrote_one = 0;
  937         char            tmpfmt[28];
  938 
  939         addr = (vaddr_t) address;
  940 
  941         switch (modif[0]) {
  942         case 'b':
  943                 size = 1;
  944                 break;
  945         case 'h':
  946                 size = 2;
  947                 break;
  948         case 'l':
  949         case '\0':
  950                 size = 4;
  951                 break;
  952 #ifdef __LP64__
  953         case 'q':
  954                 size = 8;
  955                 break;
  956 #endif
  957         default:
  958                 size = -1;
  959                 db_error("Unknown size\n");
  960                 /*NOTREACHED*/
  961         }
  962 
  963         while (db_expression(&new_value)) {
  964                 old_value = db_get_value(addr, size, 0);
  965                 db_printsym(addr, DB_STGY_ANY, db_printf);
  966                 db_printf("\t\t%s\t", db_format(tmpfmt, sizeof tmpfmt,
  967                     old_value, DB_FORMAT_N, 0, 8));
  968                 db_printf("=\t%s\n",  db_format(tmpfmt, sizeof tmpfmt,
  969                     new_value, DB_FORMAT_N, 0, 8));
  970                 db_put_value(addr, size, new_value);
  971                 addr += size;
  972 
  973                 wrote_one = 1;
  974         }
  975 
  976         if (!wrote_one) {
  977                 db_error("Nothing written.\n");
  978                 /*NOTREACHED*/
  979         }
  980 
  981         db_next = addr;
  982         db_prev = addr - size;
  983 
  984         db_skip_to_eol();
  985 }

Cache object: b5c2281afb322d23fee388e848d922a2


[ 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.