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

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

Generated by: LCOV version 1.13