On Wed, May 09, 2018 at 11:35:42AM +0200, Martin Pieuchot wrote:
> On 09/05/18(Wed) 12:13, Artturi Alm wrote:
> > On Wed, May 09, 2018 at 10:23:41AM +0200, Martin Pieuchot wrote:
> > > On 09/05/18(Wed) 07:48, Artturi Alm wrote:
> > > > On Tue, May 08, 2018 at 01:44:39AM +0300, Artturi Alm wrote:
> > >
> > >
> > > No bug are irrelevant to fix. But working with you is hard, really
> > > hard. You never explain what the problem is. Reading your email is
> > > an exercise in frustration because you can do some good work but you
> > > fail to communicate.
> > >
> > > > > (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.
> > >
> > > What do no work? What does the man page describe? Do you expect us to
> > > read the man page, then look at your mail again, then try to understand
> > > what is not working?
> > >
> >
> > For example,
> >
> > print/x "eax = " $eax "\necx = " $ecx "\n"
> >
> > will print something like this:
> >
> > eax = xxxxxx
> > ecx = yyyyyy
> >
> > Now I did install 5.0 into a VM, and there the result for above example
> > would of have been just "Ambiguous", and I'm guessing now that this
> > has not been working as in the example since import.
> > My fix is limited to producing output just like in the example, but
> > input requires more, as it needs escapes for everything not a-z,A-Z,0-9.
> >
> > > > > Should it work? I hope it would.
> > >
> > > What should work? Why do you hope? Maybe the manpage should be fixed?
> > >
> >
> > Multiple [addr] arguments to p[rint], including support for strings,
> > and i hope so because i would find it useful while testing/writing/porting
> > drivers. Maybe, I do like "show struct", and have more than just
> > the filtering diff for it, but it doesn't really work for the ad hoc
> > usecases p[rint] seems so excellent for.
> >
> > > > 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.
> > >
> > > Like I said, no bug are irrelevant but if the one finding the bug, you
> > > in that case, is not willing to properly explain the problem, then
> > > better not send an email at all ;)
> >
> > Will try in the future.
>
> Thanks for the explanation!
>
> > haven't tested the diff below yet, but compared to previous, it should
> > have working /modifierS.
>
> IMHO we should just amend the man page and keep ddb(4) code simple.
Well, that's what I was expecting. I still think even the multiple args
support should be fixed before the man page is updated to match reality,
which i think is better dealt by someone with better english too.
As an example I think the possibility to give another user instructions
remotely for:
"p /xxxu $base $roff $shft (*($base+$roff))>>$shft"
vs.
"p /x $base
p $off
p $shft
p /u (*($base+$off))>>$shft"
alone is enough to outweight the added code, but that's just my opinion.
The string support is indeed questionable, given:
#define DB_LINE_MAXLEN 120
diff below just as an lazybackup, not what i pushed to my swiss-army-debug
branch, and with dubious aim at keeping the diff with max two --, for easy
'rebase' in the future if i ever loose the branches i have it in.
-Artturi
sys/ddb/db_command.c | 4 +--
sys/ddb/db_examine.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 2 deletions(-)
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..d50039d7779 100644
--- sys/ddb/db_examine.c
+++ sys/ddb/db_examine.c
@@ -46,6 +46,7 @@
char db_examine_format[TOK_STRING_SIZE] = "x";
void db_examine(db_addr_t, char *, int);
+void db_print_cmd_value(db_expr_t, db_expr_t);
void db_search(db_addr_t, int, db_expr_t, db_expr_t, db_expr_t);
/*
@@ -237,8 +238,21 @@ db_examine(db_addr_t addr, char *fmt, int count)
/*
* Print value.
+ * Syntax is:
+ * p/[acdoruxz]*
+ *
+ * Where * can be values (expressions), or literal "string"s.
+ * Strings do not consume modifiers(format).
+ *
+ * For example, the command:
+ * p/xux "log\\t\=" $log "\\n\\t\=" $radix "\\nexpr\\t\=" ($radix-1)<<$log
+ * should print:
+ * log = 1
+ * = 16
+ * expr = 1e
*/
char db_print_format = 'x';
+char db__print_format[TOK_STRING_SIZE] = "x";
/*ARGSUSED*/
void
@@ -246,9 +260,83 @@ db_print_cmd(db_expr_t addr, int have_addr, db_expr_t
count, char *modif)
{
db_expr_t value;
char tmpfmt[28];
+ char *s;
+ int i, m, t;
+ /* check input for modifiers */
+ t = db_read_token();
+ if (t == tSLASH) {
+ t = db_read_token();
+ if (t != tIDENT) {
+ db_printf("\nBad modifier\n");
+ db_flush_lex();
+ return;
+ }
+ db_strlcpy(db__print_format, db_tok_string,
+ sizeof(db__print_format));
+ /* read next token, to match the else{}-path of this if(){} */
+ t = db_read_token();
+ }
+ /* default to old/default modifiers */
+ modif = &db__print_format[(m = 0)];
if (modif[0] != '\0')
db_print_format = modif[0];
+ /* default to printing a newline in db_print_cmd_value() */
+ value = 0; /* if we print any strings, we'll change this to 1 */
+ do {
+ if (t != tDITTO) { /* [addr] */
+ /* put back the token, for later db_expression() */
+ db_unread_token(t);
+ db_print_cmd_value(addr, value);
+ /* update modifier for the next value */
+ if (db__print_format[m + 1] != '\0')
+ m++;
+ db_print_format = db__print_format[m];
+ } else { /* literal "string" */
+ /* read+copy the string token */
+ t = db_read_token();
+ db_strlcpy(tmpfmt, db_tok_string, sizeof(tmpfmt));
+ /* check for a closing " */
+ t = db_read_token();
+ if (t != tDITTO) {
+ db_printf("\nBad string, missing \"\n");
+ db_flush_lex();
+ return;
+ }
+ /* print the string while dealing with escapes */
+ s = tmpfmt;
+ value = TOK_STRING_SIZE;
+ 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]);
+ }
+ /* we've had an "string", so.. */
+ value = 1; /* ..the user is in charge of "\n" */
+ }
+ } while ((t = db_read_token()) != tEOL);
+}
+
+void
+db_print_cmd_value(db_expr_t addr, db_expr_t no_newline)
+{
+ db_expr_t value;
+ char tmpfmt[28];
+
+ 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 +370,8 @@ db_print_cmd(db_expr_t addr, int have_addr, db_expr_t
count, char *modif)
db_printf("\\%03o", (int)value);
break;
}
+ if (no_newline)
+ return;
db_printf("\n");
}