scheme shell
about
download
support
resources
docu
links
 
scsh.net

One of the main features of a sophisticated Scheme implementation is support for debugging. Scheme 48/scsh come with a huge set of tools to ease the daily life of a programmer. This page tries to summarize these tools. Please note, that this page is still under construction.

The inspector

This allows interactive inspection of compound data structures such as lists, records, exceptions and continuations. See the respective section in the Scheme 48 manual for a full description.

Debugger

After an exception occurred you can use the ,debug command to inspect the exception continuation associated with the error:

> (define (f a b) (+ a b))
> (f 'c 4)

Error: exception
       #f
       (+ 'c 4)
1> ,debug
'#{Exception-continuation (pc 16) (+ in scheme-level-0)}

inspect: d
'#{Continuation (pc 25) (evaluate-and-select in command-processor)}

 [0] '#{Procedure 5736 (unnamed in evaluate-and-select in command-processor)}
 [1] '(f 'c 4)
 [2] '#{Package 146 user}

Here, the u and d commands from the inspector become particularly useful to walk along the continuation chain

No backtrace but a preview

The ,preview command will show the continuation frames lying on the stack.See also in the Scheme 48 Manual

Breakpoints

The structure big-util exports the procedure breakpoint , which can be used to set breakpoints. Its argument are a format string and the corresponding arguments. Simply call breakpoint somewhere in your code and when evaluation gets to it, a new command level will be pushed and the formatted string produced from the arguments to breakpoint will be printed. To continue, use the ,proceed command, which assigns a value to the breakpoint expression and lets it return.

Expanding macros

To see the result of macro expansion, you can use the ,expand command:

> ,expand (or 1)
1
> ,expand (or 1 2)
'((lambda (#(>> or temp 1290)) (if #(>> or temp 1290) #(>> or temp 1290) 2)) 1)

Also described in the Scheme 48 manual.

Record disclosers

The procedure define-record-discloser from the package define-record-types lets you specify how records of a certain type are displayed:

,open define-record-types
> (define-record-type foo :foo
  (make-foo bar baz)
  foo?
  (bar foo-bar)
  (baz foo-baz))
> (define-record-discloser :foo
  (lambda (a-foo)
    (list 'foo (foo-bar a-foo) 'entries: (vector-length (foo-baz a-foo)))))
> (define my-foo (make-foo 42 (make-vector 1000 3)))
>  my-foo
'#{Foo 42 entries: 1000}

As the example points out, this feature is particularly useful for showing large data structures.

Spatial

The structure spatial exports several procedures that print statistics about the heap usage:

  • (space) prints a overview according to the types of the objects.
  • (record-space) shows the space used by the various record types.
  • (vector-space) displays heap usage for vectors.
Traverse

The structure traverse contains another utility to detect memory leaks.It will show the accessibility from one object to another.

Call either (traverse-depth-first obj1) or (traverse-breadth-first obj1) ,where obj1 is the source object. Afterwards, (trail obj2) will show via what path obj1 points to obj2 .

Finding objects of a certain type

The structure primitives exports a procedure (find-all stob) , which returns a vector of all VM objects of type stob . The structure architecture exports the enumeration stob , which contains the types of all VM objects.

Perhaps even more useful is the procedure (find-all-records record-type) from the same structure, which returns a vector of all records of a given type.