dbug (part 3 of 4 REPOSTED)

fnf at unisoft.UUCP fnf at unisoft.UUCP
Tue Dec 17 12:38:39 AEST 1985


Seems like I blew it and tried to post the nroff'd document with
lots of ^H's and a few escapes.  Anyway, here is one stripped of
all control characters.  You may have to fiddle with it to get it
to print correctly, as I might have messed up the page boundries.

#--------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       INTRODUCTION
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 adb and sdb debuggers
Z       provided with the UNIX 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, dbug 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)       December 11, 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 dbug 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 dbug 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  dbug 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)       December 11, 1985
Z
Z
Z
Z       PRIMITIVE DEBUGGING TECHNIQUES
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)       December 11, 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  #ifdef  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 #ifdef arguments to match the
Z       indentation  of  the code, but not all C preprocessors allow
Z       this.   The  only  requirement  for  the  standard  UNIX   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)       December 11, 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)       December 11, 1985
Z
Z
Z
Z       FUNCTION TRACE EXAMPLE
Z
Z
Z            We will start off learning about  the  capabilities  of
Z       the  dbug  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                 /* User programs should use <local/dbug.h> */
Z                 #include "dbug.h"
Z
Z                 main (argc, argv)
Z                 int argc;
Z                 char *argv[];
Z                 {
Z                     register int 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 main 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                                  - 6 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 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       DBUG_OFF, forces the macro expansions to be null).
Z
Z            Also notice the inclusion of  the  header  file  dbug.h
Z       from the local header file directory.  (The version included
Z       here is the test version in  the  dbug  source  distribution
Z       directory).   This file contains all the definitions for the
Z       debugger macros, which all have the form DBUG_XX...XX.
Z
Z
Z            The DBUG_ENTER macro informs that debugger that we have
Z       entered  the function named main.  It must be the very first
Z       "executable" line in a function, after all declarations  and
Z       before any other executable line.  The DBUG_PROCESS macro is
Z       generally used only once per program to inform the  debugger
Z       what name the program was invoked with.  The DBUG_PUSH 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 DBUG_4 macro is used  to  print
Z       the  values  of each argument for which a factorial is to be
Z       computed.  The DBUG_RETURN 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  main  function  recognizes  the  "-#d:t"  string  as  a
Z       debugger  control  string, and passes the debugger arguments
Z       ("d:t")  to  the  dbug  runtime  support  routines  via  the
Z       DBUG_PUSH macro.  This particular string enables output from
Z       the DBUG_4 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
Z
Z
Z                                  - 7 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 1985
Z
Z
Z
Z       Note  that  previously  enabled  debugger  actions  can   be
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                 /* User programs should use <local/dbug.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  dbug  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 DBUG_RETURN or DBUG_VOID_RETURN
Z       macro.
Z
Z
Z            To build  the  factorial  program  on  a  UNIX  system,
Z       compile and link with the command:
Z
Z
Z
Z                                  - 8 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 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 dbug 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)       December 11, 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 DBUG_ENTER
Z       macro was reached in main, tracing was not enabled yet.   It
Z       was  only  after  the  macro  DBUG_PUSH  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  DBUG_PUSH  is   essentially
Z       invisible  to  dbug (this can be worked around by inserted a
Z       temporary   DBUG_PUSH(argv[1])   immediately    after    the
Z       DBUG_ENTER("main") macro.
Z
Z
Z
Z
Z                                  - 10 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 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  UNIX  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)       December 11, 1985
Z
Z
Z
Z       USE OF DBUG_N MACROS
Z
Z
Z            The mechanism used to produce "printf" style output  is
Z       the DBUG_N macro, where N is replaced by the matching number
Z       of arguments to the macro.  Unfortunately, the standard UNIX
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 DBUG_N macros.
Z
Z
Z            To allow selection of output from specific macros,  the
Z       first  argument  to  every  DBUG_N  macro is a dbug 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  DBUG_N
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 DBUG_N 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 DBUG_N 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)       December 11, 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 DBUG_N 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)       December 11, 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:     9: factorial: find: find 3 factorial
Z                    factorial.c:     9: factorial: find: find 2 factorial
Z                    factorial.c:     9: factorial: find: find 1 factorial
Z                    factorial.c:    13: factorial: result: result is 1
Z                    factorial.c:    13: factorial: result: result is 2
Z                    factorial.c:    13: 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)       December 11, 1985
Z
Z
Z
Z       SUMMARY OF MACROS
Z
Z
Z            This section summarizes  the  usage  of  all  currently
Z       defined  macros in the dbug package.  The macros definitions
Z       are found in the user include file dbug.h 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                           dbug 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  dbug  state  onto  an  internal
Z
Z
Z
Z                                  - 15 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 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 not be
Z                           passed as part of  the  macro  argument.
Z                           The proper usage is to pass a pointer to
Z                           the  first  character  after  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
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                           number  in  the range 2-5, and specifies
Z
Z
Z
Z                                  - 16 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 1985
Z
Z
Z
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              DBUG_SETJMP  Used in place of the  setjmp()  function
Z                           to first save the current debugger state
Z                           and then  execute  the  standard  setjmp
Z                           call.   This  allows  to the debugger to
Z                           restore it's state when the DBUG_LONGJMP
Z                           macro  is  used  to  invoke the standard
Z                           longjmp() call.  Currently all instances
Z                           of  DBUG_SETJMP  must  occur  within the
Z                           same function and at the  same  function
Z                           nesting level.
Z
Z                           EX: DBUG_SETJMP (env);
Z
Z             DBUG_LONGJMP  Used in place of the longjmp()  function
Z                           to  first  restore the previous debugger
Z                           state  at   the   time   of   the   last
Z                           DBUG_SETJMP   and   then   execute   the
Z                           standard  longjmp()  call.   Note   that
Z                           currently    all   DBUG_LONGJMP   macros
Z                           restore the state at  the  time  of  the
Z                           last  DBUG_SETJMP.  It would be possible
Z                           to  maintain  separate  DBUG_SETJMP  and
Z                           DBUG_LONGJMP   pairs   by   having   the
Z                           debugger runtime support module use  the
Z                           first   argument  to  differentiate  the
Z                           pairs.
Z
Z                           EX: DBUG_LONGJMP (env,val);
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)       December 11, 1985
Z
Z
Z
Z       DEBUG CONTROL STRING
Z
Z
Z            The debug control string is used to set  the  state  of
Z       the   debugger   via  the  DBUG_PUSH  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                    D[,time] Delay for specified  time  after  each
Z                             output  line,  to  let  output  drain.
Z                             Time is given in tenths  of  a  second
Z                             (value  of 10 is one second).  Default
Z                             is zero.
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                           N Sequentially  number   each   debugger
Z                             output  line  starting  at 1.  This is
Z                             useful  for  reference  purposes  when
Z                             debugger  output  is interspersed with
Z                             program output.
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
Z
Z
Z                                  - 18 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 1985
Z
Z
Z
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                             DBUG_PROCESS 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                             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 DBUG_PUSH
Z                             macro to reset the current indentation
Z                             level back to zero.  Most useful  with
Z                             DBUG_PUSH  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                                  - 19 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 1985
Z
Z
Z
Z       HINTS AND MISCELLANEOUS
Z
Z
Z            One of the most useful capabilities of the dbug 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 dbug 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)       December 11, 1985
Z
Z
Z
Z       CAVEATS
Z
Z
Z            The dbug 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  malloc  will  usually have problems using the standard
Z       dbug package.  The most common problem is multiply allocated
Z       memory.
Z
Z
Z            Beware  that  some  of  the  macros  are  not   context
Z       independent.   Some  of  them  contain if statements with no
Z       else statements.  In particular, the following code  segment
Z       will not behave as expected:
Z
Z
Z
Z                 if (something_interesting)
Z                         DBUG_2 ("ins", "something interesting");
Z                 else
Z                         do_normal_processing ();
Z
Z
Z
Z       The user code else will bind to the macro's  if  to  produce
Z       code equivalent to:
Z
Z
Z
Z                 if (something_interesting)
Z                         if (debugging_on)
Z                                 printf ("something interesting");
Z                         else
Z                                 do_normal_processing ();
Z
Z
Z
Z       The author has received  numerous  suggestions  for  changes
Z       which  would  eliminate  this  danger, most based on obscure
Z       features of the language or preprocessor, but  has  rejected
Z       most  of  these for portability or efficiency reasons.  (The
Z       author also considers it to be poor programming practice  to
Z
Z
Z
Z                                  - 21 -
Z
Z
Z
Z
Z
Z
Z
Z       DBUG User Manual       (preliminary)       December 11, 1985
Z
Z
Z
Z       write  code with any control flow statements that do not use
Z       braces.)  However,  if  you  absolutely  must  prevent  this
Z       behavior  try changing the macro definitions to something of
Z       the form:
Z
Z
Z
Z                 #define DBUG_2(keyword,format) \
Z                   do { \
Z                     if (_db_on_) { \
Z                       _db_printf_ (__LINE__, keyword, format); \
Z                     } \
Z                   } while (0)
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                                  - 22 -
Z
Z
Z
Z
Z
Z
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                                 ABSTRACT
Z
Z
Z
Z       This document introduces dbug, 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 dbug 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 dbug package should not be thought of as a
Z       replacement or substitute for  other  debugging  tools,  but
Z       simply  as  a useful addition 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
STUNKYFLUFF
set `sum user.t`
if test 50553 != $1
then
echo user.t: Checksum error. Is: $1, should be: 50553.
fi
echo ALL DONE BUNKY!
exit 0



More information about the Comp.sources.unix mailing list