123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- \begin{document}
- \begin{Introduction}{Debugging}
- The package \name{RDEBUG} helps you to find bugs in algebraic
- REDUCE programs by making the functions of the PSL package
- \name{DEBUG} available for algebraic mode.
- The following facilities are available:
- Entry-exit trace (\nameref{tr}, \nameref{untr}):
- visualize every call of
- explicitly declared functions, printing their arguments and
- results.
- Assignment trace (\nameref{trst}, \nameref{untrst}):
- report all assignments which
- are executed inside explicitly declared functions. This facility
- is not available for compiled functions.
- Breakpoint (\nameref{br}, \nameref{unbr}):
- interrupt the program execution at
- entry and exit of explicitly declared functions, invoking
- a \nameref{breakloop}.
- Conditional trace (\nameref{trwhen}, \nameref{untrwhen})
- or break (\nameref{brwhen},\nameref{unbrwhen}).
- Rule trace (\nameref{trrl}, \nameref{untrrl}):
- report the arguments and results of a rule whenever it fires.
- You can control the debug output using the operator \nameref{trout}
- and the variable \nameref{trlimit}.
- \end{Introduction}
- %=============================================================
- \begin{Concept}{breakloop}
- \index{debug}
- A \name{break loop} is an interrupt of the program execution
- where control is given temporarily to the terminal for
- entering commands in a standard command - evaluate - print loop.
- When a break occurs, you can inspect the current
- environment or even alter it, and the
- interrupted computation may be terminated or continued.
- A break can be caused
- - by an internal error when the switch \nameref{break} is on,
-
- - by an explicit call of \name{lisp break()},
- - at entry and exit time of a procedure which has been
- declared by \nameref{br}.
- In a break situation the evaluation is stopped temporarily
- and the control returns to the terminal with a special prompt:
- \name{break[1]1:}.
- The number in square brackets counts the break level - it is
- increased when a break occurs inside a break; the normal
- REDUCE statement counter follows. Each break loop supports its
- own statement numbers and input and output buffers.
- After terminating of a break loop the
- previous statement counters and buffers are restored.
- In a break loop all REDUCE commands can be
- entered. Additionally, there is a set of single character commands
- which allow you to control the break environment. All these
- begin with an underscore character:
- \name{\_a;} terminate break and return to the top REDUCE level
- \name{\_c;} continue execution of interrupted procedure
- \name{\_i;} print a backtrace (list of procedures in the
- call hierarchy)
- \name{\_l} \meta{var}; (local) read the content of the local variable
- \meta{var}
- \name{\_m;} print the last (LISP-) error message
- \name{\_q;} terminate the break loop and return to the next
- higher level.
- Global variables can be accessed as usual in the REDUCE language.
- They can also be set to different values in the break loop.
- The inspect values assigned to dummy arguments and scalar variables of
- procedures in the actual call hierarchy, you need a special command
- \name{\_l}. These values cannot be altered in the break loop.
- \begin{Examples}
- procedure p1(x); \\
- begin scalar y1; y1:=x^2; return p2(y1); end;\\
- procedure p2(q); q^2;\\
- br p2;\\
- x:=22;\\
- p1(alpha);\\
- p2 being entered\\
- q: alpha**2$\\
- Break before entering `p2'\\
- break[1]1: x; & 22\\
- break[1]2: _l x; & alpha\\
- break[1]3: _l y1; & alpha^2 \\
- break[1]4: _l q;& alpha^2 \\
- break[1]6: _c;\\
- Break after call `p2', value `(expt (expt alpha 2) 2)'\\
- break[1]1: _c;\\
- &alpha^4\\
- \end{Examples}
- In the corresponding break loop caused by calling \name{p2}
- indirectly via \name{p1}, you can access the global \name{x}, the
- locals \name{x} and \name{y1} of \name{p1} and the \name{q} of
- \name{p2}.
- \end{Concept}
- %=========================================================
- \begin{Operator}{tr}
- \index{trace}\index{debug}
- The command \name{tr} puts one or several procedures to
- under trace. Every time such a function is executed, a message
- is printed during the procedure entry and another one is generated
- at the return time. The entry message records the
- actual procedure arguments equated to the dummy parameter
- names, and at the exit time the procedure value is printed.
- Recursive calls are marked by an indentation and a level number.
- \begin{Syntax}
- \name{tr}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- Here \meta{proc1},\meta{proc2},...,\meta{procn}
- are names of procedures
- to be added to the set of traced procedures. See also
- \nameref{trst},\nameref{trwhen}.
- \end{Operator}
- \begin{Operator}{untr}
- \index{trace}\index{debug}
- Tracing is stopped for one or several functions by the
- command \name{untr}:
- \begin{Syntax}
- \name{untr}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- \end{Operator}
- %========================================================
- \begin{Operator}{trst}
- \index{trace}\index{assignment-trace}\index{debug}
- Sometimes one needs detailed information about the inner behavior of
- a procedure, especially if it is a longer piece of code.
- For a procedure declared in a \name{trst} command
- an extended trace is performed:
- all executed explicit assignments and all passed labels
- are reported at run time.
- \begin{Syntax}
- \name{trst}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- Here \meta{proc1},\meta{proc2},...,\meta{procn}
- are names of procedures
- to be added to the set of traced procedures.
- When your program contains a \nameref{for} loop,
- REDUCE translates this to a sequential piece of
- LISP instructions. When using \name{trst}, the printout
- is driven by the unfolded code. When the code contains a
- \name{for-each-in} statement, the name of the control variable is
- internally used to keep the remainder of the list during the loop
- control, and you will see the corresponding assignments
- in the printout rather than the individual values in the
- loop steps.
- \end{Operator}
- \begin{Operator}{untrst}
- \index{trace}\index{assignment-trace}\index{debug}
- Extended tracing is stopped for one or several functions by the
- command \name{untrst}:
- \begin{Syntax}
- \name{untrst}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- \end{Operator}
- %=========================================================
- \begin{Operator}{trwhen}
- \index{trace}\index{debug}
- The trace output can be tunrned on or off automatically by
- a boolean expression which is linked to a traced procedure
- by the command \name{trwhen}:
- \begin{Syntax}
- trwhen \meta{name},\meta{booleanexpr};
- \end{Syntax}
- The boolean expression must follow
- standard REDUCE syntax. It may contain references
- to global values and to
- the actual parameters of the procedure. As long as the
- procedure is not compiled, the original names of the dummy arguments
- are used. For a compiled procedure the original names
- are not available; instead the names \name{a1}, \name{a2}, ...
- must be used. Example: the following procedure produces trace
- output only if the main variable of its argument is \name{x}:
- \begin{Examples}
- procedure hugo(u); otto(u);\\
- tr hugo;\\
- trwhen hugo,mainvar(u)=x;\\
- \end{Examples}
- Note: for a symbolic procedure, the \name{trwhen} command
- must be given in symbolic mode or with prefix $symbolic$.
- \end{Operator}
- \begin{Operator}{untrwhen}
- \index{trace}\index{debug}
- Conditional trace is stopped for a procedure by calling
- \begin{Syntax}
- untrwhen \meta{name};
- \end{Syntax}
- \end{Operator}
- %========================================================
- \begin{Switch}{break}
- \index{debug}
- When the switch \name{break} is set on, every
- evaluation error causes a \nameref{breakloop}. Most of these
- breaks are non-continuable; however, you have the
- opportunity to read the actual values of local variables
- in the environment which caused the error.
- \end{Switch}
- %=========================================================
- \begin{Operator}{br}
- \index{break}\index{debug}
- The command \name{br} declares one or several procedures
- as breakpoints. When executing such a function, the
- computation is interrupted by a \nameref{breakloop}
- at function enter and return times.
- \begin{Syntax}
- \name{br}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- Here \meta{proc1},\meta{proc2},...,\meta{procn}
- are names of procedures
- to be added to the set of break points.
- See also \nameref{brwhen}.
- \end{Operator}
- \begin{Operator}{unbr}
- \index{break}\index{debug}
- The break property
- can be removed by the command \name{unbr}:
- \begin{Syntax}
- \name{unbr}\meta{proc1},\meta{proc2},...,\meta{procn};
- \end{Syntax}
- \end{Operator}
- % =============================================================
- \begin{Operator}{brwhen}
- \index{break}\index{debug}
- The break point (see \nameref{br})
- can be tunrned on or off automatically by
- a boolean expression which is linked to a breakpoint procedure
- by the command \name{brwhen}:
- \begin{Syntax}
- brwhen \meta{name},\meta{booleanexpr};
- \end{Syntax}
- The boolean expression must follow
- standard REDUCE syntax. It may contain references
- to global values and to
- the actual parameters of the procedure. As long as the
- procedure is not compiled, the original names of the dummy arguments
- are used. For a compiled procedure the original names
- are not available; instead the names \name{a1}, \name{a2}, ...
- must be used. Example: the following procedure is broken
- only if the main variable of its argument is \name{x}:
- \begin{Examples}
- procedure hugo(u); otto(u);\\
- br hugo;\\
- brwhen hugo,mainvar(u)=x;\\
- \end{Examples}
- Note: for a symbolic procedure, the \name{brwhen} command
- must be given in symbolic mode or with prefix $symbolic$.
- \end{Operator}
- \begin{Operator}{unbrwhen}
- \index{break}\index{debug}
- Conditional break is removed for a procedure by calling
- \begin{Syntax}
- unbrwhen \meta{name};
- \end{Syntax}
- \end{Operator}
- % ==============================================================
- \begin{Operator}{trrl}
- \index{debug}\index{rule}\index{ruleset}
- The command \name{trrl} allows you to trace individual rules
- or rule sets when they fire.
- \begin{Syntax}
- trrl \meta{rs1},\meta{rs2},...,\meta{rsn};
- \end{Syntax}
- where each of the \meta{rsi} is
- - a rule or a rule set,
- - a name of a rule or rule set (that is a non--indexed variable which
- is bound to a rule or rule list),
- - an operator name, representing the rules assigned to this
- operator.
- The specified rules are (re-) activated in REDUCE in
- a style that each of them prints a report every time if fires.
- The report is composed of the name or the rule or the
- name of the rule set plus the number of the rule in the set,
- the form matching the left hand side and the
- resulting right hand side.
- For an explicitly given rule, \name{trrl} assigns a generated name.
- \end{Operator}
- \begin{Operator}{untrrl}
- \index{debug}\index{rule}\index{ruleset}
- With \name{untrrl} you can remove the tracing from rules
- \begin{Syntax}
- untrrl \meta{rs1},\meta{rs2},...,\meta{rsn};
- \end{Syntax}
- The rules are reactivated in their original form. Alternatively
- you can use the command \nameref{clearrules} to remove the
- rules totally from the system. Please do not modify the
- rules between \name{trrl} and \name{untrrl} -- the result
- may be unpredictable.
- \end{Operator}
- %==============================================================
- \begin{Operator}{trout}
- \index{debug}\index{io}
- The trace output can be redirected to a separate file
- by using the command \name{trout}, followed
- by a file name in string quotes. A second call of \name{trout}
- closes the actual output file and assigns a new one.
- The file name NIL (without string quotes) causes the trace output
- to be redirected to the standard output device.
- Remark: under Windows a file name starting with "win:" causes
- a new window to be opened which receives the complete
- output of the debugging services.
- \end{Operator}
- %==============================================================
- \begin{Variable}{trlimit}
- \index{debug}\index{io}
- The integer valued share variable \name{trlimit} defines
- an upper limit for the number of items printed in formula
- collections. The
- initial value is 5. A different value can be assigned to
- increase or lower the output size.
- \begin{Examples}
- trlimit:=7;\\
- \end{Examples}
- \end{Variable}
- %==============================================================
- \begin{Variable}{trprinter}
- \index{debug}\index{io}
- If you want to select LISP style printing instead of
- algebraic printing during trace, set \name{trprinter!*}
- to \name{printx}:
- \begin{Syntax}
- lisp(trprinter!* := 'printx);
- \end{syntax}
- \end{Variable}
|