This section describes additional commands that are useful for debugging.
Sets a breakpoint. When the breakpoint is encountered, datum and
the arguments are typed (just as for
error) and a
read-eval-print loop is entered. The environment of the read-eval-print
loop is derived by examining the continuation of the call to
bkpt; if the call appears in a non-tail-recursive position, the
environment will be that of the call site. To exit from the breakpoint
and proceed with the interrupted process, call the procedure
continue. Sample usage:
1 ]=> (begin (write-line 'foo) (bkpt 'test-2 'test-3) (write-line 'bar) 'done) foo test-2 test-3 ;To continue, call RESTART with an option number: ; (RESTART 2) => Return from BKPT. ; (RESTART 1) => Return to read-eval-print level 1. 2 bkpt> (+ 3 3) ;Value: 6 2 bkpt> (continue) bar ;Value: done
pp procedure is described in Output Procedures in MIT/GNU Scheme Reference Manual. However, since this is a very
useful debugging tool, we also mention it here.
pp provides two
very useful functions:
ppwill print the source code of a given procedure. Often, when debugging, you will have a procedure object but will not know exactly what procedure it is. Printing the procedure using
ppwill show you the source code, which greatly aids identification.
ppwill print the fields of a record structure. If you have a compound object pointer, print it using
ppto see the component fields, like this:
(pp (->pathname "~")) -| #[pathname 14 "/usr/home/cph"] -| (host #[host 15]) -| (device unspecific) -| (directory (absolute "usr" "home")) -| (name "cph") -| (type ()) -| (version unspecific)
When combined with use of the
pp provides the
functionality of a simple object inspector. For example, let’s look at
the fields of the host object from the above example:
(pp #@15) -| #[host 15] -| (type-index 0) -| (name ())
pa prints the arguments of procedure. This can be used to
remind yourself, for example, of the correct order of the arguments to a
for-all? ⇒ #[compiled-procedure 40 ("boole" #x6) #xC #x20ECB0] (pa for-all?) -| (items predicate) (pp for-all?) -|(named-lambda (for-all? items predicate) -| (let loop ((items items)) -| (or (null? items) -| (and (predicate (car items)) -| (loop (cdr items))))))
where enters the environment examination system.
This allows environments and variable bindings to be examined and
where accepts one-letter commands. The commands can
be found by typing ? to the ‘where>’ prompt. The optional
argument, obj, is an object with an associated environment: an
environment, a procedure, or a promise. If obj is omitted, the
environment examined is the read-eval-print environment from which
where was called (or an error or breakpoint environment if called
from the debugger). If a procedure is supplied,
where lets the
user examine the closing environment of the procedure. This is useful
for debugging procedure arguments and values.
Search an environment for bound names containing string and print
out the matching bound names. If environment is specified, it
must be an environment or package name, and it defaults to the current
REPL environment. The flag search-parents? specifies
whether the environment’s parents should be included in the search. The
#f if environment is specified, and
environment is not specified.
(apropos "search") -| #[package 47 (user)] -| #[package 48 ()] -| list-search-negative -| list-search-positive -| nt-fs-flag/case-sensitive-search -| re-string-search-backward -| re-string-search-forward -| re-substring-search-backward -| re-substring-search-forward -| search-ordered-subvector -| search-ordered-vector -| search-protection-list -| string-search-all -| string-search-backward -| string-search-forward -| substring-search-all -| substring-search-backward -| substring-search-forward -| vector-binary-search