root/ddb/db_output.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. db_force_whitespace
  2. db_more
  3. db_putchar
  4. db_print_position
  5. db_end_line
  6. db_format
  7. db_stack_dump

    1 /*      $OpenBSD: db_output.c,v 1.25 2006/07/06 18:14:14 miod Exp $     */
    2 /*      $NetBSD: db_output.c,v 1.13 1996/04/01 17:27:14 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  * Printf and character output for debugger.
   32  */
   33 #include <sys/param.h>
   34 #include <sys/proc.h>
   35 #include <sys/stdarg.h>
   36 #include <sys/systm.h>
   37 
   38 #include <dev/cons.h>
   39 
   40 #include <uvm/uvm_extern.h>
   41 
   42 #include <machine/db_machdep.h>
   43 
   44 #include <ddb/db_command.h>
   45 #include <ddb/db_output.h>
   46 #include <ddb/db_interface.h>
   47 #include <ddb/db_sym.h>
   48 #include <ddb/db_var.h>
   49 #include <ddb/db_extern.h>
   50 
   51 /*
   52  *      Character output - tracks position in line.
   53  *      To do this correctly, we should know how wide
   54  *      the output device is - then we could zero
   55  *      the line position when the output device wraps
   56  *      around to the start of the next line.
   57  *
   58  *      Instead, we count the number of spaces printed
   59  *      since the last printing character so that we
   60  *      don't print trailing spaces.  This avoids most
   61  *      of the wraparounds.
   62  */
   63 
   64 #ifndef DB_MAX_LINE
   65 #define DB_MAX_LINE             24      /* maximum line */
   66 #define DB_MAX_WIDTH            80      /* maximum width */
   67 #endif  /* DB_MAX_LINE */
   68 
   69 #define DB_MIN_MAX_WIDTH        20      /* minimum max width */
   70 #define DB_MIN_MAX_LINE         3       /* minimum max line */
   71 #define CTRL(c)                 ((c) & 0xff)
   72 
   73 int     db_output_position = 0;         /* output column */
   74 int     db_output_line = 0;             /* output line number */
   75 int     db_last_non_space = 0;          /* last non-space character */
   76 int     db_tab_stop_width = 8;          /* how wide are tab stops? */
   77 #define NEXT_TAB(i) \
   78         ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
   79 int     db_max_line = DB_MAX_LINE;      /* output max lines */
   80 int     db_max_width = DB_MAX_WIDTH;    /* output line width */
   81 int     db_radix = 16;                  /* output numbers radix */
   82 
   83 static void db_more(void);
   84 
   85 /*
   86  * Force pending whitespace.
   87  */
   88 void
   89 db_force_whitespace(void)
   90 {
   91         int last_print, next_tab;
   92 
   93         last_print = db_last_non_space;
   94         while (last_print < db_output_position) {
   95             next_tab = NEXT_TAB(last_print);
   96             if (next_tab <= db_output_position) {
   97                 while (last_print < next_tab) { /* DON'T send a tab!!! */
   98                         cnputc(' ');
   99                         last_print++;
  100                 }
  101             }
  102             else {
  103                 cnputc(' ');
  104                 last_print++;
  105             }
  106         }
  107         db_last_non_space = db_output_position;
  108 }
  109 
  110 static void
  111 db_more(void)
  112 {
  113         char *p;
  114         int quit_output = 0;
  115 
  116         for (p = "--db_more--"; *p; p++)
  117             cnputc(*p);
  118         switch(cngetc()) {
  119         case ' ':
  120             db_output_line = 0;
  121             break;
  122         case 'q':
  123         case CTRL('c'):
  124             db_output_line = 0;
  125             quit_output = 1;
  126             break;
  127         default:
  128             db_output_line--;
  129             break;
  130         }
  131         p = "\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b";
  132         while (*p)
  133             cnputc(*p++);
  134         if (quit_output) {
  135             db_error(0);
  136             /* NOTREACHED */
  137         }
  138 }
  139 
  140 /*
  141  * Output character.  Buffer whitespace.
  142  */
  143 void
  144 db_putchar(int c)
  145 {
  146         if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
  147             db_more();
  148 
  149         if (c > ' ' && c <= '~') {
  150             /*
  151              * Printing character.
  152              * If we have spaces to print, print them first.
  153              * Use tabs if possible.
  154              */
  155             db_force_whitespace();
  156             cnputc(c);
  157             db_output_position++;
  158             if (db_max_width >= DB_MIN_MAX_WIDTH
  159                 && db_output_position >= db_max_width-1) {
  160                 /* auto new line */
  161                 cnputc('\n');
  162                 db_output_position = 0;
  163                 db_last_non_space = 0;
  164                 db_output_line++;
  165             }
  166             db_last_non_space = db_output_position;
  167         }
  168         else if (c == '\n') {
  169             /* Return */
  170             cnputc(c);
  171             db_output_position = 0;
  172             db_last_non_space = 0;
  173             db_output_line++;
  174         }
  175         else if (c == '\t') {
  176             /* assume tabs every 8 positions */
  177             db_output_position = NEXT_TAB(db_output_position);
  178         }
  179         else if (c == ' ') {
  180             /* space */
  181             db_output_position++;
  182         }
  183         else if (c == '\007') {
  184             /* bell */
  185             cnputc(c);
  186         }
  187         /* other characters are assumed non-printing */
  188 }
  189 
  190 /*
  191  * Return output position
  192  */
  193 int
  194 db_print_position(void)
  195 {
  196         return (db_output_position);
  197 }
  198 
  199 /*
  200  * End line if too long.
  201  */
  202 void
  203 db_end_line(int space)
  204 {
  205         if (db_output_position >= db_max_width - space)
  206             db_printf("\n");
  207 }
  208 
  209 char *
  210 db_format(char *buf, size_t bufsize, long val, int format, int alt, int width)
  211 {
  212         const char *fmt;
  213 
  214         if (format == DB_FORMAT_Z || db_radix == 16)
  215                 fmt = alt ? "-%#*lx" : "-%*lx";
  216         else if (db_radix == 8)
  217                 fmt = alt ? "-%#*lo" : "-%*lo";
  218         else
  219                 fmt = alt ? "-%#*lu" : "-%*lu";
  220 
  221         /* The leading '-' is a nasty (and beautiful) idea from NetBSD */
  222         if (val < 0 && format != DB_FORMAT_N)
  223                 val = -val;
  224         else
  225                 fmt++;
  226 
  227         snprintf(buf, bufsize, fmt, width, val);
  228 
  229         return (buf);
  230 }
  231 
  232 void
  233 db_stack_dump(void)
  234 {
  235         static int intrace;
  236 
  237         if (intrace) {
  238                 printf("Faulted in traceback, aborting...\n");
  239                 return;
  240         }
  241 
  242         intrace = 1;
  243         printf("Starting stack trace...\n");
  244         db_stack_trace_print((db_expr_t)__builtin_frame_address(0), TRUE,
  245             256 /* low limit */, "", printf);
  246         printf("End of stack trace.\n");
  247         intrace = 0;
  248 }

/* [<][>][^][v][top][bottom][index][help] */