Next: , Previous: , Up: The language   [Contents][Index]


5.41 Debugging

When you have written a Lisp program you will have to debug it (unless all your programs work first time?). There are two main classes of errors; syntax errors and semantic errors.

Syntax errors occur when the text you’ve typed out to represent your program is not a valid representation of a Lisp object (since a program is simply an ordered set of Lisp objects). When you try to load your program the Lisp reader will find the syntax error and tell you about, unfortunately though it probably won’t be able to tell you exactly where the error is.

The most common source of syntax errors is too few or too many parentheses; the Jade or Emacs Ctrl-Meta-f and Ctrl-Meta-b commands can be used to show the structure of the program as the Lisp reader sees it.

Semantic errors are what we normally call bugs—errors in logic, the program is syntactically correct but doesn’t do what you want it to. For these types of errors librep provides hooks to allow interactive debugging. The debugger supplied with librep uses these hooks to implement a simple command line debugger; programs using librep as an extension language may provide their own debugger interface.

There are several ways to enter the Lisp debugger; functions can be marked so that they cause the debugger to be entered when they are called, breakpoints can be written in functions or it can be called explicitly with a form to step through.

Command: trace symbol

This command marks the symbol symbol so that each time its value is dereferenced the debugger is entered when the next form is evaluated. This can be used to set breakpoints on functions (or variables).

When called interactively symbol is prompted for.

Command: untrace symbol

The opposite of trace—unmarks the symbol.

Function: break

This function causes the debugger to be entered immediately. By putting the form (break) at suitable points in your program simple breakpoints can be created.

Command: step form

This function invokes the debugger to step through the form form.

When called interactively form is prompted for.

Function: backtrace #!optional stream

Prints a description of the current Lisp function call stack to stream (or standard-output if stream is undefined).

(backtrace (current-buffer))
     -| #<subr backtrace> ((current-buffer)) nil
     -| #<closure eval-and-print> ((backtrace (current-buffer))) t
     ⇒ t

Each line represents a stack frame, the first item is the called function, the second is the list of arguments applied to it. The third item is true if the list of arguments as displayed has already been evaluated.

Whenever the Lisp debugger is entered the form waiting to be evaluated is printed, preceded by the current depth of execution in angular brackets. At this point the special debugger commands available are,

step
s

Step into the current form; this means that in a list form the debugger is used to evaluated each argument in turn.

next
n

Continue evaluating forms normally until the next form at the current level is entered, then re-enter the debugger.

continue
c

Continue execution normally. Note that this command is the one to use when an error has been trapped.

return form
r form

Evaluate form then return this value as the result of the current form.

print form
p form

Evaluate form, then print its value.

form
f

Print the form being debugged.

backtrace
b

Print a backtrace of the current Lisp call stack.

Entering a null string repeats the previous ‘next’, ‘step’, or ‘continue’ command.

After the form has been evaluated (i.e. after you’ve typed one of the commands above) the value of the form is printed in the buffer, prefixed by the string ‘=> ’.

Note that it is also possible to make certain types of errors invoke the debugger immediately they are signalled, see Errors. Also note that the debugger is unable to step through compiled Lisp code.


Next: , Previous: , Up: The language   [Contents][Index]