[Openmcl-devel] How do I use the debugger
gb at clozure.com
Sun Feb 1 15:40:18 UTC 2004
On Sun, 1 Feb 2004, Anders Conradi wrote:
> This weekend I have tried to work on a hobby project in lisp. The
> problem is that I can't seem to figure out how to use the debugger.
OpenMCL's debugger is certainly spartan, but it's generally true that
debugging lisp code is different than debugging code compiled in other
> How do I add breakpoints?
The simplest way to do so is to edit your source code and call
BREAK at appropriate times. That sounds primitive (and sometimes
is), but you generally have the entire lisp environment (for better
or worse ...) at your disposal in a break loop.
> How do I get information about which line in the code it was that
> caused an error?
This is a hard problem. In most other programming environments,
the compiler frontend reads and parses the source file(s), annotating
the parsed representation with source file and line number information
as it does so. In lisp, this parsing's done by a separate function
(READ), and the parse tree that the compiler sees is just an
S-expression. (I vaguely remember some attempts by some people
to define a version of READ that annotated its result with source
file information: I think that a CL implementation called WCL used
to try to do this, but don't know how successful these attempts
A compiler -could- do more than OpenMCL's does to associate PC
values in a function with the containing S-expression (in some
sense of the term: the compiler's notion of the containing
S-expression - after macroexpansion and other transformations -
may be pretty far removed from the original S-expression, and
the original expression may or may not be very useful). Alan
Ruttenberg has done some work to annotate disassembled code this
way, and incorporating this information into the backtrace might
make it easier to get oriented more often.
> I would also like to be able to walk up and down the
> stack to see where I came from, i.e. see which line called the
> offending function, and view local variables. How is this done?
Typing :? in a break loop gives a terse summary of available
colon-commands, some of which can take arguments.
:B will display a (very raw) stack backtrace, showing the functions
that're currently waiting to receive values from their callees
(and runtime arcana,) The stack backtrace shows where you're
going, which isn't always the same as where you've come from.
Frames in the stack backtrace are numbered, with 0 being the
frame associated with the most recent function invocation.
(:F n) will display the contents (incoming arguments, local variables,
saved register values, outgoing function arguments, ...) of the
nth frame Sometimes, it's necessary to poke around a bit to
find the value you're interested in: register values may be saved
in younger frame, it's easier to see the value of a special variable
as of the time a binding construct was entered than to see its
current value, etc.
There are usually a few more things available, and there are lots of
other things (return-from-frame, a higher-level presentation of
backtrace information, source expression annotations) that one might
want, and those things can be very useful. It's in practice often
very useful just to insert BREAK and FORMAT calls at strategic points
in your program and/or to TRACE things to see how they're being called
and what they're returning, and a lot of the time these simple approaches
work remarkably well. (Putting a printf() call in a C function would
often work as well, but that's often a more disruptive approach and
the best that printf() can do in many cases is to show you a hex address.)
> Thanks in advance for any help, //Anders
> _______________________________________________ Openmcl-devel
> mailing list Openmcl-devel at clozure.com
More information about the Openmcl-devel