@page @node Debugger User Interface @chapter Debugger User Interface @c --- The title and introduction of this appendix need to @c distinguish this clearly from the chapter on the internal @c debugging interface. When debugging a program, programmers often find it helpful to examine the program's internal status while it runs: the values of internal variables, the choices made in @code{if} and @code{cond} statements, and so forth. Guile Scheme provides a debugging interface that programmers can use to single-step through Scheme functions and examine symbol bindings. This is different from the @ref{Debugging}, which permits programmers to debug the Guile interpreter itself. Most programmers will be more interested in debugging their own Scheme programs than the interpreter which evaluates them. [FIXME: should we include examples of traditional debuggers and explain why they can't be used to debug interpreted Scheme or Lisp?] @menu * Single-Step:: Execute a program or function one step at a time. * Trace:: Print a report each time a given function is called. * Backtrace:: See a list of the statements that caused an error. * Stacks and Frames:: Examine the state of an interrupted program. @end menu @node Single-Step @section Single-Step @node Trace @section Trace When a function is @dfn{traced}, it means that every call to that function is reported to the user during a program run. This can help a programmer determine whether a function is being called at the wrong time or with the wrong set of arguments. @defun trace function Enable debug tracing on @code{function}. While a program is being run, Guile will print a brief report at each call to a traced function, advising the user which function was called and the arguments that were passed to it. @end defun @defun untrace function Disable debug tracing for @code{function}. @end defun Example: @lisp (define (rev ls) (if (null? ls) '() (append (rev (cdr ls)) (cons (car ls) '())))) @result{} rev (trace rev) @result{} (rev) (rev '(a b c d e)) @result{} [rev (a b c d e)] | [rev (b c d e)] | | [rev (c d e)] | | | [rev (d e)] | | | | [rev (e)] | | | | | [rev ()] | | | | | () | | | | (e) | | | (e d) | | (e d c) | (e d c b) (e d c b a) (e d c b a) @end lisp Note the way Guile indents the output, illustrating the depth of execution at each function call. This can be used to demonstrate, for example, that Guile implements self-tail-recursion properly: @lisp (define (rev ls sl) (if (null? ls) sl (rev (cdr ls) (cons (car ls) sl)))) @result{} rev (trace rev) @result{} (rev) (rev '(a b c d e) '()) @result{} [rev (a b c d e) ()] [rev (b c d e) (a)] [rev (c d e) (b a)] [rev (d e) (c b a)] [rev (e) (d c b a)] [rev () (e d c b a)] (e d c b a) (e d c b a) @end lisp Since the tail call is effectively optimized to a @code{goto} statement, there is no need for Guile to create a new stack frame for each iteration. Using @code{trace} here helps us see why this is so. @node Backtrace @section Backtrace @node Stacks and Frames @section Stacks and Frames When a running program is interrupted, usually upon reaching an error or breakpoint, its state is represented by a @dfn{stack} of suspended function calls, each of which is called a @dfn{frame}. The programmer can learn more about the program's state at the point of interruption by inspecting and modifying these frames. @deffn {Scheme Procedure} stack? obj Return @code{#t} if @var{obj} is a calling stack. @end deffn @deffn {Scheme Procedure} make-stack @end deffn @deffn syntax start-stack id exp Evaluate @var{exp} on a new calling stack with identity @var{id}. If @var{exp} is interrupted during evaluation, backtraces will not display frames farther back than @var{exp}'s top-level form. This macro is a way of artificially limiting backtraces and stack procedures, largely as a convenience to the user. @end deffn @deffn {Scheme Procedure} stack-id stack Return the identifier given to @var{stack} by @code{start-stack}. @end deffn @deffn {Scheme Procedure} stack-ref @end deffn @deffn {Scheme Procedure} stack-length @end deffn @deffn {Scheme Procedure} frame? @end deffn @deffn {Scheme Procedure} last-stack-frame @end deffn @deffn {Scheme Procedure} frame-number @end deffn @deffn {Scheme Procedure} frame-source @end deffn @deffn {Scheme Procedure} frame-procedure @end deffn @deffn {Scheme Procedure} frame-arguments @end deffn @deffn {Scheme Procedure} frame-previous @end deffn @deffn {Scheme Procedure} frame-next @end deffn @deffn {Scheme Procedure} frame-real? @end deffn @deffn {Scheme Procedure} frame-procedure? @end deffn @deffn {Scheme Procedure} frame-evaluating-args? @end deffn @deffn {Scheme Procedure} frame-overflow @end deffn