6.26.4.6 High-Level Traps

The low-level trap API allows one to make traps that call procedures, and the trap state API allows one to keep track of what traps are there. But neither of these APIs directly helps you when you want to set a breakpoint, because it’s unclear what to do when the trap fires. Do you enter a debugger, or mail a summary of the situation to your great-aunt, or what?

So for the common case in which you just want to install breakpoints, and then have them all result in calls to one parameterizable procedure, we have the high-level trap interface.

Perhaps we should have started this section with this interface, as it’s clearly the one most people should use. But as its capabilities and limitations proceed from the lower layers, we felt that the character-building exercise of building a mental model might be helpful.

These procedures share a module with trap states:

(use-modules (system vm trap-state))
Scheme Procedure: with-default-trap-handler handler thunk

Call thunk in a dynamic context in which handler is the current trap handler.

Additionally, during the execution of thunk, the VM trace level (see VM Hooks) is set to the number of enabled traps. This ensures that traps will in fact fire.

handler may be #f, in which case VM hooks are not enabled as they otherwise would be, as there is nothing to handle the traps.

The trace-level-setting behavior of with-default-trap-handler is one of its more useful aspects, but if you are willing to forgo that, and just want to install a global trap handler, there’s a function for that too:

Scheme Procedure: install-trap-handler! handler

Set the current thread’s trap handler to handler.

Trap handlers are called when traps installed by procedures from this module fire. The current “consumer” of this API is Guile’s REPL, but one might easily imagine other trap handlers being used to integrate with other debugging tools.

Scheme Procedure: add-trap-at-procedure-call! proc

Install a trap that will fire when proc is called.

This is a breakpoint.

Scheme Procedure: add-trace-at-procedure-call! proc

Install a trap that will print a tracing message when proc is called. See Tracing Traps, for more information.

This is a tracepoint.

Scheme Procedure: add-trap-at-source-location! file user-line

Install a trap that will fire when control reaches the given source location. user-line is one-indexed, as users count lines, instead of zero-indexed, as Guile counts lines.

This is a source breakpoint.

Scheme Procedure: add-ephemeral-trap-at-frame-finish! frame handler

Install a trap that will call handler when frame finishes executing. The trap will be removed from the trap state after firing, or on nonlocal exit.

This is a finish trap, used to implement the “finish” REPL command.

Scheme Procedure: add-ephemeral-stepping-trap! frame handler [#:into?] [#:instruction?]

Install a trap that will call handler after stepping to a different source line or instruction. The trap will be removed from the trap state after firing, or on nonlocal exit.

If instruction? is false (the default), the trap will fire when control reaches a new source line. Otherwise it will fire when control reaches a new instruction.

Additionally, if into? is false (not the default), the trap will only fire for frames at or prior to the given frame. If into? is true (the default), the trap may step into nested procedure invocations.

This is a stepping trap, used to implement the “step”, “next”, “step-instruction”, and “next-instruction” REPL commands.