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

Cache object: b7f04212ac9ae99ba7abaae4058ae4ed


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