[net.sources] dbug documentation

fnf@unisoft.UUCP (Fred Fish) (01/09/85)

[ is this bug *REALLY* dead? :-} ]

Apparently many recipients of the dbug package did not have
access to the "mm" macros so were unable to recreate the
dbug documentation.  This posting contains an nroff'd version
that should be suitable for printing on most decwriter style
printers.  I have verified that it makes it though "sh" intact
but can't vouch for any mangling by the net mail programs.
It may require slight hand modification prior to printing.

P.S.  If you are actually using this stuff (and it DOES work)
how about letting me know your impressions, suggestions, etc.
All mail is welcome!

Enjoy

- Fred

#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
#                                                       #
# This is a shell archive file.  To extract files:      #
#                                                       #
#    1)	Make a directory for the files.                 #
#    2) Write a file, such as "file.shar", containing   #
#       this archive file into the directory.           #
#    3) Type "sh file.shar".  Do not use csh.           #
#                                                       #
#########################################################
#
#
echo Extracting user.t:
sed 's/^Z//' >user.t <<\STUNKYFLUFF
Z
Z
Z
Z                                 D B U G
Z
Z                       C Program Debugging Package
Z
Z                                    by
Z
Z                                Fred Fish
Z
Z
Z
Z
Z       IIIINNNNTTTTRRRROOOODDDDUUUUCCCCTTTTIIIIOOOONNNN
Z
Z
Z            Almost every program development environment worthy  of
Z       the  name provides some sort of debugging facility.  Usually
Z       this takes the  form  of  a  program  which  is  capable  of
Z       controlling  execution  of  other programs and examining the
Z       internal state of other executing programs.  These types  of
Z       programs will be referred to as external debuggers since the
Z       debugger is not part of the executing program.  Examples  of
Z       this  type  of  debugger  include  the aaaaddddbbbb and ssssddddbbbb debuggers
Z       provided with the UUUUNNNNIIIIXXXX811119 operating system.
Z
Z
Z            One of the problems associated with developing programs
Z       in  an  environment  with  good  external  debuggers is that
Z       developed programs  tend  to  have  little  or  no  internal
Z       instrumentation.   This  is  usually  not  a problem for the
Z       developer since he is, or at  least  should  be,  intimately
Z       familiar  with  the  internal organization, data structures,
Z       and control flow of the program being  debugged.   It  is  a
Z       serious   problem   for  maintenance  programmers,  who  are
Z       unlikely to have such familiarity  with  the  program  being
Z       maintained,  modified, or ported to another environment.  It
Z       is also a problem, even for the developer, when the  program
Z       is  moved  to  an environment with a primitive or unfamiliar
Z       debugger, or even no debugger.
Z
Z
Z            On the other hand, _d_b_u_g is an example  of  an  internal
Z       debugger.  Because it requires internal instrumentation of a
Z       program, and its  usage  does  not  depend  on  any  special
Z       capabilities  of  the  execution  environment,  it is always
Z       available and will  execute  in  any  environment  that  the
Z       program  itself will execute in.  In addition, since it is a
Z       complete  package  with  a  specific  user  interface,   all
Z       programs   which  use  it  will  be  provided  with  similar
Z       debugging capabilities.  This is in sharp contrast to  other
Z
Z
Z       __________
Z
Z        1. UNIX is a trademark of AT&T Bell Laboratories.
Z
Z
Z
Z
Z                                  - 1 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       forms of internal instrumentation where each  developer  has
Z       their  own, usually less capable, form of internal debugger.
Z       In summary, because _d_b_u_g is an internal debugger it provides
Z       consistency across operating environments, and because it is
Z       available to all developers it provides  consistency  across
Z       all programs in the same environment.
Z
Z
Z            The _d_b_u_g package imposes only a slight speed penalty on
Z       executing programs, typically much less than 10 percent, and
Z       a modest size penalty,  typically  10  to  20  percent.   By
Z       defining  a specific C preprocessor symbol both of these can
Z       be reduced to zero with no changes required  to  the  source
Z       code.
Z
Z
Z            The  following  list  is  a  quick   summary   of   the
Z       capabilities  of  the  _d_b_u_g package.  Each capability can be
Z       individually enabled or disabled at the time  a  program  is
Z       invoked   by   specifying   the   appropriate  command  line
Z       arguments.
Z
Z               o Execution trace  showing  function  level  control
Z                 flow    in   a   semi-graphically   manner   using
Z                 indentation to indicate nesting depth.
Z
Z               o Output the values of all, or any  subset  of,  key
Z                 internal variables.
Z
Z               o Limit  actions  to  a  specific   set   of   named
Z                 functions.
Z
Z               o Limit function trace to a specified nesting depth.
Z
Z               o Label each output line with source file  name  and
Z                 line number.
Z
Z               o Label  each  output  line  with  name  of  current
Z                 process.
Z
Z               o Push or pop  internal  debugging  state  to  allow
Z                 execution with built in debugging defaults.
Z
Z               o Redirect  the  debug  output  stream  to  standard
Z                 output  (stdout)  or  a  named  file.  The default
Z                 output stream is  standard  error  (stderr).   The
Z                 redirection mechanism is completely independent of
Z                 normal command line redirection  to  avoid  output
Z                 conflicts.
Z
Z
Z
Z
Z
Z                                  - 2 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       PPPPRRRRIIIIMMMMIIIITTTTIIIIVVVVEEEE DDDDEEEEBBBBUUUUGGGGGGGGIIIINNNNGGGG TTTTEEEECCCCHHHHNNNNIIIIQQQQUUUUEEEESSSS
Z
Z
Z            Internal instrumentation is already a familiar  concept
Z       to most programmers, since it is usually the first debugging
Z       technique  learned.    Typically,   "print statements"   are
Z       inserted  in the source code at interesting points, the code
Z       is recompiled and executed,  and  the  resulting  output  is
Z       examined in an attempt to determine where the problem is.
Z
Z       The procedure is iterative,  with  each  iteration  yielding
Z       more  and  more  output,  and  hopefully  the  source of the
Z       problem is discovered before the output becomes too large to
Z       deal  with  or  previously  inserted  statements  need to be
Z       removed.  Figure 1 is an example of this type  of  primitive
Z       debugging technique.
Z
Z
Z
Z                 #include <stdio.h>
Z
Z                 main (argc, argv)
Z                 int argc;
Z                 char *argv[];
Z                 {
Z                     printf ("argv[0] = %d\n", argv[0]);
Z                     /*
Z                      *  Rest of program
Z                      */
Z                     printf ("== done ==\n");
Z                 }
Z
Z
Z                                   Figure 1
Z                         Primitive Debugging Technique
Z
Z
Z
Z
Z
Z            Eventually,  and  usually  after   at   least   several
Z       iterations,  the  problem  will  be found and corrected.  At
Z       this point, the newly  inserted  print  statements  must  be
Z       dealt  with.   One obvious solution is to simply delete them
Z       all.  Beginners usually do this a few times until they  have
Z       to  repeat  the entire process every time a new bug pops up.
Z       The second most obvious solution is to somehow  disable  the
Z       output,  either  through  the  source code comment facility,
Z       creation of a debug variable to be switched on or off, or by
Z       using  the  C  preprocessor.   Figure 2 is an example of all
Z       three techniques.
Z
Z
Z
Z                                  - 3 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z
Z
Z                 #include <stdio.h>
Z
Z                 int debug = 0;
Z
Z                 main (argc, argv)
Z                 int argc;
Z                 char *argv[];
Z                 {
Z                     /* printf ("argv = %x\n", argv) */
Z                     if (debug) printf ("argv[0] = %d\n", argv[0]);
Z                     /*
Z                      *  Rest of program
Z                      */
Z                 #ifdef DEBUG
Z                     printf ("== done ==\n");
Z                 #endif
Z                 }
Z
Z
Z                                   Figure 2
Z                           Debug Disable Techniques
Z
Z
Z
Z
Z
Z            Each technique has  its  advantages  and  disadvantages
Z       with  respect  to  dynamic vs static activation, source code
Z       overhead, recompilation requirements, ease of  use,  program
Z       readability,  etc.   Overuse  of  the  preprocessor solution
Z       quickly leads to problems with source code  readability  and
Z       maintainability  when  multiple  ####iiiiffffddddeeeeffff  symbols  are  to be
Z       defined or  undefined  based  on  specific  types  of  debug
Z       desired.  The source code can be made slightly more readable
Z       by suitable indentation of the ####iiiiffffddddeeeeffff arguments to match the
Z       indentation  of  the code, but not all C preprocessors allow
Z       this.   The  only  requirement  for  the  standard  UUUUNNNNIIIIXXXX   C
Z       preprocessor is for the '#' character to appear in the first
Z       column,  but  even  this  seems  like   an   arbitrary   and
Z       unreasonable  restriction.   Figure  3 is an example of this
Z       usage.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 4 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z
Z
Z                 #include <stdio.h>
Z
Z                 main (argc, argv)
Z                 int argc;
Z                 char *argv[];
Z                 {
Z                 #   ifdef DEBUG
Z                     printf ("argv[0] = %d\n", argv[0]);
Z                 #   endif
Z                     /*
Z                      *  Rest of program
Z                      */
Z                 #   ifdef DEBUG
Z                     printf ("== done ==\n");
Z                 #   endif
Z                 }
Z
Z
Z                                   Figure 3
Z                       More Readable Preprocessor Usage
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 5 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       FFFFUUUUNNNNCCCCTTTTIIIIOOOONNNN TTTTRRRRAAAACCCCEEEE EEEEXXXXAAAAMMMMPPPPLLLLEEEE
Z
Z
Z            We will start off learning about  the  capabilities  of
Z       the  _d_b_u_g  package  by  using  a simple minded program which
Z       computes the factorial of a  number.   In  order  to  better
Z       demonstrate  the  function  trace mechanism, this program is
Z       implemented recursively.  Figure 4 is the main function  for
Z       this factorial program.
Z
Z
Z
Z                 #include <stdio.h>
Z                 #include <dbug.h>
Z
Z                 main (argc, argv)
Z                 int argc;
Z                 char *argv[];
Z                 {
Z                     register int flag, result, ix;
Z                     extern int factorial (), atoi ();
Z
Z                     DBUG_ENTER ("main");
Z                     DBUG_PROCESS (argv[0]);
Z                     for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
Z                         switch (argv[ix][1]) {
Z                             case '#':
Z                                 DBUG_PUSH (&(argv[ix][2]));
Z                                 break;
Z                         }
Z                     }
Z                     for (; ix < argc; ix++) {
Z                         DBUG_4 ("args", "argv[%d] = %s", ix, argv[ix]);
Z                         result = factorial (atoi (argv[ix]));
Z                         printf ("%d\n", result);
Z                     }
Z                     DBUG_RETURN (0);
Z                 }
Z
Z
Z                                   Figure 4
Z                          Factorial Program Mainline
Z
Z
Z
Z
Z
Z            The mmmmaaaaiiiinnnn function is  responsible  for  processing  any
Z       command   line  option  arguments  and  then  computing  and
Z       printing the factorial of each non-option argument.
Z
Z
Z
Z
Z                                  - 6 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z            First of all, notice that all of the debugger functions
Z       are  implemented  via  preprocessor  macros.   This does not
Z       detract from the readability of the code and makes disabling
Z       all debug compilation trivial (a single preprocessor symbol,
Z       DDDDBBBBUUUUGGGG____OOOOFFFFFFFF, forces the macro expansions to be null).
Z
Z            Also notice the inclusion of  the  header  file  ddddbbbbuuuugggg....hhhh
Z       from the standard header file directory.  This file contains
Z       all the definitions for the debugger macros, which all  have
Z       the form DDDDBBBBUUUUGGGG____XXXXXXXX............XXXXXXXX.
Z
Z
Z            The DDDDBBBBUUUUGGGG____EEEENNNNTTTTEEEERRRR macro informs that debugger that we have
Z       entered  the function named mmmmaaaaiiiinnnn.  It must be the very first
Z       "executable" line in a function, after all declarations  and
Z       before any other executable line.  The DDDDBBBBUUUUGGGG____PPPPRRRROOOOCCCCEEEESSSSSSSS macro is
Z       generally used only once per program to inform the  debugger
Z       what name the program was invoked with.  The DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH macro
Z       modifies the current debugger state by saving  the  previous
Z       state  and  setting  a new state based on the control string
Z       passed as its argument.  The DDDDBBBBUUUUGGGG____4444 macro is used  to  print
Z       the  values  of each argument for which a factorial is to be
Z       computed.  The DDDDBBBBUUUUGGGG____RRRREEEETTTTUUUURRRRNNNN macro tells the debugger that the
Z       end  of  the current function has been reached and returns a
Z       value to the calling function.  All of these macros will  be
Z       fully explained in subsequent sections.
Z
Z            To use the debugger, the factorial program  is  invoked
Z       with a command line of the form:
Z
Z                          factorial -#d:t 1 2 3
Z
Z       The  mmmmaaaaiiiinnnn  function  recognizes  the  "-#d:t"  string  as  a
Z       debugger  control  string, and passes the debugger arguments
Z       ("d:t")  to  the  _d_b_u_g  runtime  support  routines  via  the
Z       DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH macro.  This particular string enables output from
Z       the DDDDBBBBUUUUGGGG____4444 macro with the  'd'  flag  and  enables  function
Z       tracing  with  the 't' flag.  The factorial function is then
Z       called three times, with the arguments "1", "2", and "3".
Z
Z
Z            Debug control strings consist of a  header,  the  "-#",
Z       followed  by  a  colon separated list of debugger arguments.
Z       Each debugger argument is a single character  flag  followed
Z       by  an optional comma separated list of argments specific to
Z       the given flag.  Some examples are:
Z
Z                          -#d:t:o
Z                          -#d,in,out:f,main:F:L
Z
Z       Note  that  previously  enabled  debugger  actions  can   be
Z
Z
Z
Z                                  - 7 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       disabled by the control string "-#".
Z
Z
Z            The definition of the factorial function, symbolized as
Z       "N!", is given by:
Z
Z                         N! = N * N-1 * ... 2 * 1
Z
Z       Figure 5 is the factorial  function  which  implements  this
Z       algorithm  recursively.   Note  that this is not necessarily
Z       the best way to  do  factorials  and  error  conditions  are
Z       ignored completely.
Z
Z
Z
Z                 #include <stdio.h>
Z                 #include <dbug.h>
Z
Z                 int factorial (value)
Z                 register int value;
Z                 {
Z                     DBUG_ENTER ("factorial");
Z                     DBUG_3 ("find", "find %d factorial", value);
Z                     if (value > 1) {
Z                         value *= factorial (value - 1);
Z                     }
Z                     DBUG_3 ("result", "result is %d", value);
Z                     DBUG_RETURN (value);
Z                 }
Z
Z
Z                                   Figure 5
Z                              Factorial Function
Z
Z
Z
Z
Z
Z            One advantage (some may not consider it  so)  to  using
Z       the  _d_b_u_g  package  is  that  it  strongly  encourages fully
Z       structured coding with only one entry and one exit point  in
Z       each  function.  Multiple exit points, such as early returns
Z       to escape a loop, may be used, but each such point  requires
Z       the  use  of  an appropriate DDDDBBBBUUUUGGGG____RRRREEEETTTTUUUURRRRNNNN or DDDDBBBBUUUUGGGG____VVVVOOOOIIIIDDDD____RRRREEEETTTTUUUURRRRNNNN
Z       macro.
Z
Z
Z            To build  the  factorial  program  on  a  UUUUNNNNIIIIXXXX  system,
Z       compile and link with the command:
Z
Z
Z
Z
Z
Z                                  - 8 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z                cc -o factorial main.c factorial.c -ldbug
Z
Z       The "-ldbug" argument  tells  the  loader  to  link  in  the
Z       runtime support modules for the _d_b_u_g package.  Executing the
Z       factorial program with a command of the form:
Z
Z                           factorial 1 2 3 4 5
Z
Z       generates the output shown in figure 6.
Z
Z
Z
Z                 1
Z                 2
Z                 6
Z                 24
Z                 120
Z
Z
Z                                   Figure 6
Z                              factorial 1 2 3 4 5
Z
Z
Z
Z
Z
Z            Function  level  tracing  is  enabled  by  passing  the
Z       debugger the 't' flag in the debug control string.  Figure 7
Z       is  the  output  resulting  from  the  command  "factorial -
Z       #t:o 3 2".
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 9 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z
Z
Z                 |   >factorial
Z                 |   |   >factorial
Z                 |   |   <factorial
Z                 |   <factorial
Z                 2
Z                 |   >factorial
Z                 |   |   >factorial
Z                 |   |   |   >factorial
Z                 |   |   |   <factorial
Z                 |   |   <factorial
Z                 |   <factorial
Z                 6
Z                 <main
Z
Z
Z                                   Figure 7
Z                              factorial -#t:o 3 2
Z
Z
Z
Z
Z
Z            Each entry to or return from a function is indicated by
Z       '>'  for  the  entry  point  and  '<'  for  the  exit point,
Z       connected by vertical bars to allow matching  points  to  be
Z       easily found when separated by large distances.
Z
Z
Z            This trace output indicates that there was  an  initial
Z       call  to  factorial from main (to compute 2!), followed by a
Z       single recursive call to factorial to compute 1!.  The  main
Z       program  then  output  the  result  for  2!  and  called the
Z       factorial  function  again  with  the  second  argument,  3.
Z       Factorial  called  itself  recursively to compute 2! and 1!,
Z       then returned control to main, which output the value for 3!
Z       and exited.
Z
Z
Z            Note that there is no matching entry point "main>"  for
Z       the  return point "<main" because at the time the DDDDBBBBUUUUGGGG____EEEENNNNTTTTEEEERRRR
Z       macro was reached in main, tracing was not enabled yet.   It
Z       was  only  after  the  macro  DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH  was  executing that
Z       tracing became enabled.  This implies that the argument list
Z       should  be  processed  as  early  as possible since all code
Z       preceding  the  first  call  to  DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH  is   essentially
Z       invisible  to  ddddbbbbuuuugggg (this can be worked around by inserted a
Z       temporary   DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH((((aaaarrrrggggvvvv[[[[1111]]]]))))   immediately    after    the
Z       DDDDBBBBUUUUGGGG____EEEENNNNTTTTEEEERRRR((((""""mmmmaaaaiiiinnnn"""")))) macro.
Z
Z
Z
Z
Z                                  - 10 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z            One last note, the trace output normally comes  out  on
Z       the  standard error.  Since the factorial program prints its
Z       result on the standard output, there is the  possibility  of
Z       the  output  on  the  terminal  being  scrambled  if the two
Z       streams are not synchronized.  Thus the debugger is told  to
Z       write its output on the standard output instead, via the 'o'
Z       flag character.   Note  that  no  'o'  implies  the  default
Z       (standard  error),  a  'o'  with no arguments means standard
Z       output, and a 'o' with an  argument  means  used  the  named
Z       file.   I.E,  "factorial -#t:o,logfile 3 2"  would write the
Z       trace output in "logfile".  Because of  UUUUNNNNIIIIXXXX  implementation
Z       details,  programs usually run faster when writing to stdout
Z       rather than stderr, though this is not a prime consideration
Z       in this example.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 11 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       UUUUSSSSEEEE OOOOFFFF DDDDBBBBUUUUGGGG____NNNN MMMMAAAACCCCRRRROOOOSSSS
Z
Z
Z            The mechanism used to produce "printf" style output  is
Z       the DDDDBBBBUUUUGGGG____NNNN macro, where NNNN is replaced by the matching number
Z       of arguments to the macro.  Unfortunately, the standard UUUUNNNNIIIIXXXX
Z       C preprocessor does not allow macros to have variable number
Z       of arguments.  If it did,  then  a  single  macro  (such  as
Z       DBUG_PRINTF) could replace all the DDDDBBBBUUUUGGGG____NNNN macros.
Z
Z
Z            To allow selection of output from specific macros,  the
Z       first  argument  to  every  DDDDBBBBUUUUGGGG____NNNN  macro is a _d_b_u_g keyword.
Z       When this keyword appears in the argument list  of  the  'd'
Z       flag    in    a    debug    control   string,   as   in   "-
Z       #d,keyword1,keyword2,...:t", output from  the  corresponding
Z       macro  is enabled.  The default when there is no 'd' flag in
Z       the control string is  to  enable  output  from  all  DDDDBBBBUUUUGGGG____NNNN
Z       macros.
Z
Z
Z            Typically, a program will be run once, with no keywords
Z       specified,  to  determine  what keywords are significant for
Z       the current problem (the keywords are printed in  the  macro
Z       output  line).  Then the program will be run again, with the
Z       desired  keywords,  to  examine  only  specific   areas   of
Z       interest.
Z
Z
Z            The rest of the argument list to a DDDDBBBBUUUUGGGG____NNNN is a standard
Z       printf  style  format  string  and  one or more arguments to
Z       print.  Note that no explicit newline is required at the end
Z       of  the  format  string.  As a matter of style, two or three
Z       small DDDDBBBBUUUUGGGG____NNNN macros are preferable to a single macro with  a
Z       huge  format  string.  Figure 8 shows the output for default
Z       tracing and debug.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 12 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z
Z
Z                 |   args: argv[2] = 3
Z                 |   >factorial
Z                 |   |   find: find 3 factorial
Z                 |   |   >factorial
Z                 |   |   |   find: find 2 factorial
Z                 |   |   |   >factorial
Z                 |   |   |   |   find: find 1 factorial
Z                 |   |   |   |   result: result is 1
Z                 |   |   |   <factorial
Z                 |   |   |   result: result is 2
Z                 |   |   <factorial
Z                 |   |   result: result is 6
Z                 |   <factorial
Z                 6
Z                 <main
Z
Z
Z                                   Figure 8
Z                              factorial -#d:t:o 3
Z
Z
Z
Z
Z
Z            The output from the DDDDBBBBUUUUGGGG____NNNN macro is indented  to  match
Z       the trace output for the function in which the macro occurs.
Z       When debugging is enabled, but not trace, the output  starts
Z       at the left margin, without indentation.
Z
Z
Z            To demonstrate selection of specific macros for output,
Z       figure  9  shows  the  result  when the factorial program is
Z       invoked with the debug control string "-#d,result:o".
Z
Z
Z
Z                 factorial: result: result is 1
Z                 factorial: result: result is 2
Z                 factorial: result: result is 6
Z                 factorial: result: result is 24
Z                 24
Z
Z
Z                                   Figure 9
Z                           factorial -#d,result:o 4
Z
Z
Z
Z
Z
Z
Z
Z                                  - 13 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z            It is sometimes desirable  to  restrict  debugging  and
Z       trace  actions  to a specific function or list of functions.
Z       This is accomplished with the  'f'  flag  character  in  the
Z       debug  control  string.   Figure  10  is  the  output of the
Z       factorial program  when  run  with  the  control  string  "-
Z       #d:f,factorial:F:L:o".  The 'F' flag enables printing of the
Z       source file name and the 'L' flag enables  printing  of  the
Z       source file line number.
Z
Z
Z
Z                    factorial.c:     8: factorial: find: find 3 factorial
Z                    factorial.c:     8: factorial: find: find 2 factorial
Z                    factorial.c:     8: factorial: find: find 1 factorial
Z                    factorial.c:    12: factorial: result: result is 1
Z                    factorial.c:    12: factorial: result: result is 2
Z                    factorial.c:    12: factorial: result: result is 6
Z                 6
Z
Z
Z                                   Figure 10
Z                       factorial -#d:f,factorial:F:L:o 3
Z
Z
Z
Z
Z
Z            The output in figure 10 shows that the "find" macro  is
Z       in  file  "factorial.c"  at  source  line 8 and the "result"
Z       macro is in the same file at source line 12.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 14 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       SSSSUUUUMMMMMMMMAAAARRRRYYYY OOOOFFFF MMMMAAAACCCCRRRROOOOSSSS
Z
Z
Z            This section summarizes  the  usage  of  all  currently
Z       defined  macros in the _d_b_u_g package.  The macros definitions
Z       are found in the user include file ddddbbbbuuuugggg....hhhh from the  standard
Z       include directory.
Z
Z
Z
Z               DBUG_ENTER  Used to tell the runtime support  module
Z                           the  name of the function being entered.
Z                           The argument must be of type "pointer to
Z                           character".   The  DBUG_ENTER macro must
Z                           precede  all  executable  lines  in  the
Z                           function  just  entered,  and  must come
Z                           after  all  local  declarations.    Each
Z                           DBUG_ENTER  macro  must  have a matching
Z                           DBUG_RETURN or DBUG_VOID_RETURN macro at
Z                           the  function  exit  points.  DBUG_ENTER
Z                           macros   used   without    a    matching
Z                           DBUG_RETURN  or  DBUG_VOID_RETURN  macro
Z                           will cause  warning  messages  from  the
Z                           _d_b_u_g package runtime support module.
Z
Z                           EX: DBUG_ENTER ("main");
Z
Z              DBUG_RETURN  Used at each exit point  of  a  function
Z                           containing  a  DBUG_ENTER  macro  at the
Z                           entry point.  The argument is the  value
Z                           to  return.   Functions  which return no
Z                           value    (void)    should    use     the
Z                           DBUG_VOID_RETURN  macro.  It is an error
Z                           to     have     a     DBUG_RETURN     or
Z                           DBUG_VOID_RETURN  macro  in  a  function
Z                           which has no matching DBUG_ENTER  macro,
Z                           and  the  compiler  will complain if the
Z                           macros are actually used (expanded).
Z
Z                           EX: DBUG_RETURN (value);
Z                           EX: DBUG_VOID_RETURN;
Z
Z             DBUG_PROCESS  Used to name the current  process  being
Z                           executed.   A  typical argument for this
Z                           macro is "argv[0]", though  it  will  be
Z                           perfectly happy with any other string.
Z
Z                           EX: DBUG_PROCESS (argv[0]);
Z
Z                DBUG_PUSH  Sets a new debugger state by pushing the
Z                           current  ddddbbbbuuuugggg  state  onto  an  internal
Z
Z
Z
Z                                  - 15 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z                           stack and setting up the new state using
Z                           the  debug  control string passed as the
Z                           macro argument.  The most  common  usage
Z                           is to set the state specified by a debug
Z                           control  string   retrieved   from   the
Z                           argument  list.   Note  that the leading
Z                           "-#" in a debug control string specified
Z                           as  a  command line argument must nnnnooootttt be
Z                           passed as part of  the  macro  argument.
Z                           The proper usage is to pass a pointer to
Z                           the  first  character  aaaafffftttteeeerrrr  the   "-#"
Z                           string.
Z
Z                           EX: DBUG_PUSH ((argv[i][2]));
Z                           EX: DBUG_PUSH ("d:t");
Z                           EX: DBUG_PUSH ("");
Z
Z                 DBUG_POP  Restores the previous debugger state  by
Z                           popping  the state stack.  Attempting to
Z                           pop more  states  than  pushed  will  be
Z                           ignored  and  no  warning will be given.
Z                           The DBUG_POP macro has no arguments.
Z
Z                           EX: DBUG_POP ();
Z
Z                DBUG_FILE  The  DBUG_FILE  macro  is  used  to   do
Z                           explicit I/O on the debug output stream.
Z                           It is used in the  same  manner  as  the
Z                           symbols  "stdout"  and  "stderr"  in the
Z                           standard I/O package.
Z
Z                           EX: fprintf (DBUG_FILE, "Doing  my   own
Z                           I/O!0);
Z
Z             DBUG_EXECUTE  The  DBUG_EXECUTE  macro  is   used   to
Z                           execute any arbitrary C code.  The first
Z                           argument is the debug keyword,  used  to
Z                           trigger  execution of the code specified
Z                           as the second argument.  This macro must
Z                           be  used  cautiously  because,  like the
Z                           DBUG_N  macros,  it   is   automatically
Z                           selected  by  default  whenever  the 'd'
Z                           flag has no argument list  (I.E.,  a  "-
Z                           #d:t" control string).
Z
Z                           EX: DBUG_EXECUTE ("abort", abort ());
Z                           EX: DBUG_EXECUTE ("tprint", {printtree (tree, DBUG_FILE);});
Z
Z                   DBUG_N  Used  to  do  printing via the "fprintf"
Z                           library function on  the  current  debug
Z                           stream, DBUG_FILE.  N may currently be a
Z
Z
Z
Z                                  - 16 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z                           number in the range 2-5,  and  specifies
Z                           the   number   of   arguments   in   the
Z                           corresponding macro.  The first argument
Z                           is  a  debug  keyword,  the  second is a
Z                           format   string,   and   the   remaining
Z                           arguments,  if any, are the values to be
Z                           printed.
Z
Z                           EX: DBUG_2 ("eof", "end of file found");
Z                           EX: DBUG_3 ("type","type is %x", type);
Z                           EX: DBUG_4 ("stp",   "%x -> %s",    stp,
Z                           stp -> name);
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 17 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       DDDDEEEEBBBBUUUUGGGG CCCCOOOONNNNTTTTRRRROOOOLLLL SSSSTTTTRRRRIIIINNNNGGGG
Z
Z
Z            The debug control string is used to set  the  state  of
Z       the   debugger   via  the  DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH  macro.   This  section
Z       summarizes the currently available debugger options and  the
Z       flag  characters  which  enable  or  disable them.  Argument
Z       lists enclosed in '[' and ']' are optional.
Z
Z
Z                d[,keywords] Enable   output   from   macros   with
Z                             specified  keywords.   A  null list of
Z                             keywords implies that all keywords are
Z                             selected.
Z
Z               f[,functions] Limit   debugger   actions   to    the
Z                             specified  list  of functions.  A null
Z                             list of  functions  implies  that  all
Z                             functions are selected.
Z
Z                           F Mark each debugger  output  line  with
Z                             the name of the source file containing
Z                             the macro causing the output.
Z
Z                           L Mark each debugger  output  line  with
Z                             the  source  file  line  number of the
Z                             macro causing the output.
Z
Z                           n Mark each debugger  output  line  with
Z                             the current function nesting depth.
Z
Z                    o[,file] Redirect the debugger output stream to
Z                             the   specified   file.   The  default
Z                             output  stream  is  stderr.   A   null
Z                             argument  list  causes  output  to  be
Z                             redirected to stdout.
Z
Z               p[,processes] Limit   debugger   actions   to    the
Z                             specified   processes.   A  null  list
Z                             implies all processes.  This is useful
Z                             for    processes   which   run   child
Z                             processes.  Note  that  each  debugger
Z                             output  line  can  be  marked with the
Z                             name of the current  process  via  the
Z                             'P' flag.  The process name must match
Z                             the    argument    passed    to    the
Z                             DDDDBBBBUUUUGGGG____PPPPRRRROOOOCCCCEEEESSSSSSSS macro.
Z
Z                           P Mark each debugger  output  line  with
Z                             the name of the current process.  Most
Z                             useful when used with a process  which
Z
Z
Z
Z                                  - 18 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z                             runs  child  processes  that  are also
Z                             being debugged.  Note that the  parent
Z                             process  must arrange for the debugger
Z                             control string to  be  passed  to  the
Z                             child processes.
Z
Z                           r Used in conjunction with the DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH
Z                             macro to reset the current indentation
Z                             level back to zero.  Most useful  with
Z                             DDDDBBBBUUUUGGGG____PPPPUUUUSSSSHHHH  macros  used to temporarily
Z                             alter the debugger state.
Z
Z                       t[,N] Enable function control flow  tracing.
Z                             The maximum nesting depth is specified
Z                             by N, and defaults to 200.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 19 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       HHHHIIIINNNNTTTTSSSS AAAANNNNDDDD MMMMIIIISSSSCCCCEEEELLLLLLLLAAAANNNNEEEEOOOOUUUUSSSS
Z
Z
Z            One of the most useful capabilities of the _d_b_u_g package
Z       is  to  compare  the  executions  of  a given program in two
Z       different environments.  This is typically done by executing
Z       the program in the environment where it behaves properly and
Z       saving the debugger output in a reference file.  The program
Z       is  then  run with identical inputs in the environment where
Z       it  misbehaves  and  the  output  is  again  captured  in  a
Z       reference  file.   The  two  reference  files  can  then  be
Z       differentially compared to determine exactly where execution
Z       of the two processes diverges.
Z
Z
Z            A  related  usage  is  regression  testing  where   the
Z       execution   of   a   current  version  is  compared  against
Z       executions of previous versions.  This is most  useful  when
Z       there are only minor changes.
Z
Z
Z            It is not difficult to modify an existing  compiler  to
Z       implement  some  of  the  functionality  of the _d_b_u_g package
Z       automatically, without source code changes  to  the  program
Z       being debugged.  In fact, such changes were implemented in a
Z       version of the Portable C Compiler by  the  author  in  less
Z       than  a  day.   However,  it is strongly encouraged that all
Z       newly developed code continue to use the debugger macros for
Z       the   portability   reasons  noted  earlier.   The  modified
Z       compiler should be used only for testing existing programs.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 20 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)         January 8, 1985
Z
Z
Z
Z       CCCCAAAAVVVVEEEEAAAATTTTSSSS
Z
Z
Z            The _d_b_u_g package works best with  programs  which  have
Z       "line oriented"  output,  such  as  text processors, general
Z       purpose utilities, etc.  It can be  interfaced  with  screen
Z       oriented  programs  such as visual editors by redefining the
Z       appropriate macros to call special functions for  displaying
Z       the  debugger  results.   Of  course,  this  caveat  is  not
Z       applicable if the debugger output is simply  dumped  into  a
Z       file for post-execution examination.
Z
Z
Z            Programs which use memory  allocation  functions  other
Z       than  mmmmaaaalllllllloooocccc  will  usually have problems using the standard
Z       _d_b_u_g package.  The most common problem is multiply allocated
Z       memory.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                  - 21 -
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z                                 D B U G
Z
Z                       C Program Debugging Package
Z
Z                                    by
Z9
Z                                Fred Fish
Z9
Z
Z
Z                                 _A_B_S_T_R_A_C_T
Z
Z
Z
Z       This document introduces _d_b_u_g, a  macro  based  C  debugging
Z       package  which  has  proven to be a very flexible and useful
Z       tool for debugging, testing, and porting C programs.
Z
Z
Z            All of the features of the _d_b_u_g package can be  enabled
Z       or  disabled dynamically at execution time.  This means that
Z       production programs will run normally when debugging is  not
Z       enabled,  and  eliminates  the need to maintain two separate
Z       versions of a program.
Z
Z
Z            Many   of   the   things   easily   accomplished   with
Z       conventional  debugging  tools,  such as symbolic debuggers,
Z       are difficult or impossible  with  this  package,  and  vice
Z       versa.   Thus the _d_b_u_g package should _n_o_t be thought of as a
Z       replacement or substitute for  other  debugging  tools,  but
Z       simply  as  a useful _a_d_d_i_t_i_o_n to the program development and
Z       maintenance environment.
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z
Z99
Z
Z
Z
Z
Z
Z
STUNKYFLUFF
set `sum user.t`
if test 19753 != $1
then
echo user.t: Checksum error. Is: $1, should be: 19753.
fi
echo ALL DONE BUNKY!
exit 0