racket/collects/errortrace/doc.txt
2005-09-15 22:14:19 +00:00

314 lines
12 KiB
Plaintext

[index entries: _debug_ _debugger_ _debugging_
_profile_ _profiler_ _profiling_
_coverage_ ]
_Errortrace_ is a stack-trace-on-exceptions/profiler/coverage tool for
MzScheme. Errortrace is not a complete debugger, and a real debugger
in DrScheme is expected soon; meanwhile, using errortrace might be
better than nothing.
Quick instructions
------------------
0) Throw away .zo versions of your source
1) Prefix your program with
(require (lib "errortrace.ss" "errortrace"))
or start MzScheme with the -M flag:
mzscheme -M errortrace
2) When an exception occurs, the exception handler prints something
like a stack trace, most recent contexts first
The errortrace module is odd; don't import it into another module.
Instead, the errortrace module is meant to be invoked from the
top-level, so that it can install an evaluation handler, exception
handler, etc.
To reuse parts of the code of errortrace, import _errortrace-lib.ss_.
It contains all of the names here but does not set the compilation
handler or the error display handler.
Exception Information
---------------------
Invoking the errortrace.ss module sets the compilation handler to
instrument Scheme source code. It also sets the error display handler
to report source information for an exception, and it sets the
`use-compiled-file-paths' parameter to trigger the use of
errortrace-specific .zo files.
NOTE: errortrace has no effect on code loaded as compiled byte code
(i.e., from a .zo file) or native code (i.e., from a .dll or .so
file). But use the "--mode errortrace" flag to Setup PLT to create
.zo files with errortrace information.
Errortrace's instrumentation can be explicitly disabled via the
`instrumenting-enabled' boolean parameter. Instrumentation is on by
default. The `instrumenting-enabled' parameter affects only the way
that source code is compiled, not the way that exception information
is reported.
> (instrumenting-enabled) - returns #t if error tracing instrumentation is
enabled, #f otherwise
> (instrumenting-enabled on?) - enables/disables error tracing
instrumentation
The instrumentation for storing exception information slows most
programs by a factor of 2 or 3.
Do not load errortrace before writing .zo files. Errortrace
instruments S-expressions with unprintable values; this works fine if
the instrumented S-expression is passed to the default eval handler,
but neither the S-expression nor its byte-code form can be marshalled
to a string.
The `print-error-trace' procedure takes a port and exception and
prints the errortrace-collected debugging information contained in the
exception. It is used by the exception handler installed by
errortrace.
> (print-error-trace output-port exn) - prints the errortrace
information in `exn' to `output-port'.
The `error-context-display-depth' parameter controls how much context
errortrace's exception handler displays. The default value is 10000.
> (error-context-display-depth) - returns the current context display
depth
> (error-context-display-depth d) - sets the context display depth to
`d'
Profiling
---------
Errortrace's profiling instrumentation is off by default. Enable
profiling instrumentation with the `profiling-enabled' boolean
parameter (but setting `instrumentation-enabled' to #f also disables
profiling):
> (profiling-enabled) - returns #t if profiling instrumentation is
enabled, #f otherwise
> (profiling-enabled on?) - enables/disables profiling instrumentation
> (profiling-record-enabled) - returns #t if profiling info is
recorded for instrumented code, #f otherwise; the default is #t
> (profiling-record-enabled on?) - enables/disables the recording of
profiling info (independent of whether newly evaluated code is
instrumented)
Profiling records:
* the number of times a procedure was called.
* the number of milliseconds consumed by the procedure's body across
all calls (including the time consumed by any nested non-tail call
within the procedure, but not including time consumed by a
tail-call from the procedure).
* an inferred name for the procedure.
* the procedure's source in the form of a syntax object (which might,
in turn, provide a source location file and position).
* optionally, information about the procedure call path (something
like the stack trace) for every call to the procedure. Path
information is collected when the `profile-paths-enabled' boolean
parameter is #t; the default is #f, but setting the parameter to #t
immediately affects all procedure instrumented for profiling
information:
> (profile-paths-enabled) - returns #t if profiling collects path
information, #f otherwise
> (profile-paths-enabled on?) - enables/disables collecting path
information for profiling
Profiling information is accumulated in a hash table. If a procedure
is redefined, new profiling information is accumulated for the new
version of the procedure, but the old information is also preserved.
To retrieve all profiling information accumulated so far, call
`get-profile-results':
> (get-profile-results) - returns a list of lists that contain:
* the number of times the procedure was called;
* the number of milliseconds of process time consumed by the
procedure;
* the inferred name or #f of the procedure;
* the syntax source of the procedure; and
* a list of call paths, recorded while `profile-paths-enabled' is
set to #t. Each call path is a list containing two-element lists;
each two-element list contains the calling procedure's name or
source expression and the calling procedure's source file or #f.
Depending of the source program, profiling usually induces a factor of
2 to 4 slowdown (in addition to any slowdown from the exception
information instrumentation).
> (output-profile-results paths? sort-time?)
Gets the current profile results and displays them. It optionally
shows paths information (if it is recorded) and sorts by either time
or call counts.
Coverage
--------
Errortrace can track expression execution that is useful for checking
test coverage (i.e., simple expression coverage). Enable coverage
checking with the `execute-counts-enabled' boolean parameter (but
setting `instrumentation-enabled' to #f also disables execute
counting):
> (execute-counts-enabled) - returns #t if execute-counting
instrumentation is enabled, #f otherwise
> (execute-counts-enabled on?) - enables/disables execute-counting
instrumentation
> (get-execute-counts) - returns a list of pairs, one for each
instrumented expression. The first element of the pair is a syntax
object (usually containing source location information) for the
original expression, and the second element of the pair is the
number of times that the expression has been evaluated. These
elements are destructively modified, so to take a snapshot you will
need to copy them.
> (annotate-executed-file filename-path) - writes the named file to
the current output port, inserting an additional line between each
source line to reflect execution counts (as reported by
`get-execute-counts'). An expression underlined with "^" has been
executed 0 times; an expression underlined with "." has been
executed 1 time; and an expression underlined with "," has been
executed multiple times.
_Re-using errortrace handlers_
-----------------------------------
The _errortrace-lib.ss_ module exports all of the exports of
"errortrace.ss", plus a few more. It does not install any handlers.
The addition exports are as follows:
> (errortrace-compile-handler stx immediate-eval?) - compiles `stx'
using the compilation handler that was active when the
"errortrace-lib.ss" module was executed, but first instruments the
code for errortrace information. The code is instrumented only if
the namespace is the same as when the module was executed. This
procedure is suitable for use as a compilation handler.
> (errortrace-error-display-handler string exn) - displays information
about the exception; this procedure is suitable for use as an error
display handler.
> (errortrace-annotate stx) - macro-expands and instruments the given
top-level form. If the form is a module named `errortrace-key', no
instrumentation is applied. This annotation function is used by
`errortrace-compile-handler'.
> (annotate-top stx) - like `errortrace-annotate', but without the
special case for `errortrace-key'. Also, if `stx' is a module
declaration, it is not enriched with imports to explicitly load
errortrace run-time support.
_Re-using errortrace stack tracing_
-----------------------------------
The errortrace collection also includes a _stacktrace.ss_ library. It
exports the _stacktrace@_ unit and it import signature
_stacktrace-imports^_, and its export signature _stacktrace^_.
The export signature contains these names:
> annotate : syntax boolean -> syntax
> annotate-top : syntax boolean -> syntax
> make-st-mark : syntax -> syntax
> st-mark-source : st-mark -> any
> st-mark-bindings : st-mark -> (listof (list syntax any))
The first two functions annotate expressions with errortrace
information. The `annotate-top' function should be called with a
top-level expression, and `annotate' should be called with a nested
expression (e.g., by `profile-point'). The boolean argument indicates
whether the expression is a transformer expression (#t) or a normal
expression (#f).
The `st-mark-source' and `st-mark-bindings' functions extract
information from a particular kind of value. The value must be
created by `make-st-mark'. `st-mark-source' extracts the value
originally provided to the expression-maker, and `st-mark-bindings'
returns local binding information (if available).
The import signature contains these names:
> with-mark : syntax syntax -> syntax
This procedure is called by `annotate' and `annotate-top' to wrap
expressions with `with-continuation-mark'. The first argument is
the source expression and the second argument is the expression to
be wrapped.
> test-coverage-enabled : (parameter boolean)
This parameter determines if the test coverage annotation is
inserted into the code. This parameter controls how compilation
happens -- it does not affect the dynamic behavior of the already
compiled code. If the parameter is set, calls to test-covered are
inserted into the code (and initialize-test-coverage-point is called
during compilation). If not, no calls to test-covered are inserted.
> test-covered : symbol -> void
During execution of the program, this is called for each point with
the key for that program point that was passed to
initialize-test-coverage-point.
> initialize-test-coverage-point : symbol syntax -> void
During compilation of the program, this function is called with each
sub-expression of the program. The first argument is a special key
used to identify this program point. The second argument is the
syntax of this program point.
> profile-key : symbol
only used for profiling paths.
> profiling-enabled : -> boolean
determines if profiling information is currently collected (affects
the behavior of compiling the code -- does not affect running code).
If this always returns #f, the other profiling functions are never
called.
> initialize-profile-point : symbol (union #f syntax[symbol]) syntax -> void
called as the program is compiled for each profiling point that
might be encountered during the program's execution. The first
argument is a key identifying this code. The second argument is the
inferred name at this point and the final argument is the syntax of
this expression.
> register-profile-start : symbol -> (union #f number)
Called when some profiled code is about to be executed. If the
result is a number, it is expected to be the current number of
milliseconds. The symbol is a key that is unique to this fragment
of code -- it is the same symbol passed to initialize-profile-point
for this code fragment.
> register-profile-done : symbol (union #f number) -> void
This function is called when some profiled code is finished
executing.
Note that register-profile-start and register-profile-done can be
called in a nested manner; in this case, the result of
register-profile-point should be #f.