The <step-trap>
class implements traps that do single-stepping
through a program's execution. They come in two flavours, with and
without a specified file name. If a file name is specified, the trap
is triggered by the next evaluation, application or frame exit
pertaining to source code from the specified file. If a file name is
not specified, the trap is triggered by the next evaluation,
application or frame exit from any file (or for code whose source
location was not recorded), in other words by the next evaluator step
of any kind.
The design goal of the <step-trap>
class is to match what a
user would intuitively think of as single-stepping through their code,
either through code in general (roughly corresponding to GDB's
step
command, for example), or through code from a particular
source file (roughly corresponding to GDB's next
). Therefore
if you are using a step trap to single-step through code and finding
its behaviour counter-intuitive, please report that so we can improve
it.
The implementation and options of the <step-trap>
class are
complicated by the fact that it is unreliable to determine whether a
low level frame exit trap is applicable to a specified file by
examining the details of the reported frame. This is a consequence of
tail recursion, which has the effect that many frames can be removed
from the stack at once, with only the outermost frame being reported
by the low level trap call. The effects of this on the
<step-trap>
class are such as to require the introduction of
the strange-looking #:exit-depth
option, for the following
reasons.
<step-trap>
class is installed from the context of an application or evaluation
frame entry, the #:exit-depth
option should be used to specify
this stack depth.
#:exit-depth
option is not needed and should be
omitted or set to #f
.
When a step trap is installed without #:single-shot #t
, such
that it keeps firing, the <step-trap>
code automatically
updates its idea of the #:exit-depth
setting each time, so that
the trap always fires correctly for the following step.
If not
#f
, this is a string containing the name of a source file, and restricts the step trap to evaluation steps within that source file. (Default value#f
.)
If not
#f
, this is a positive integer implying that the next step may be frame exit past the stack depth depth. See the discussion above for more details. (Default value#f
.)
Example:
(install-trap (make <step-trap> #:file-name (frame-file-name (stack-ref stack index)) #:exit-depth (- (stack-length stack) (stack-ref stack index)) #:single-shot #t #:behaviour debug-trap))