Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh The beginnings of the great shell DEBUG (tracing) upg...



details:   https://anonhg.NetBSD.org/src/rev/55f35182ffbf
branches:  trunk
changeset: 823883:55f35182ffbf
user:      kre <kre%NetBSD.org@localhost>
date:      Sat May 13 03:26:03 2017 +0000

description:
The beginnings of the great shell DEBUG (tracing) upgrade of 2017...

First, be aware that the DEBUG spoken of here has nothing whatever to
do with MKDEBUG=true type builds of NetBSD.   The only way to get a
DEBUG shell is to build it yourself manually.

That said, for non-DEBUG shells, this change makes only one slight
(trivial really) difference, which should affect nothing.

Previously some code was defined like ...

function(args)
{
#ifdef DEBUG
        /* function code goes here */
#endif
}

and called like ...

#ifdef DEBUG
        function(params);
#endif

resulting in several empty functions that are never called being
defined in non-DEBUG shells.   Those are now gone.   If you can detect
the difference any way other than using "nm" or similar, I'd be very
surprised...

For DEBUG shells, this introduces a whole new TRACE() setup to use
to assist in debugging the shell.

I have had this locally (uncommitted) for over a year...  it helps.

By itself this change is almost useless, nothing really changes, but
it provides the framework to allow other TRACE() calls to be updated
over time.   This is why I had not committed this earlier, my previous
version required a flag day, with all the shell's internal tracing
being updated a once - which I had done, but that shell version has
bit-rotted so badly now it is almost useless...

Future updates will add the mechanism to allow the new stuff to actually
be used in a productive way, and following that, over time, gradual
conversion of all the shell tracing to the updated form (as required,
or when I am bored...)

The one useful change that we do get now is that the fd that the shell
uses for tracing (which was usually 3, but not any more) is now protected
from user/script interference, like all the other shell inernal fds.

There is no doc (nor will there be) on any of this, if you are not reading
the source code it is useless to you, if you are, you know how it works.

diffstat:

 bin/sh/eval.c  |     8 +-
 bin/sh/shell.h |   144 +++++-
 bin/sh/show.c  |  1297 ++++++++++++++++++++++++++++++++++++++-----------------
 bin/sh/show.h  |     4 +-
 4 files changed, 1032 insertions(+), 421 deletions(-)

diffs (truncated from 1645 to 300 lines):

diff -r e3f926bd977f -r 55f35182ffbf bin/sh/eval.c
--- a/bin/sh/eval.c     Sat May 13 02:58:03 2017 +0000
+++ b/bin/sh/eval.c     Sat May 13 03:26:03 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.139 2017/05/09 05:14:03 kre Exp $   */
+/*     $NetBSD: eval.c,v 1.140 2017/05/13 03:26:03 kre 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.139 2017/05/09 05:14:03 kre Exp $");
+__RCSID("$NetBSD: eval.c,v 1.140 2017/05/13 03:26:03 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -931,6 +931,7 @@
                        savelocalvars = localvars;
                        localvars = NULL;
                        vforked = 1;
+       VFORK_BLOCK
                        switch (pid = vfork()) {
                        case -1:
                                serrno = errno;
@@ -942,6 +943,7 @@
                                /* Make sure that exceptions only unwind to
                                 * after the vfork(2)
                                 */
