LCOV - code coverage report
Current view: top level - ddb - db_command.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 324 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13