6.26.4.4 Tracing Traps

The (system vm trace) module defines a number of traps for tracing of procedure applications. When a procedure is traced, it means that every call to that procedure is reported to the user during a program run. The idea is that you can mark a collection of procedures for tracing, and Guile will subsequently print out a line of the form

|  |  (procedure args …)

whenever a marked procedure is about to be applied to its arguments. This can help a programmer determine whether a function is being called at the wrong time or with the wrong set of arguments.

In addition, the indentation of the output is useful for demonstrating how the traced applications are or are not tail recursive with respect to each other. Thus, a trace of a non-tail recursive factorial implementation looks like this:

scheme@(guile-user)> (define (fact1 n) 
                       (if (zero? n) 1
                           (* n (fact1 (1- n)))))
scheme@(guile-user)> ,trace (fact1 4)
trace: (fact1 4)
trace: |  (fact1 3)
trace: |  |  (fact1 2)
trace: |  |  |  (fact1 1)
trace: |  |  |  |  (fact1 0)
trace: |  |  |  |  1
trace: |  |  |  1
trace: |  |  2
trace: |  6
trace: 24

While a typical tail recursive implementation would look more like this:

scheme@(guile-user)> (define (facti acc n)
                       (if (zero? n) acc
                           (facti (* n acc) (1- n))))
scheme@(guile-user)> (define (fact2 n) (facti 1 n))
scheme@(guile-user)> ,trace (fact2 4)
trace: (fact2 4)
trace: (facti 1 4)
trace: (facti 4 3)
trace: (facti 12 2)
trace: (facti 24 1)
trace: (facti 24 0)
trace: 24

The low-level traps below (see Low-Level Traps) share some common options:

#:width

The maximum width of trace output. Trace printouts will try not to exceed this column, but for highly nested procedure calls, it may be unavoidable. Defaults to 80.

#:vm

The VM on which to add the traps. Defaults to the current thread’s VM.

#:prefix

A string to print out before each trace line. As seen above in the examples, defaults to "trace: ".

To have access to these procedures, you’ll need to have imported the (system vm trace) module:

(use-modules (system vm trace))
Scheme Procedure: trace-calls-to-procedure proc [#:width] [#:vm] [#:prefix]

Print a trace at applications of and returns from proc.

Scheme Procedure: trace-calls-in-procedure proc [#:width] [#:vm] [#:prefix]

Print a trace at all applications and returns within the dynamic extent of calls to proc.

Scheme Procedure: trace-instructions-in-procedure proc [#:width] [#:vm]

Print a trace at all instructions executed in the dynamic extent of calls to proc.

In addition, Guile defines a procedure to call a thunk, tracing all procedure calls and returns within the thunk.

Scheme Procedure: call-with-trace thunk [#:calls?=#t] [#:instructions?=#f] [#:width=80]

Call thunk, tracing all execution within its dynamic extent.

If calls? is true, Guile will print a brief report at each procedure call and return, as given above.

If instructions? is true, Guile will also print a message each time an instruction is executed. This is a lot of output, but it is sometimes useful when doing low-level optimization.

Note that because this procedure manipulates the VM trace level directly, it doesn’t compose well with traps at the REPL.

See Profile Commands, for more information on tracing at the REPL.