home *** CD-ROM | disk | FTP | other *** search
- @part[Debug, root "TMAN.MSS"] @Comment{-*-System:TMAN-*-}
- @chap[Debugging]
-
- @label[debugging chapter] @comment{Referred to from user interface chapter.}
-
-
- The facilities described in this chapter are highly
- implementation-specific, and subject to change without notice.
- Facilities described here are intended either for use directly as
- commands, or as utilities for user-written debugging subsystems.
-
-
- @section[Errors]
- @index[Errors]
-
- @label[Errors Interface Section] @Comment{ref: Errors Section}
- @label[dealing section]
-
- When the implementation detects an error condition, a message is printed and
- a read-eval-print loop is entered in the dynamic context in which
- the error occurred. A number of facilities are available at this
- point for debugging and for recovering from the error.
-
- Errors are usually detected in conditions which are left
- undefined by the manual (see sections @ref[undefined semantics section]
- and @ref[errors section]). These conditions include the following:
-
- @itemize[
- An unbound variable is referenced.
-
- A procedure is called with too few or too many arguments.
-
- A non-procedure is called.
-
- An object of the wrong type is passed to a system procedure.
-
- A string or vector index is out of range.
-
- A generic operation is invoked on an object with no method
- to handle it.
-
- The external representation of an object being parsed by @tc[READ-OBJECT]
- or a read macro is syntactically incorrect. (This kind of error
- is called a @i[read error.])
-
- An object being interpreted as an expression by a compiler or a
- macro expander is syntactically incorrect. (This kind of error is
- called a @i[syntax error.])
-
- A call to @tc[ERROR] or @tc[UNDEFINED-EFFECT] occurs.
- ]
-
- Once inside the read-eval-print loop, one may examine the current
- environment (e.g., examining variables or the stack) using the
- read-eval-print loop (section @ref[REPL section]) or the inspector
- (section @ref[inspector section]).
-
- Typical actions after an error occurs include:
- @begin[itemize]
- The user corrects the error by returning a new value
- with @tc[RET].
-
- The user goes up one command level by typing the end-of-file character
- (see page @pageref[end-of-file]).
-
- The user throws to top level by calling @tc[(RESET)] (page @pageref[RESET]).
- @end[itemize]
-
- Example:
- @begin[ProgramExample]
- > (CADR 3)
-
- ** Error: attempting to take CADR of 3
- >> (RET '(A B))
- B
- > (PLUS 3 4)
-
- ** Error: variable PLUS has no value
- >> (RET ADD)
- 7
- @end[ProgramExample]
-
- @dc[Talk about errors from compiled code.]
-
- @info[notes="Settable"]
- @desc[(RECKLESSNESS) @yl[] LOW, MEDIUM, @r[or] HIGH]
- Doing @tc[(SET (RECKLESSNESS) 'HIGH)] will improve performance at
- the expense of error-checking. Specifically, somewhere between 10
- and 25 instructions will be elided from most procedure calls, but
- wrong-number-of-argument, undefined-procedure, and object-not-applicable
- errors will probably cause illegal memory references or odd address
- errors instead of more comprehensible error reports.
- @EndDesc[RECKLESSNESS]
-
-
- @section[Debugging utilities]
-
- @info[NOTES="Special form"]
- @desc[(TRACE @i[variable]) @yl[] @i[undefined]]
- Reassigns @i[variable], whose value should be a procedure,
- to be a new procedure which prints information on the
- @tc[(DEBUG-OUTPUT)] stream whenever it is called or returns a value.
- @EndDesc[TRACE]
-
- @info[NOTES="Special form"]
- @desc[(UNTRACE @i[variable]) @yl[] @i[undefined]]
- If @i[variable] has a traced procedure as its value,
- @tc[UNTRACE] restores it to its original value.
- Otherwise it prints a warning and does nothing.
- @EndDesc[UNTRACE]
-
- @info[NOTES="Special form"]
- @desc[(PP @i[procedure]) @yl[] @i[undefined]]
- Prints the definition of @i[procedure] on the terminal output stream.
- If the source code is not available, then it prints the name of a file
- where it can be found.
- (See also @tc[PRETTY-PRINT], page @pageref[PRETTY-PRINT],
- and @tc[WHERE-DEFINED], page @pageref[WHERE-DEFINED].)
- @EndDesc[PP]
-
- @desc[(BACKTRACE) @yl[] @i[undefined]]
- Prints a one-line summary describing each continuation on the stack.
- @index[continuations]
- See also @tc[DEBUG], page @pageref[DEBUG].
- @EndDesc[BACKTRACE]
-
-
- @section[The inspector]
- @label[inspector section]
-
- @tc[CRAWL], also known as the @iix[inspector],
- is a stack and structure inspector.
- It consists of a command loop and a set of commands.
- The inspector keeps track of a @i[current object], and a stack of
- objects which have previously been current objects. Some inspector
- commands move from one object to another.
-
- The command loop operates as follows: the current object is
- @qu"summarized" (that is, printed or displayed somehow); a prompt is
- printed; a line is read; and any commands on the line are executed.
- One can give one or more commands on a single input line.
-
- The current object may be any object. If it is a continuation (stack frame),
- the name of the procedure which contains the continuation's return point
- is printed, and the prompt is @qu"@tc[debug:]". Otherwise, the object
- is printed (up to a maximum of one line of output),
- and the prompt is @qu"@tc[crawl:]".
- @index[stack]
- @index[frames]
- @index[continuations]
-
- The meanings of some commands vary depending on what kind of object
- the current object is, and not all commands are
- appropriate for all kinds of objects.
-
- @desc[(DEBUG) @yl[] @i[undefined]]
- @tc[(DEBUG)] enters the inspector. The current object becomes a continuation
- near the top of the stack (more precisely, the continuation to which
- the value passed to @tc[RET] will be given).
- @EndDesc[DEBUG]
-
- @desc[(CRAWL @i[object]) @yl[] @i[undefined]]
- Enters the inspector. The current object becomes @i[object].
- @EndDesc[CRAWL]
-
- Inspector commands:
-
- @begin[Description]
- @tc[?]@\@i[Help:] prints a list of inspector commands, with one-line
- summaries.
-
- @tc[Q]@\@i[Quit:] exits out of the inspector, usually back to the
- read-eval-print loop.
-
- @tc[U]@\@i[Up:] pops the stack of saved objects. The current object is
- forgotten, and the inspector moves to the previous current object.
-
- @tc[D]@\@i[Down:] if the current object is a continuation,
- moves to the next continuation deeper in the stack, that is, to the
- continuation that
- was pushed prior to the current continuation.
-
- @begin[multiple]
- @tc[X]@\@i[Exhibit:] prints useful information about the current object.
- The exact behavior of this varies depending on the type of the object.
- For structures, all of the structure's components are displayed.
- For continuations, any saved values are printed. Integers are printed
- in various radices.
-
- For some kinds of object, such as structures and vectors, the contents
- of an object will be displayed in a menu form, as a sequence of lines of
- the form
- @w[@qu"@tc<[@i[key]] @i[component]>"].
- In this case, giving @i[key] as an inspector command will move to
- @i[component], which then becomes the current object.
- @end[multiple]
-
- @i[integer]@\@i[Select element:] in the case of a list or vector,
- this moves to the appropriate component. For example, if the current object
- is a list, then @tc[3] as an inspector command is the same as @tc[A CADDDR]:
- it moves to the list's fourth element.
-
- @i[selector]@\@i[Select component:] if the current object is a structure,
- typing a selector name will move to that component of the structure.
-
- @tc[B]@\@i[Breakpoint:] enters a read-eval-print loop. Executing
- @tc[(RET)] will return back into the inspector. The read-eval-print
- loop will execute either in @tc[(REPL-ENV)], or, if the current object
- is a continuation or procedure created by interpreted code (i.e. code
- compiled by the standard compiler, as opposed to TC), in the lexical
- environment of the object. Inside the breakpoint loop, the system
- variable @tc[*OBJ*] is bound to the current object.
-
- @tc[C]@\@i[Crawl:] moves to a new object. The
- object is obtained by evaluating an input expression, which is
- read either from the command line or in response to a prompt.
- The environment of the evaluation is one appropriate to
- the current object, as with the @tc[B] command.
-
- @tc[E]@\@i[Evaluate:] evaluates an expression. The expression is read
- and evaluated as
- with the @tc[C] command. The result of the evaluation is printed, but
- the current object remains the same.
-
- @tc[A]@\@i[Apply:] applies a procedure to the current object, and move to the
- result of that call. An expression evaluating to the procedure is
- read as with the @tc[C] command.
-
- @tc[M]@\@i[Macroexpand:] performs one macro expansion on the current
- object, which should be a list, and the current object becomes the result
- of the macro expansion.
- @index[Macros]
-
- @tc[P]@\@i[Pretty-print:] prints the current object using the pretty
- printer.
- If the current object is a continuation, then this command tries to
- print the expression to which the value returned by the continuation
- is to be supplied.
-
- @tc[R]@\@i[Return:] if the current object is a continuation, returns a
- value to it. The value is obtained as with the @tc[C],
- @tc[E], and @tc[A] commands.
-
- @comment{ not implemented in 2.7.
- @tc[R]@\@i[Right:] if the current object is a list, this is the same
- as @tc[A CDR]: that is, it moves to the list's cdr.
- }
-
- @tc[W]@\@i[Where-defined:] prints the result of calling @tc[WHERE-DEFINED]
- on the current object.
-
- @tc[V]@\@i[Unit:] moves to a template's or procedure's
- unit. Units are not documented, but the @tc[X] command works with them.
- This command is intended primarily for the use of the @Timp[] implementors.
- @end[Description]
-
- The control stack which one inspects by invoking the
- inspector with @tc[(DEBUG)] is a sequence of continuations, or stack
- frames. These differ from activation records in implementations of
- languages such as C or Lisp in that they represent future computations
- rather than past calls. A full call history is not easily
- available in tail-recursive languages such a @Tau[] and Scheme.
- This is implementation-dependent, of course, and future @Tau[]
- implementations may maintain call histories for debugging purposes.
-
- Each continuation represents a control point which will make use of
- the value returned to the continuation. Usually these control points
- correspond to the arguments in a call, the predicate in an @tc[IF]
- or @tc[COND], or any but the last subform of a block. For example,
- when evaluating a call, a continuation is constructed for each argument
- in the call, because these values will be used when the call actually
- occurs. In the example below, the continuations into @tc[FACT] were
- mostly delivering values to the second argument position in the call
- to @tc[*].
-
- The three-column synopsis that the inspector prints for continuations
- is the same as that printed by @tc[BACKTRACE] (page
- @pageref[BACKTRACE]). The first column is the name of the procedure
- into which control will return, or @tc[(anonymous)] if no procedure
- name is available (as for procedures created by anonymous top-level
- @tc[LAMBDA]-expressions instead of by @tc[DEFINE]). The second column
- is the name of the source file containing the procedure, and the third
- column is relevant source code, if available.
-
- Here is a sample interaction with the inspector.
- Commentary is in Roman font on the right.
- The terms @qu"frame," @qu"stack frame," and @qu"continuation" are
- used interchangeably.
- @begin[ProgramExample]
- > (define (fact n) @r[Define factorial function.]
- (cond ((= n 0) i) @r[Bug: @tc[i] instead of @tc[1].]
- (else (* n (fact (- n 1))))))
- #{Procedure 120 FACT}
- > (fact 4)
-
- ** Error: variable I is unbound @r[Error detected by interpreter.]
- >> (debug)
- #{Continuation 121} @r[Current object is this frame.]
- BIND-INTERNAL THROW @r[Internal to the implementation.]
- debug: d @r[Go down one frame.]
- #{Dynamic-state-transition 122} @r[Also internal, keep going.]
- debug: d
- #{Continuation 123}
- FACT () I @r[Okay, this looks good.]
- debug: d
- #{Continuation 124}
- FACT () (* N (FACT (- N 1)))
- debug: e n @r[Evaluate @tc[N] in this frame.]
- 1 @r[Value is 1.]
- debug: d
- #{Continuation 125}
- FACT () (* N (FACT (- N 1)))
- debug: e n @r[Value is 2 in this frame.]
- 2
- debug: d d @r[Go down two frames.]
- #{Continuation 126}
- FACT () (* N (FACT (- N 1)))
- debug: d
- #{Continuation 127}
- READ-EVAL-PRINT-LOOP REPL @r[@tc[FACT]'s caller (i.e. top level).]
- debug: u u u u u @r[Up five frames.]
- #{Continuation 123}
- FACT () I
- debug: r 1 @r[Return the value 1 to this frame.]
- 24 @r[Execution proceeds, and the value]
- > @r[24 comes out.]
- @end[ProgramExample]
-
-
-
- @section[Debugging primitives]
-
- This section describes routines which may be useful in writing debugging
- aids. Note that they are not part of the language, and therefore should be
- avoided in @qu"ordinary" programs. Relying on these routines may lead
- to programs which behave differently depending on how the programs
- are compiled (TC or standard compiler), or which fail to work
- across releases.
-
- @info[NOTES="Operation"]
- @desc[(WHERE-DEFINED @i[object]) @yl[] @i[filename]]
- Tries to find a filename for the source file wherein
- @i[object] (usually a procedure) is defined.
- @EndDesc[WHERE-DEFINED]
-
- @info[NOTES="Operation"]
- @desc[(IDENTIFICATION @i[object]) @yl[] @i[symbol] @r[or] @i[false]]
- If appropriate, this returns a symbol naming a variable which, in some
- environment, might be defined to be the @i[object]. If no such
- identification is appropriate, @tc[IDENTIFICATION] returns false. This
- behavior is heuristic, not contractual; for no value is @tc[IDENTIFICATION]
- required to return non-null.
-
- @begin[ProgramExample]
- (IDENTIFICATION CADR) @ev[] CADR
- (LET ((X CADR)) (IDENTIFICATION X)) @ev[] CADR
- @end[ProgramExample]
- @EndDesc[IDENTIFICATION]
-
- @info[NOTES="Operation"]
- @desc[(ARGSPECTRUM @i[procedure]) @yl[] @i[pair]]
- Returns an @i[argspectrum] for @i[procedure]. An argspectrum is a pair
- @wt[(@i[min] . @i[max])] which describes the number of arguments that
- @i[procedure] expects to receive when called. @i[Min] is always an
- integer giving the minimum number of arguments expected; @i[max] is
- either an integer giving a maximum, or it is @tc[()], meaning that exactly
- @i[min] arguments are required, or it is @tc[T], meaning that any number
- of arguments (but at least @i[min]) are acceptable. @dc[This convention
- seems pretty random; suggest something better.]
- @EndDesc[ARGSPECTRUM]
-
- @desc[(DISCLOSE @i[procedure]) @yl[] @i[list] @r[or] @i[false]]
- Attempts to reconstruct a source expression from which @i[procedure]
- may have been compiled. This may work for code compiled using the
- standard compiler, but is likely to fail to work for code compiled using
- TC. Returns false if no source code can be obtained.
- @EndDesc[DISCLOSE]
-
- @desc[(GET-ENVIRONMENT @i[procedure]) @yl[] @i[environment] @r[or] @i[false]]
- Attempts to reconstruct an environment in which @i[procedure]
- may have been loaded (or run). This may work for code compiled using the
- standard compiler, but is likely to fail to work for code compiled using
- TC. Returns false if no environment can be obtained.
- @EndDesc[GET-ENVIRONMENT]
-
- @desc[(STRUCTURE-TYPE @i[object]) @yl[] @i[stype] @r[or] @i[false]]
- If @i[object] is a structure, this returns the structure type of which
- it is an instance. If @i[object] is not a structure, it returns false.
- @tc[STRUCTURE-TYPE] is to be used with care since it may violate the
- data protection otherwise provided by structure types. That is, anyone
- who is given a structure may find out about its internals.
- @EndDesc[STRUCTURE-TYPE]
-
- @info[EQUIV="MAPATOMS"]
- @desc[(WALK-SYMBOLS @i[procedure]) @yl[] @i[undefined]]
- Calls @i[procedure] on every accessible symbol.
- @EndDesc[WALK-SYMBOLS]
-
-
- @section[Miscellaneous]
-
- @desc[*T-VERSION-NUMBER* @yl[] @i[integer]]
- An integer which gives the version number of the currently running @Tau[]
- implementation.
- The integer has the form
- @begin[ProgramExample]
- (+ (* @i[major-version-number] 1000) @i[minor-version-number])
- @end[ProgramExample]
- For example, in @Timp[] 2.7, @tc[*T-VERSION-NUMBER*] is @tc[2007]. Knowledge
- of the version number may be useful in dealing with
- incompatibilities between @Timp[] releases, so that programs may
- conditionally adjust their state according to the version, and thus
- be able to run in both older and newer releases.
- @enddesc[*T-VERSION-NUMBER*]
-
- @desc[*T-IMPLEMENTATION-ENV* @yl[] @i[locale]]
- This environment contains variables internal to the implementation of
- @Tau[].
- @begin[ProgramExample]
- (IMPORT *T-IMPLEMENTATION-ENV* %%PAIR-TAG)
- @end[ProgramExample]
- @enddesc[*T-IMPLEMENTATION-ENV*]
-
- @desc[*TC-ENV* @yl[] @i[locale]]
- This environment contains variables internal to the implementation
- of TC.
- @EndDesc[*TC-ENV*]
-
- @desc[(GC) @yl[] @i[undefined]]
- Invokes the garbage collector.@index[Garbage collection]
- Garbage collection is a low-level process by which the memory used by
- objects which are no longer accessible is reclaimed for use by new
- objects.
- Ordinarily, garbage collection is invoked asynchronously as the need
- arises, so explicit calls to @tc[GC] are unnecessary.
-
- A side-effect of garbage collection is that any streams created by
- @tc[OPEN] which are both inaccessible and still open, are closed.
-
- See also section @ref[OBJECT-HASH].
- @EndDesc[GC]
-
- @desc[(GC-STATS) @yl[] @i[undefined]]
- Prints some statistics about the most recent garbage collection.
- @EndDesc[GC-STATS]
-
- @info[NOTES="Settable"]
- @desc[(GC-NOISILY?) @yl[] @i[boolean]]
- Switch, initially true. If true, then the garbage collector will print
- messages when invoked. If false, it will do its work silently.
- @EndDesc[GC-NOISILY?]
-