+                               SHELL_FORKED();
                                if (setjmp(jmploc.loc)) {
                                        if (exception == EXSHELLPROC) {
                                                /* We can't progress with the vfork,
@@ -960,6 +962,7 @@
                                forkchild(jp, cmd, mode, vforked);
                                break;
                        default:
+                               VFORK_UNDO();
                                handler = savehandler;  /* restore from vfork(2) */
                                poplocalvars();
                                localvars = savelocalvars;
@@ -974,6 +977,7 @@
                                forkparent(jp, cmd, mode, pid);
                                goto parent;
                        }
+       VFORK_END
                } else {
 normal_fork:
 #endif
diff -r e3f926bd977f -r 55f35182ffbf bin/sh/shell.h
--- a/bin/sh/shell.h    Sat May 13 02:58:03 2017 +0000
+++ b/bin/sh/shell.h    Sat May 13 03:26:03 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: shell.h,v 1.20 2017/03/21 10:52:46 joerg Exp $ */
+/*     $NetBSD: shell.h,v 1.21 2017/05/13 03:26:03 kre Exp $   */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,6 @@
 /*
  * The follow should be set to reflect the type of system you have:
  *     JOBS -> 1 if you have Berkeley job control, 0 otherwise.
- *     SHORTNAMES -> 1 if your linker cannot handle long names.
  *     define BSD if you are running 4.2 BSD or later.
  *     define SYSV if you are running under System V.
  *     define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
@@ -59,7 +58,7 @@
 #endif
 
 #ifndef DO_SHAREDVFORK
-#if __NetBSD_Version__ >= 104000000
+#if defined(__NetBSD_Version__) &&  __NetBSD_Version__ >= 104000000
 #define DO_SHAREDVFORK
 #endif
 #endif
@@ -77,13 +76,140 @@
 
 extern const char nullstr[1];          /* null string */
 
+#ifdef SMALL
+#undef DEBUG
+#endif
 
 #ifdef DEBUG
-#define TRACE(param)   trace param
-#define TRACEV(param)  tracev param
-#else
-#define TRACE(param)
-#define TRACEV(param)
-#endif
+
+extern uint64_t        DFlags;
+extern int             ShNest;
+
+/*
+ * This is selected as there are 26 letters in ascii - not that that
+ * matters for anything, just makes it easier to assign a different
+ * command letter to each debug option.  We currently use only 18
+ * so this could be reduced, but that is of no real benefit.  It can also
+ * be increased, but that both limits the maximum value tha can be
+ * used with DBG_EXTRAS(), and causes problems with verbose option naming.
+ */
+#define        DBG_VBOSE_SHIFT         26
+#define        DBG_EXTRAS(n)   ((DBG_VBOSE_SHIFT * 2) + (n))
+
+/*
+ * Unconditional tracing for compatibility with old tracing setup.
+ */
+#define TRACE(param)           do {                                    \
+                                       trace param;                    \
+                               } while (/*CONSTCOND*/ 0)
+#define TRACEV(param)          do {                                    \
+                                       tracev param;                   \
+                               } while (/*CONSTCOND*/ 0)
+
+/*
+ * and the newer conditional tracing, so the mainainer can control
+ * just how much debug output is dumped to the trace file
+ * (once the rest of the shell is converted to use it).
+ *
+ * in the X forms, "xtra" can be any legal C statement(s) without (bare) commas
+ * executed if the relevant debug flag is enabled, after any tracing output.
+ */
+#define CTRACE(when, param)    do {                                    \
+                                   if ((DFlags & (when)) != 0)         \
+                                       trace param;                    \
+                               } while (/*CONSTCOND*/ 0)
+
+#define CTRACEV(when, param)   do {                                    \
+                                   if ((DFlags & (when)) != 0)         \
+                                       tracev param;                   \
+                               } while (/*CONSTCOND*/ 0)
+
+#define XTRACE(when, param, xtra) do {                                 \
+                                   if ((DFlags & (when)) != 0) {       \
+                                       trace param;                    \
+                                       xtra;                           \
+                                   }                                   \
+                               } while (/*CONSTCOND*/ 0)
+
+#define VTRACE(when, param)    do {                                    \
+                                   if ((DFlags &                       \
+                                       (when)<<DBG_VBOSE_SHIFT) != 0)  \
+                                           trace param;                \
+                               } while (/*CONSTCOND*/ 0)
+
+#define VTRACEV(when, param)   do {                                    \
+                                   if ((DFlags &                       \
+                                       (when)<<DBG_VBOSE_SHIFT) != 0)  \
+                                           tracev param;               \
+                               } while (/*CONSTCOND*/ 0)
+
+#define VXTRACE(when, param, xtra) do {                                        \
+                                   if ((DFlags &                       \
+                                       (when)<<DBG_VBOSE_SHIFT) != 0) {\
+                                           trace param;                \
+                                           xtra;                       \
+                                   }                                   \
+                               } while (/*CONSTCOND*/ 0)
+
+#define SHELL_FORKED() ShNest++
+#define VFORK_BLOCK    { const int _ShNest = ShNest;
+#define VFORK_END      }
+#define VFORK_UNDO()   ShNest = _ShNest
+
+#define        DBG_ALWAYS      (1LL << 0)
+#define        DBG_PARSE       (1LL << 1)              /* r (read commands) */
+#define        DBG_EVAL        (1LL << 2)              /* e */
+#define        DBG_EXPAND      (1LL << 3)              /* x */
+#define        DBG_JOBS        (1LL << 4)              /* j */
+#define        DBG_PROCS       (1LL << 5)              /* p */
+#define        DBG_REDIR       (1LL << 6)              /* f (fds) */
+#define        DBG_CMDS        (1LL << 7)              /* c */
+#define        DBG_ERRS        (1LL << 8)              /* z (?) */
+#define        DBG_WAIT        (1LL << 9)              /* w */
+#define        DBG_TRAP        (1LL << 10)             /* t */
+#define        DBG_VARS        (1LL << 11)             /* v */
+#define        DBG_INPUT       (1LL << 12)             /* i */
+#define        DBG_OUTPUT      (1LL << 13)             /* o */
+#define        DBG_MEM         (1LL << 14)             /* m */
+#define        DBG_ARITH       (1LL << 15)             /* a */
+#define        DBG_HISTORY     (1LL << 16)             /* h */
+#define        DBG_SIG         (1LL << 17)             /* s */
+
+/*
+ * reserved extras: b=builtins l=alias
+ * still free:  d g k n q s u y
+ */
+
+       /* use VTRACE(DBG_ALWAYS, (...)) to test this one */
+#define        DBG_VERBOSE     (1LL << DBG_VBOSE_SHIFT)
+
+       /* DBG_EXTRAS 0 .. 11 (max) only  - non-alpha options (no VTRACE !!) */
+#define        DBG_U0          (1LL << DBG_EXTRAS(0))  /* 0 - ad-hoc extra flags */
+#define        DBG_U1          (1LL << DBG_EXTRAS(1))  /* 1 - for short term */
+#define        DBG_U2          (1LL << DBG_EXTRAS(2))  /* 2 - extra tracing*/
+
+#define        DBG_PID         (1LL << DBG_EXTRAS(10)) /* $ ($$) */
+#define        DBG_NEST        (1LL << DBG_EXTRAS(11)) /* ^ */
+
+extern void set_debug(const char *, int);
+
+#else  /* DEBUG */
+
+#define TRACE(param)                   /* historic normal trace */
+#define TRACEV(param)                  /* historic varargs trace */
+
+#define CTRACE(when, param)            /* conditional normal trace */
+#define CTRACEV(when, param)           /* conditional varargs trace */
+#define XTRACE(when, param, extra)     /* conditional trace, plus more */
+#define VTRACE(when, param)            /* conditional verbose trace */
+#define VTRACEV(when, param)           /* conditional verbose varargs trace */
+#define VXTRACE(when, param, extra)    /* cond verbose trace, plus more */
+
+#define SHELL_FORKED()
+#define VFORK_BLOCK
+#define VFORK_END
+#define VFORK_UNDO()
+
+#endif /* DEBUG */
 
 #endif /* SHELL_H */
