From bc8cfb7d77cfd239f48ab8251afcb72ef41624e1 Mon Sep 17 00:00:00 2001 From: christos Date: Sat, 27 Feb 2016 18:34:12 +0000 Subject: [PATCH] Improve debugging, from kre (I hooked it to the build). --- bin/sh/Makefile | 8 +- bin/sh/eval.c | 21 +++++- bin/sh/main.c | 5 +- bin/sh/mknodenames.sh | 17 ++++- bin/sh/show.c | 172 ++++++++++++++++++++++++++++-------------- 5 files changed, 157 insertions(+), 66 deletions(-) diff --git a/bin/sh/Makefile b/bin/sh/Makefile index 067bdb079497..4af9dd410b3f 100644 --- a/bin/sh/Makefile +++ b/bin/sh/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.101 2015/05/10 20:30:54 joerg Exp $ +# $NetBSD: Makefile,v 1.102 2016/02/27 18:34:12 christos Exp $ # @(#)Makefile 8.4 (Berkeley) 5/5/95 .include @@ -10,7 +10,7 @@ SHSRCS= alias.c cd.c echo.c error.c eval.c exec.c expand.c \ mystring.c options.c parser.c redir.c show.c trap.c output.c var.c \ test.c kill.c syntax.c GENSRCS=arith.c arith_lex.c builtins.c init.c nodes.c -GENHDRS=arith.h builtins.h nodes.h token.h +GENHDRS=arith.h builtins.h nodes.h token.h nodenames.h SRCS= ${SHSRCS} ${GENSRCS} DPSRCS+=${GENHDRS} @@ -76,6 +76,10 @@ nodes.c nodes.h: mknodes.sh nodetypes nodes.c.pat ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.OBJDIR} [ -f nodes.h ] +nodenames.h: mknodenames.sh nodes.h + ${_MKTARGET_CREATE} + ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} > ${.TARGET} + .if ${USETOOLS} == "yes" NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat .endif diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 43988cecf96c..0539dacf8f99 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -1,4 +1,4 @@ -/* $NetBSD: eval.c,v 1.113 2016/02/24 14:57:12 christos Exp $ */ +/* $NetBSD: eval.c,v 1.114 2016/02/27 18:34:12 christos Exp $ */ /*- * Copyright (c) 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; #else -__RCSID("$NetBSD: eval.c,v 1.113 2016/02/24 14:57:12 christos Exp $"); +__RCSID("$NetBSD: eval.c,v 1.114 2016/02/27 18:34:12 christos Exp $"); #endif #endif /* not lint */ @@ -80,6 +80,7 @@ __RCSID("$NetBSD: eval.c,v 1.113 2016/02/24 14:57:12 christos Exp $"); #include "mystring.h" #include "main.h" #ifndef SMALL +#include "nodenames.h" #include "myhistedit.h" #endif @@ -220,6 +221,7 @@ evalstring(char *s, int flag) setinputstring(s, 1); while ((n = parsecmd(0)) != NEOF) { + TRACE(("evalstring: "); showtree(n)); if (nflag == 0) evaltree(n, flag); popstackmark(&smark); @@ -249,8 +251,13 @@ evaltree(union node *n, int flags) #ifndef SMALL displayhist = 1; /* show history substitutions done with fc */ #endif +#ifdef NODETYPENAME + TRACE(("pid %d, evaltree(%p: %s(%d), %d) called\n", + getpid(), n, NODETYPENAME(n->type), n->type, flags)); +#else TRACE(("pid %d, evaltree(%p: %d, %d) called\n", getpid(), n, n->type, flags)); +#endif switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, flags & EV_TESTED); @@ -341,6 +348,16 @@ evalloop(union node *n, int flags) loopnest++; status = 0; + +#ifdef NODETYPENAME + TRACE(("evalloop %s: ", NODETYPENAME(n->type))); +#else + TRACE(("evalloop %s: ", n->type == NWHILE ? "while" : "until")); +#endif + TRACE((""); showtree(n->nbinary.ch1)); + TRACE(("evalloop do: "); showtree(n->nbinary.ch2)); + TRACE(("evalloop done\n")); + for (;;) { evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip) { diff --git a/bin/sh/main.c b/bin/sh/main.c index 819a745756bf..69634309b81f 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $ */ +/* $NetBSD: main.c,v 1.60 2016/02/27 18:34:12 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993\ #if 0 static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; #else -__RCSID("$NetBSD: main.c,v 1.59 2015/05/26 21:35:15 christos Exp $"); +__RCSID("$NetBSD: main.c,v 1.60 2016/02/27 18:34:12 christos Exp $"); #endif #endif /* not lint */ @@ -270,6 +270,7 @@ cmdloop(int top) flushout(&errout); } n = parsecmd(inter); + TRACE(("cmdloop: "); showtree(n)); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) diff --git a/bin/sh/mknodenames.sh b/bin/sh/mknodenames.sh index b16e0cb7fda6..e6cdb941ab08 100755 --- a/bin/sh/mknodenames.sh +++ b/bin/sh/mknodenames.sh @@ -1,6 +1,13 @@ #! /bin/sh -test -t 1 && test "$#" -eq 0 && exec > nodenames.h +if [ -z "$1" ]; then + echo "Usage: $0 nodes.h" 1>&2 + exit 1 +fi + +NODES=$1 + +test -t 1 && exec > nodenames.h echo "#ifdef DEBUG" echo ' @@ -10,7 +17,7 @@ echo ' */ ' -MAX=$(awk < nodes.h ' +MAX=$(awk < "$NODES" ' /#define/ { if ($3 > MAX) MAX = $3 } @@ -18,9 +25,10 @@ MAX=$(awk < nodes.h ' ') echo +echo '#ifdef DEFINE_NODENAMES' echo "STATIC const char * const NodeNames[${MAX} + 1] = {" -grep '^#define' nodes.h | sort -k2n | while read define name number opt_comment +grep '^#define' "$NODES" | sort -k2n | while read define name number opt_comment do : ${next:=0} while [ "$number" -gt "$next" ] @@ -33,6 +41,9 @@ do done echo "};" +echo '#else' +echo "extern const char * const NodeNames[${MAX} + 1];" +echo '#endif' echo echo '#define NODETYPENAME(type) \' echo ' ((unsigned)(type) <= '"${MAX}"' ? NodeNames[(type)] : "??OOR??")' diff --git a/bin/sh/show.c b/bin/sh/show.c index 9c008715dc2a..45154145f587 100644 --- a/bin/sh/show.c +++ b/bin/sh/show.c @@ -1,4 +1,4 @@ -/* $NetBSD: show.c,v 1.28 2011/08/23 10:01:32 christos Exp $ */ +/* $NetBSD: show.c,v 1.29 2016/02/27 18:34:12 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: show.c,v 1.28 2011/08/23 10:01:32 christos Exp $"); +__RCSID("$NetBSD: show.c,v 1.29 2016/02/27 18:34:12 christos Exp $"); #endif #endif /* not lint */ @@ -54,124 +54,160 @@ __RCSID("$NetBSD: show.c,v 1.28 2011/08/23 10:01:32 christos Exp $"); #include "options.h" -#ifdef DEBUG -static void shtree(union node *, int, char *, FILE*); -static void shcmd(union node *, FILE *); -static void sharg(union node *, FILE *); -static void indent(int, char *, FILE *); -static void trstring(char *); +FILE *tracefile; +#ifdef DEBUG +static int shtree(union node *, int, int, char *, FILE*); +static int shcmd(union node *, FILE *); +static int sharg(union node *, FILE *); +static int indent(int, char *, FILE *); +static void trstring(char *); void showtree(union node *n) { - trputs("showtree called\n"); - shtree(n, 1, NULL, stdout); + FILE *fp; + + fp = tracefile ? tracefile : stdout; + + trputs("showtree("); + if (n == NULL) + trputs("NULL"); + else if (n == NEOF) + trputs("NEOF"); + trputs(") called\n"); + if (n != NULL && n != NEOF) + shtree(n, 1, 1, NULL, fp); } -static void -shtree(union node *n, int ind, char *pfx, FILE *fp) +static int +shtree(union node *n, int ind, int nl, char *pfx, FILE *fp) { struct nodelist *lp; const char *s; + int len; - if (n == NULL) - return; + if (n == NULL) { + if (nl) + fputc('\n', fp); + return 0; + } - indent(ind, pfx, fp); - switch(n->type) { + len = indent(ind, pfx, fp); + switch (n->type) { case NSEMI: s = "; "; + len += 2; goto binop; case NAND: s = " && "; + len += 4; goto binop; case NOR: s = " || "; + len += 4; binop: - shtree(n->nbinary.ch1, ind, NULL, fp); - /* if (ind < 0) */ - fputs(s, fp); - shtree(n->nbinary.ch2, ind, NULL, fp); + len += shtree(n->nbinary.ch1, 0, 0, NULL, fp); + fputs(s, fp); + if (len >= 60) { + putc('\n', fp); + len = indent(ind < 0 ? 2 : ind + 1, pfx, fp); + } + len += shtree(n->nbinary.ch2, 0, nl, NULL, fp); break; case NCMD: - shcmd(n, fp); - if (ind >= 0) - putc('\n', fp); + len += shcmd(n, fp); + if (nl) + len = 0, putc('\n', fp); break; case NPIPE: for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { - shcmd(lp->n, fp); - if (lp->next) - fputs(" | ", fp); + len += shcmd(lp->n, fp); + if (lp->next) { + len += 3, fputs(" | ", fp); + if (len >= 60) { + fputc('\n', fp); + len = indent(ind < 0 ? 2 : ind + 1, + pfx, fp); + } + } } if (n->npipe.backgnd) - fputs(" &", fp); - if (ind >= 0) - putc('\n', fp); + len += 2, fputs(" &", fp); + if (nl || len >= 60) + len = 0, fputc('\n', fp); break; default: - fprintf(fp, "", n->type); - if (ind >= 0) - putc('\n', fp); +#ifdef NODETYPENAME + len += fprintf(fp, "", n->type, + NODETYPENAME(n->type)); +#else + len += fprintf(fp, "", n->type); +#endif + if (nl) + len = 0, putc('\n', fp); break; } + return len; } -static void +static int shcmd(union node *cmd, FILE *fp) { union node *np; int first; const char *s; int dftfd; + int len = 0; first = 1; for (np = cmd->ncmd.args ; np ; np = np->narg.next) { if (! first) - putchar(' '); - sharg(np, fp); + len++, fputc(' ', fp); + len += sharg(np, fp); first = 0; } for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { if (! first) - putchar(' '); + len++, fputc(' ', fp); switch (np->nfile.type) { - case NTO: s = ">"; dftfd = 1; break; - case NCLOBBER: s = ">|"; dftfd = 1; break; - case NAPPEND: s = ">>"; dftfd = 1; break; - case NTOFD: s = ">&"; dftfd = 1; break; - case NFROM: s = "<"; dftfd = 0; break; - case NFROMFD: s = "<&"; dftfd = 0; break; - case NFROMTO: s = "<>"; dftfd = 0; break; - default: s = "*error*"; dftfd = 0; break; + case NTO: s = ">"; dftfd = 1; len += 1; break; + case NCLOBBER: s = ">|"; dftfd = 1; len += 2; break; + case NAPPEND: s = ">>"; dftfd = 1; len += 2; break; + case NTOFD: s = ">&"; dftfd = 1; len += 2; break; + case NFROM: s = "<"; dftfd = 0; len += 1; break; + case NFROMFD: s = "<&"; dftfd = 0; len += 2; break; + case NFROMTO: s = "<>"; dftfd = 0; len += 2; break; + default: s = "*error*"; dftfd = 0; len += 7; break; } if (np->nfile.fd != dftfd) - fprintf(fp, "%d", np->nfile.fd); + len += fprintf(fp, "%d", np->nfile.fd); fputs(s, fp); if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { - fprintf(fp, "%d", np->ndup.dupfd); + len += fprintf(fp, "%d", np->ndup.dupfd); } else { - sharg(np->nfile.fname, fp); + len += sharg(np->nfile.fname, fp); } first = 0; } + return len; } -static void +static int sharg(union node *arg, FILE *fp) { char *p; struct nodelist *bqlist; int subtype; + int len = 0; if (arg->type != NARG) { - printf("\n", arg->type); + fprintf(fp, "\n", arg->type); abort(); } bqlist = arg->narg.backquote; @@ -179,84 +215,107 @@ sharg(union node *arg, FILE *fp) switch (*p) { case CTLESC: putc(*++p, fp); + len++; break; case CTLVAR: putc('$', fp); putc('{', fp); + len += 2; subtype = *++p; if (subtype == VSLENGTH) - putc('#', fp); + len++, putc('#', fp); - while (*p != '=') - putc(*p++, fp); + while (*++p != '=') + len++, putc(*p, fp); if (subtype & VSNUL) - putc(':', fp); + len++, putc(':', fp); switch (subtype & VSTYPE) { case VSNORMAL: putc('}', fp); + len++; break; case VSMINUS: putc('-', fp); + len++; break; case VSPLUS: putc('+', fp); + len++; break; case VSQUESTION: putc('?', fp); + len++; break; case VSASSIGN: putc('=', fp); + len++; break; case VSTRIMLEFT: putc('#', fp); + len++; break; case VSTRIMLEFTMAX: putc('#', fp); putc('#', fp); + len += 2; break; case VSTRIMRIGHT: putc('%', fp); + len++; break; case VSTRIMRIGHTMAX: putc('%', fp); putc('%', fp); + len += 2; break; case VSLENGTH: break; default: - printf("", subtype); + len += fprintf(fp, "", subtype); } break; case CTLENDVAR: putc('}', fp); + len++; break; case CTLBACKQ: case CTLBACKQ|CTLQUOTE: putc('$', fp); putc('(', fp); - shtree(bqlist->n, -1, NULL, fp); + len += shtree(bqlist->n, -1, 0, NULL, fp) + 3; putc(')', fp); break; default: putc(*p, fp); + len++; break; } } + return len; } -static void +static int indent(int amount, char *pfx, FILE *fp) { int i; + int len = 0; + /* + * in practice, pfx is **always** NULL + * but here, we assume if it were not, at least strlen(pfx) < 8 + * if that is invalid, output will look messy + */ for (i = 0 ; i < amount ; i++) { if (pfx && i == amount - 1) fputs(pfx, fp); putc('\t', fp); + len |= 7; + len++; } + return len; } #endif @@ -267,7 +326,6 @@ indent(int amount, char *pfx, FILE *fp) */ -FILE *tracefile; #ifdef DEBUG