home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / BIPL.ZIP / DEBUG.ZIP / DEBUGIFY.DOC < prev    next >
Encoding:
Text File  |  1992-10-19  |  25.0 KB  |  512 lines

  1. 1     PACKING LIST/INSTALLATION
  2.  
  3. Presumably, you have received the DEBUGIFY software in some sort of packaged
  4. form, e.g., as a ZIP or TAR file.  The package should include the following
  5. files:
  6.  
  7. DEBUGIFY.IC0             The unconfigured ICON source for the DEBUGIFY program
  8.                          which installs debug hooks into ucode files.  This is
  9.                          used to create the configured DEBUGIFY.ICN source.
  10. DEBUG.ICN                The ICON source for an example debug procedure which may
  11.                          be used with DEBUGIFY.
  12. DEBUGIFY.DOC             The file you are reading now.  This file describes how
  13.                          to install and use the above files.
  14. DEBCFG.ICN        The ICON source for the program which configures DEBUGIFY for
  15.                   the current version of ICON.
  16.  
  17. It is assumed that you have previously installed the ICON version 8 translator
  18. and interpreter and the ICON program library.  DEBUGIFY may work with versions 7
  19. and 7.5, but I have not tested it with them.  DEBUGIFY was designed to be as
  20. system-independent as possible, however, it has only been tested on the MS-DOS
  21. and UNIX (4.3bsd) ICON versions.  It is assumed that you have had some experience
  22. with ICON, e.g.,  you know how to link separately compiled modules, you know what
  23. a ucode file is, etc.
  24.  
  25. Because of minor differences in ucode files, DEBUGIFY must be configured for the
  26. version of Icon running on your system.   DEBUGIFY MUST BE RECONFIGURED EACH TIME
  27. A DIFFERENT VERSION OF ICON IS USED!!  To configure or reconfigure DEBUGIFY, make
  28. sure the following files are in the same directory:
  29.  
  30.                   DEBUGIFY.IC0
  31.                   DEBCFG.ICN
  32.  
  33. To prepare the configuration process, execute the following in that directory:
  34.  
  35.                      icont -c debcfg
  36.                      icont debcfg.u
  37.  
  38. To create DEBUGIFY.ICN, execute the following:
  39.  
  40.                     iconx debcfg
  41.  
  42. To compile DEBUGIFY, execute the following:
  43.  
  44.                     icont debugify
  45.  
  46. after compilation, move the resultant DEBUGIFY or DEBUGIFY.ICX file to a directo-
  47. ry where you keep executable files.
  48.  
  49. To compile DEBUG, change to the directory containing DEBUG.ICN and execute the
  50. following:
  51.  
  52.       icont -c debug
  53.  
  54. after compilation, move the resultant DEBUG.U1 and DEBUG.U2 files to a directory
  55. where you keep ICON procedure ucode files.
  56.  
  57. ONCE AGAIN, ALL OF THE ABOVE STEPS, INCLUDING RECOMPILING DEBCFG.ICN, MUST BE
  58. PERFORMED EACH TIME A DIFFERENT VERSION OF ICON IS USED!
  59.  
  60. 2     INTRODUCTION
  61.  
  62. In using ICON, I have frequently felt the need for a more capable debug facility
  63. than that offered by the usual ICON tracing.  It would be nice to be able to
  64. trace at a source line level rather than at a procedure entry/exit level.  A good
  65. debugger should also allow interactive display and modification of program
  66. variables.  DEBUGIFY enables the ICON programmer to produce an executable file
  67. which calls a debug routine prior to executing each ICON statement.  The debug
  68. routine is written in ICON and may be modified or replaced entirely by the
  69. programmer.  This gives the programmer maximum flexibility to define what he
  70. wants the debug routine to do.
  71.  
  72. I considered several possible ways of implementing an ICON debugger.  The first
  73. method was to write a program in ICON which would parse an ICON source file and
  74. insert additional ICON debugging statements in the source file.  I actually
  75. started to write this program.  After awhile I realized I would never be able to
  76. finish this project in the limited spare time I had.  The second method consid-
  77. ered was using the ICON variant translator system to create debugging code along
  78. with the translation of each source code statement.  Unfortunately, the variant
  79. translator system is not included in all ICON versions, particularly those for
  80. personal computers.  Since I use ICON at work on a UNIX system and at home on my
  81. MS-DOS system, the variant translator debugging method would not be usable on the
  82. MS-DOS machine.
  83.  
  84. In Issue Number 8 (October 1991) of The Icon Analyst, the article "An Imaginary
  85. Icon Computer" briefly discussed the structure of ucode files.  It contained an
  86. example of an Icon program and its corresponding ucode.  I realized that with a
  87. little study, ucode files are not be hard to understand.  Basically, ucode files
  88. are source code files based on a Postfix-evaluation type of stack language. 
  89. Those of you who have had experience with FORTH would probably be able to read
  90. ucode files with little difficulty.  Anyway, I found that I could modify ucode
  91. files, compile them into executables, and they would run just as if I had altered
  92. the original source code instead of the ucode files.  DEBUGIFY performs a ucode
  93. modification automatically.
  94.  
  95. DEBUGIFY reads a ucode file and inserts additional ucode statements before and
  96. after each block of ucode statements which correspond to a single source code
  97. line.  To be more precise, the ICON translator converts an ICON source file into
  98. a stream of ucode stack language commands and inserts ICON source line markers
  99. wherever appropriate.  DEBUGIFY inserts a call to a debugging routine after each
  100. of the source line markers.   DEBUGIFY inserts ucode which is exactly equivalent
  101. to the following ICON source code:
  102.  
  103.       __vals := []
  104.       every put(_vals, variable(!__names))
  105.       __debug_proc(&file, <proc_name>, &line, __names, __vals)
  106.       every __i := 1 to *__names do
  107.             variable(__names[__i]) := __vals[__i]
  108.  
  109. The first two lines collect the values of all the currently accessible variables
  110. and place them on the __vals list. The third line calls a user-written ICON
  111. procedure called __debug_proc.  The last two lines replace the values of all
  112. variables with new ones which may or may not have been changed by __debug_proc.
  113.  
  114.  
  115. 3     USING DEBUGIFY
  116.  
  117. There are basically four steps to follow in producing a DEBUGIFYed program.
  118.  
  119. 1)    Write source code modules
  120. 2)    Compile source code to ucode
  121. 3)    DEBUGIFY selected ucode modules
  122. 4)    Link DEBUGIFYed and regular ucode modules to produce final program
  123.  
  124. STEP 1: WRITE SOURCE CODE MODULES
  125.  
  126. Assume you have written an ICON program consisting of three procedures: main,
  127. proc, and replace contained in the source  files MAIN.ICN, PROC.ICN and 
  128. STRINGS.ICN, respectively.  Note that STRINGS.ICN is part of the Icon Program
  129. Library while main and proc are user-written procedures.  We will assume that the
  130. procedure replace has already been thoroughly debugged and therefore you will
  131. only want to DEBUGIFY main and proc.  Optionally, MAIN.ICN and PROC.ICN each may
  132. contain the statement
  133.  
  134.       link <debugfile>
  135.  
  136. where <debugfile> is the name of the file containing the __debug_proc procedure. 
  137. This is DEBUG if the supplied __debug_proc is used and DEBUG is contained in a
  138. directory on the IPATH path.
  139.  
  140. STEP 2: COMPILE SOURCE CODE TO UCODE
  141.  
  142. To produce ucode files, enter the following:
  143.  
  144.       icont -c MAIN.ICN
  145.       icont -c PROC.ICN
  146.       icont -c STRINGS.ICN (if not already done)
  147.  
  148. which will produce the needed  .U1 and .U2 files.
  149.  
  150.  
  151. STEP 3: DEBUGIFY SELECTED UCODE MODULES
  152.  
  153. This step produces new MAIN.U1 and PROC.U1 files with debugging hooks inserted.
  154. First rename MAIN.U1 to another file name, say MAIN.TMP and enter either
  155.  
  156.       DEBUGIFY -m MAIN.TMP> MAIN.U1
  157.  
  158.             for UNIX or
  159.  
  160.       iconx  DEBUGIFY -m MAIN.TMP> MAIN.U1
  161.  
  162.             for MS-DOS
  163.  
  164. Repeat the aboe rename and DEBUGIFY steps for PROC.U1.
  165.  
  166. STEP 4: LINK UCODE MODULES TO PRODUCE FINAL PROGRAM
  167.  
  168. To create the executable file MAIN (UNIX) or MAIN .ICX (MS-DOS), run the follow-
  169. ing:
  170.  
  171.       icont MAIN.U PROC.U STRINGS.U DEBUG.U
  172.  
  173. or if the line "link DEBUG" was inserted in MAIN.ICN, then it is only necessary
  174. to run
  175.  
  176.       icont MAIN.U PROC.U STRINGS.U
  177.  
  178. You can now run the executable file and it will enter __debug_proc prior to
  179. executing each source code line.
  180.  
  181. LINKING UNDER MS-DOS
  182.  
  183. Since a debugified ucode file can be 6 times larger than the equivalent untreated
  184. ucode file, the MS-DOS ICON interpreter may not be able to perform the compila-
  185. tion of MAIN.  If you get an error message which says "icont: out of <something>
  186. space", then you can try recompiling with the -S option.  The <something> might
  187. be label, constant, code buffer, or any of a number of other space-consuming
  188. objects.  The -S option is of the form -S[cfgilnrstCFL]n where the letter
  189. following S stands for the one of the type of objects in the table below and n is
  190. the number of storage units to allocate for objects of that type.  For example
  191.  
  192.       icont -SL100 -SC32767 PROG.U
  193.  
  194. would provide twice the usual amount of label space and the maximum amount of
  195. code buffer space.
  196.  
  197. c     constant table            100
  198. f     field table               100
  199. g     global symbol table       200
  200. i     identifier table          500
  201. l     local symbol table        100
  202. n     line number table         1000
  203. r     record table              100
  204. s     string space              20000
  205. t     tree space                15000
  206. C     code buffer               15000
  207. F     file names                10
  208. L     labels                    500
  209.  
  210. The numbers given above represent the default storage unit allocations for each
  211. of the object types.  The above table and the information on the -S option is
  212. based on the technical report "Version 8 of Icon for MS-DOS" by Ralph E.
  213. Griswold.
  214.  
  215. If a program cannot be compiled after using the  -S option, there are three more
  216. tricks that can be used.  First of all, a considerable amount of memory can be
  217. saved if DEBUGIFY is run without the -m option. The m option tells DEBUGIFY to
  218. insert the ucode lines which allow __debug_proc modifications to variable values
  219. to remain in effect when control passes back to the procedure being debugged. 
  220. Without -m, __debug_proc changes to values are not visible to the procedure being
  221. debugged.  So a __debug_proc with an interactive  "set value" command would never
  222. work unless -m was used.  A debugified ucode file created without the -m option
  223. is about 4 times larger than the undebugified version.  Note that it was not
  224. possible to debugify DEBUGIFY with the -m option on my MS-DOS computer.  However,
  225. when -m was left off, DEBUGIFY could be recompiled with
  226.  
  227.       icont -SL1000 -SC24000 DEBUGIFY.U
  228.  
  229. The second trick involves restructuring the program to be debugified by breaking
  230. it into more and  smaller procedures.  It seems that memory resources used for
  231. compilation of a procedure are released after the compiler is done with that
  232. procedure.  This means that a program is only as difficult to debugify as is its
  233. largest (or most complex) procedure.  Thus the strategy is to break up large
  234. procedures into ones that have fewer executable statements and fewer variables. 
  235. The positive side of this restructuring  is that it usually improves the read-
  236. ability and maintainability of a program to reduce the size of very large
  237. procedures.
  238.  
  239. The third trick is selectively debugifying only some of the procedures which make
  240. up the application program.  This was already done in the example above involving
  241. main, proc, and replace.  Only main and proc were DEBUGIFYed.  However procedures
  242. can be selectively DEBUGIFYed even when they reside in the same source file.  If
  243. MAIN.ICN contained the procedures main, proc1 and proc2, and proc2 was deemed too
  244. complex to DEBUGIFY, we could exclude it without breaking it out of MAIN.ICN like
  245. this
  246.  
  247.       DEBUGIFY -i main -i proc1 MAIN.TMP > MAIN.U1
  248.  
  249. Use of the -i option includes only the procedures main and proc1 for DEBUIFica-
  250. tion.
  251.  
  252. As must be obvious by now, DEBUGIFY is not always simple to use.  It is recom-
  253. mended that the debugification steps presented above be automated via a batch
  254. (MS-DOS) or shell script (UNIX) file.  Such a file would 1) create the initial
  255. ucode file, 2) rename and debugify it, and 3) perform the final compilation and
  256. link step.
  257.  
  258.                        DEBUGIFY COMMAND LINE SUMMARY
  259.  
  260. DEBUGIFY [-m] [[-i procedure_name]...] ucode_file
  261.  
  262. Install debug hooks in all the procedures in ucode_file and writes out the
  263. resultant ucode file to standard output.  When the resultant ucode file is
  264. compiled and executed the procedure __debug_proc is invoked prior to the execu-
  265. tion of each source code line.  By default, debug hooks are installed in all
  266. procedures in ucode_file.  It is assumed that the source code file for ucode_file
  267. includes a link statement  for the file containing the __debug_proc ucode or will
  268. be otherwise linked to __debug_proc in a later call to icont. 
  269.  
  270. -m          Generate ucode that will allow __debug_proc to alter the value of
  271.             program variables.  A debugified ucode file created with -m is about
  272.             6 times larger than the equivalent untreated ucode file.  Without -
  273.             m, this reduces to a factor of about 4.
  274.  
  275. -i          Debugify the procedure whose name follows the -i option.  If
  276.             DEBUGIFY encounters any -i options, then only those procedures named
  277.             on the command line with -i will be debugified.
  278.  
  279. 4     WRITING A NEW DEBUG ROUTINE
  280.  
  281. One of the great benefits of using DEBUGIFY is that you are not restricted to
  282. using the debug procedure in the supplied DEBUG.ICN file.  A new one may be
  283. written in Icon or the supplied one may be modified.  To get used to using
  284. DEBUGIFY, it is suggested that initially at least one program be DEBUGIFYed 
  285. using the supplied DEBUG.ICN.
  286.  
  287. If you intend to modify the supplied debug routine or write one of your own, you
  288. must be aware of the nature of the debug interface which DEBUGIFY installs.  It
  289. is also suggested that you study the supplied source code in DEBUG.ICN (see the
  290. next section too).
  291.  
  292. The debug procedure invocation which DEBUGIFY installs in ucode corresponds
  293. exactly to the following ICON source code:
  294.  
  295.       __debug_proc(&file, <proc_name>, &line, __names, __vals)
  296.  
  297. Note that __debug_proc must be the name of the debug procedure you supply.  The
  298. parameters passed to __debug_proc are:
  299.  
  300. &file             The ICON keyword whose value is the name of the current source
  301.                   code file.
  302.  
  303. <proc_name>       A string containing the name of the procedure currently
  304.                   executing when __debug_proc is called.
  305.  
  306. &line             The ICON keyword whose value is the number of the source code
  307.                   line which will be executed after __debug_proc returns.
  308.  
  309. __names                  A list of strings, each of which is the name of a
  310.                          variable referenced in the currently executing
  311.                          procedure.  If a variable is global, but not referenced
  312.                          anywhere in the procedure, then it will not appear in
  313.                          this list.
  314.  
  315. __vals                   A list of values, each of which is the value of a
  316.                          variable referenced in the currently executing proce-
  317.                          dure.  The lists, __names and __vals, are ordered in
  318.                          such a way that the variable whose name is __names[i]
  319.                          has value __vals[i].  The procedure __debug_proc may
  320.                          change a value in the procedure from which it was called
  321.                          by changing the corresponding element in __vals.  For
  322.                          example, if __names[3] is "VAR1", then executing 
  323.  
  324.                   __vals[3] := "panic"
  325.  
  326.                          will have the effect of assigning "panic" to the vari-
  327.                          able VAR1 when __debug_proc returns to its calling
  328.                          routine.  This change will only be visible to the call-
  329.                          ing procedure if it was debugified with the -m option.  
  330.                          Note that changing the length of  the list __vals may
  331.                          have strange and undesirable effects if the -m option is
  332.                          set.
  333.  
  334. 5     USING THE SUPPLIED DEBUG ROUTINE
  335.  
  336. A simple but useful __debug_proc procedure is supplied in the file DEBUG.ICN.   
  337. It is of the interactive command line variety like the MS-DOS DEBUG program. 
  338. Each time __debug_proc is entered and is producing output (i.e., when not in a
  339. silent trace and not after an "nd" command), a status line is printed.  A typical
  340. status line might look like:
  341.  
  342.       proc.icn:co-expression_1(1):proc:23
  343.  
  344. This means __debug_proc has stopped just prior to execution of line 23 in the
  345. procedure proc during the execution of co-expression co-expression_1(1).  The
  346. file proc.icn is the source file containing the line about to be executed.
  347.  
  348. Following the appearance of the status line, the user is prompted to enter debug
  349. commands with the prompt
  350.  
  351. debug>
  352.  
  353. This prompt will repeat after each command is executed until one of the following
  354. occurs:
  355.  
  356. 1)    A blank line is entered
  357. 2)    The "stop" or "nd" command is entered
  358.  
  359. The debug commands are summarized below:
  360.  
  361. p var [var]...                 Print the type and image of each variable speci-
  362.                                fied.  Currently, thee is no way to print the
  363.                                image of structure (record, list, or table) compo-
  364.                                nents.
  365.  
  366. pa                             Print the type and image of all variables.
  367.  
  368. sn var number                  Set the value of the variable to the number
  369.  
  370. ss var string                  Set the value of the variable to the string.  The
  371.                                string may contain blanks however consecutive
  372.                                blanks are compressed to a single blank.  A blank
  373.                                may be represented by "\ " so that consecutive
  374.                                blanks may be entered as \ \ \ \  ...
  375.  
  376. t                              Turn on trace mode.  When in trace mode,
  377.                                __debug_proc prints out the current line number
  378.                                and other information needed for tracing execution
  379.                                and then returns to the caller.  No input is
  380.                                requested from the user.  However if the current
  381.                                line number is a breakpoint, then the debug
  382.                                interpreter will request input even though in
  383.                                trace mode.  Note that the trace command does not
  384.                                take effect immediately.  The debug interpreter
  385.                                continues processing input until a blank line is
  386.                                entered at which time __debug_proc is exited and
  387.                                tracing begins.
  388.  
  389. ut                             Turn off trace mode.
  390.  
  391. ts                             Make trace run silently.  Nothing is printed by
  392.                                __debug_proc when in trace mode.  Note that "ts"
  393.                                does not turn trace mode on or off.  It is only
  394.                                meaningful when trace mode is activated.
  395.  
  396. tv                             Make trace run verbosely (default).  The normal
  397.                                information is printed by __debug_proc when in
  398.                                trace mode.  Note that "tv" does not turn trace
  399.                                mode on or off.  It is only meaningful when trace
  400.                                mode is activated.
  401.  
  402. sbp integer [integer]... Set each of the specified line numbers as trace
  403.                          breakpoints.  The debug interpreter will not complain if
  404.                          you set non-existent lines as breakpoints.  It will
  405.                          simply have no effect.  
  406.  
  407. ubp integer [integer]... Unset each of the specified trace breakpoints.
  408.  
  409. pbp                            Print the line numbers of all current breakpoints.
  410.  
  411. nd                             Exit DEBUG immediately and (seemingly) do not
  412.                                return to DEBUG later unless __nodebug has been
  413.                                set to &null by the program.  This essentially
  414.                                disables debug processing and allows the program
  415.                                to execute normally.  Note that __debug_proc is
  416.                                still called prior to each line execution.  It
  417.                                just exits immediately when called.
  418.  
  419. ?, h, help               Print a list of DEBUG interpreter commands.
  420.  
  421. stop                           Immediately exit DEBUG and the program.
  422.  
  423. blank or empty line            Return to the program.  If trace mode is on then
  424.                                DEBUG status information will print prior to the
  425.                                execution of each program line until a breakpoint
  426.                                is encountered.  Otherwise the DEBUG interpreter
  427.                                will be invoked prior to the execution of each
  428.                                program line.
  429.  
  430. A number of global variables are provided by __debug_proc which may be changed or
  431. inspected by the debugified program.
  432.  
  433. __trace                        This variable reflects the trace state.  It
  434.                                contains a non-null value when trace mode is
  435.                                active and &null when trace mode is off.  The
  436.                                program may assign a value to __trace to change
  437.                                the trace state.
  438.  
  439.  __nodebug               If the program sets __nodebug to a non-null value, then
  440.                          debug is disabled.  This is the same as entering the
  441.                          "nd" command when in the debug interpreter.
  442.  
  443. __debug_in               This is the input file from which __debug_proc requests
  444.                          input.  The program may change the debug input file via
  445.                          a statement like
  446.                   __debug_in := open(file_name, "r")
  447.  
  448.                                See the discussion of the DEBUG_IN environment
  449.                                variable below.  
  450.  
  451. __debug_out              This is the output file into which __debug_proc writes
  452.                          all its output.  The program may change the debug output
  453.                          file via a statement like
  454.                   __debug_out:= open(file_name, "w")
  455.  
  456.                                See the discussion of the DEBUG_OUT environment
  457.                                variable below.
  458.  
  459. __trace_silent                 Setting this variable to a non-null value has the
  460.                                same effect as executing the "ts" command in the
  461.                                debug interpreter.  Conversely assigning &null to
  462.                                it corresponds to "tv".
  463.  
  464. The following environment variables are recognized by __debug_proc:
  465.  
  466. TRACEINIT         If this environment variable is set, then the program will
  467.                   start in trace mode.  There will be no human interaction with
  468.                   the debug interpreter.
  469.  
  470. DEBUG_IN          This environment variable can be set to specify the name of
  471.                   the file from which the debug interpreter will get its input. 
  472.                   If it is not set, then __debug_proc assumes a system-dependent
  473.                   default.  For MS-DOS the default is "CON".  For UNIX, it is
  474.                   "/dev/tty".  For other systems, it defaults to the ICON &input
  475.                   value.
  476.  
  477. DEBUG_OUT         This environment variable can be set to specify the name of
  478.                   the file to which the debug interpreter writes its output.  If
  479.                   it is not set, then __debug_proc assumes a system-dependent
  480.                   default.  For MS-DOS the default is "CON".  For UNIX, it is
  481.                   "/dev/tty".  For other systems, it defauls to the ICON &output
  482.                   value.
  483.  
  484.  
  485. If your system does not support environment variables and &input and &output are
  486. not satisfactory I/O debug devices, it may be tempting to specifiy initial debug
  487. I/O devices by having your program open up __debug_in and __debug_out.  Remember
  488. that if your main procedure is DEBUGIFYed, then __debug_proc will access its I/O
  489. devices before the first program statement is executed.  You might consider not
  490. DEBUGIFYing your main procedure, but opening __debug_in and __debug_out prior to
  491. the first invocation of a DEBUGIFYed procedure.
  492.  
  493. 6     VERSION HISTORY
  494.  
  495. Version 1.01             9/6/92.  Added DEBCFG.ICN and changed DEBUGIFY to allow
  496.                          it to be configured for particular Icon version.  Thanks
  497.                          to David Kuhlman for uncovering problem.
  498.  
  499. Version 1.00             11/29/91.  Initial release.
  500.  
  501. 7     ACKNOWLEDGMENT
  502.  
  503. I wish to thank David Kuhlman for uncovering differences in keyword tokens
  504. between ucode files for different versions of Icon.
  505.  
  506. 8     RIGHTS/DISTRIBUTION
  507.  
  508. DEBUGIFY, DEBUG, and DEBCFG are public domain software with one restriction: 
  509. Source code files and any accompanying documentation must indicate that I am the
  510. original author.  Other than that, you can do whatever you wish with the source
  511. code.  It may be freely distributed and/or modified.
  512.