PREV UP NEXT SCM

3.8: Debugging Scheme Code

The cautious and stack-limit options of build (see Build Options) support 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).

STACK_LIMIT
If SCM is built with the `STACK_LIMIT' flag, the interpreter will check stack size periodically. If the size of stack exceeds a certain amount (default is HEAP_SEG_SIZE/2), SCM generates a segment violation interrupt.

The usefulness of `STACK_LIMIT' depends on the user. I don't use it; but the user I added this feature for got primarily this type of error.

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:

Procedure: 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 '<proc-name>' and `)' around an expression in order to see its value as a program operates.

Syntax: print-args name1 ...
Writes name1 ... (separated by spaces) and then writes the 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.

ftp-swiss.ai.mit.edu:pub/scm/slib-psd1-3.tar.gz
prep.ai.mit.edu:pub/gnu/jacal/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