diff -r e3f926bd977f -r 55f35182ffbf bin/sh/show.c
--- a/bin/sh/show.c     Sat May 13 02:58:03 2017 +0000
+++ b/bin/sh/show.c     Sat May 13 03:26:03 2017 +0000
@@ -1,9 +1,11 @@
-/*     $NetBSD: show.c,v 1.38 2017/05/09 05:14:03 kre Exp $    */
+/*     $NetBSD: show.c,v 1.39 2017/05/13 03:26:03 kre Exp $    */
 
 /*-
  * Copyright (c) 1991, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.  All rights reserved.
+ *
  * This code is derived from software contributed to Berkeley by
  * Kenneth Almquist.
  *
@@ -37,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)show.c     8.3 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: show.c,v 1.38 2017/05/09 05:14:03 kre Exp $");
+__RCSID("$NetBSD: show.c,v 1.39 2017/05/13 03:26:03 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -45,6 +47,11 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/uio.h>
 
 #include "shell.h"
 #include "parser.h"
@@ -52,402 +59,911 @@
 #include "mystring.h"
 #include "show.h"
 #include "options.h"
-#ifndef SMALL
-#define DEFINE_NODENAMES
-#include "nodenames.h"
+#include "redir.h"
+#include "error.h"
+
+#if defined(DEBUG) && !defined(DBG_PID)
+/*
+ * If this is compiled, it means this is being compiled in a shell that still
+ * has an older shell.h (a simpler TRACE() mechanism than is coming soon.)
+ *
+ * Compensate for as much of that as is missing and is needed here
+ * to compile and operate at all.   After the other changes have appeared,
+ * this little block can (and should be) deleted (sometime).
+ *
+ * Try to avoid waiting 22 years...
+ */
+#define        DBG_PID         1
+#define        DBG_NEST        2
 #endif
 
-
-FILE *tracefile;
-
-#ifdef DEBUG
-static int shtree(union node *, int, int, char *, FILE*);
-static int shcmd(union node *, FILE *);
-static int shsubsh(union node *, FILE *);
-static int shredir(union node *, FILE *, int);
-static int sharg(union node *, FILE *);
-static int indent(int, char *, FILE *);
-static void trstring(char *);
-
-void
-showtree(union node *n)
-{



Home | Main Index | Thread Index | Old Index