On Tue, May 08, 2018 at 01:44:39AM +0300, Artturi Alm wrote:
> Hi,
> 
> (manual "copypaste"):
> nc2k4hp# sysctl ddb.trigger=1
> Stopped at    db_enter+0x4:   popl    %ebp
> ddb{0}> print/x "eax = " $eax "\necx = " $ecx "\n"
>       3
> ddb{0}> c
> ddb.trigger: 0 -> 1
> 
> so, for reasons yet unknown to me, p[rint] doesn't seem to work at all
> like described in the man page, tested on i386.
> Should it work? I hope it would.
> 

Does feel like waste of time to go any further fixing this, if this is
yet another bug too irrelevant for anyone to ack for, so _any_ input
here would be great.

Fixing this to allow strings with spaces etc. without escaping won't be
pretty, but the diff below does get it this far:

ddb{0}> p "eax\ \=\ " $eax "\\necx\ \=\ " $ecx "\\n"
eax =       13
ecx = d34b2000

ddb{0}> 

The goto label approach was taken below because of how broken sys/ddb/
is with regards to spacing and style(9) + desire to keep it minimal.

-Artturi


diff --git sys/ddb/db_command.c sys/ddb/db_command.c
index a275023dc58..27cda0ba641 100644
--- sys/ddb/db_command.c
+++ sys/ddb/db_command.c
@@ -612,8 +612,8 @@ struct db_command db_command_table[] = {
        { "machine",    NULL,                   0,              NULL},
 #endif
        { "kill",       db_kill_cmd,            0,              NULL },
-       { "print",      db_print_cmd,           0,              NULL },
-       { "p",          db_print_cmd,           0,              NULL },
+       { "print",      db_print_cmd,           CS_OWN,         NULL },
+       { "p",          db_print_cmd,           CS_OWN,         NULL },
        { "pprint",     db_ctf_pprint_cmd,      CS_OWN,         NULL },
        { "examine",    db_examine_cmd,         CS_SET_DOT,     NULL },
        { "x",          db_examine_cmd,         CS_SET_DOT,     NULL },
diff --git sys/ddb/db_examine.c sys/ddb/db_examine.c
index d8fec8219f1..1f2ec716e29 100644
--- sys/ddb/db_examine.c
+++ sys/ddb/db_examine.c
@@ -245,10 +245,61 @@ void
 db_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
 {
        db_expr_t       value;
+       char            _modif[TOK_STRING_SIZE];
+       char            tmptok[TOK_STRING_SIZE];
        char            tmpfmt[28];
+       char            *s;
+       int             i, t;
 
-       if (modif[0] != '\0')
-               db_print_format = modif[0];
+       t = db_read_token();
+
+       /* check for modifier */
+       if (t == tSLASH) {
+               t = db_read_token();
+               if (t != tIDENT) {
+                       db_printf("\nBad modifier\n");
+                       db_flush_lex();
+                       return;
+               }
+               db_strlcpy(_modif, db_tok_string, sizeof(_modif));
+               if (_modif[0] != '\0')
+                       db_print_format = _modif[0];
+               t = db_read_token();
+       }
+
+_inp_loop:
+       if (t == tDITTO) {
+               t = db_read_token();
+               db_strlcpy(tmptok, db_tok_string, sizeof(tmptok));
+               t = db_read_token();
+               if (t != tDITTO) {
+                       db_printf("\nBad string, missing \"\n");
+                       db_flush_lex();
+                       return;
+               }
+               s = db_tok_string;
+               for (i = 0; i < TOK_STRING_SIZE && s[i] != '\0'; i++) {
+                       if (i < (TOK_STRING_SIZE - 1) && s[i] == '\\') {
+                               switch (s[++i]) {
+                               case 'n':
+                                       db_putchar('\n');
+                                       continue;
+                               case 't':
+                                       db_putchar('\t');
+                                       continue;
+                               }
+                       }
+                       db_putchar(s[i]);
+               }
+               goto _next_token;
+       } else
+               db_unread_token(t);
+
+       if (db_expression(&addr)) {
+               db_dot = (db_addr_t) addr;
+               db_last_addr = db_dot;
+       } else
+               addr = (db_expr_t) db_dot;
 
        switch (db_print_format) {
        case 'a':
@@ -282,6 +333,12 @@ db_print_cmd(db_expr_t addr, int have_addr, db_expr_t 
count, char *modif)
                        db_printf("\\%03o", (int)value);
                break;
        }
+
+_next_token:
+       t = db_read_token();
+       if (t != tEOL)
+               goto _inp_loop;
+
        db_printf("\n");
 }
 

Reply via email to