Next: , Previous: Editing Scheme Code, Up: Operational Features


3.8 Debugging Scheme Code

The cautious option of build (see Build Options) supports debugging in Scheme.

CAUTIOUS
If SCM is built with the ‘CAUTIOUS’ flag, then when an error occurs, a stack trace of certain pending calls are printed as part of the default error response. A (memoized) expression and newline are printed for each partially evaluated combination whose procedure is not builtin. See Memoized Expressions for how to read memoized expressions.

Also as the result of the ‘CAUTIOUS’ flag, both error and user-interrupt (invoked by <C-c>) to print stack traces and conclude by calling breakpoint (see Breakpoints) instead of aborting to top level. Under either condition, program execution can be resumed by (continue).

In this configuration one can interrupt a running Scheme program with <C-c>, inspect or modify top-level values, trace or untrace procedures, and continue execution with (continue).

If verbose (see verbose) is called with an argument greater than 2, then the interpreter will check stack size periodically. If the size of stack in use exceeds the C #define STACK_LIMIT (default is HEAP_SEG_SIZE), SCM generates a ‘stacksegment violation.

There are several SLIB macros which so useful that SCM automatically loads the appropriate module from SLIB if they are invoked.

— Macro: trace proc1 ...

Traces the top-level named procedures given as arguments. — Macro: trace

With no arguments, makes sure that all the currently traced identifiers are traced (even if those identifiers have been redefined) and returns a list of the traced identifiers.

— Macro: untrace proc1 ...

Turns tracing off for its arguments. — Macro: untrace

With no arguments, untraces all currently traced identifiers and returns a list of these formerly traced identifiers.

The routines I use most frequently for debugging are:

— Function: print arg1 ...

Print writes all its arguments, separated by spaces. Print outputs a newline at the end and returns the value of the last argument.

One can just insert ‘(print '<label>’ and ‘)’ around an expression in order to see its values as a program operates.

— Function: pprint arg1 ...

Pprint pretty-prints (see Pretty-Print) all its arguments, separated by newlines. Pprint returns the value of the last argument.

One can just insert ‘(pprint '<label>’ and ‘)’ around an expression in order to see its values as a program operates. Note pretty-print does not format procedures.

When typing at top level, pprint is not a good way to see nested structure because it will return the last object pretty-printed, which could be large. pp is a better choice.

— Procedure: pp arg1 ...

Pprint pretty-prints (see Pretty-Print) all its arguments, separated by newlines. pp returns #<unspecified>.

— Syntax: print-args name
— Syntax: print-args

Writes name if supplied; then writes the names and values of the closest lexical bindings enclosing the call to Print-args.

          (define (foo a b) (print-args foo) (+ a b))
          (foo 3 6)
          -| In foo: a = 3; b = 6;
          ⇒ 9

Sometimes more elaborate measures are needed to print values in a useful manner. When the values to be printed may have very large (or infinite) external representations, Quick Print, can be used.

When trace is not sufficient to find program flow problems, SLIB-PSD, the Portable Scheme Debugger offers source code debugging from GNU Emacs. PSD runs slowly, so start by instrumenting only a few functions at a time.

     http://groups.csail.mit.edu/mac/ftpdir/scm/slib-psd1-3.tar.gz
     ftp.maths.tcd.ie:pub/bosullvn/jacal/slib-psd1-3.tar.gz
     ftp.cs.indiana.edu:/pub/scheme-repository/utl/slib-psd1-3.tar.gz