Clasp provides two ways of debugging code. In interactive sessions Clasp invokes a built in Common Lisp debugger when errors or other exceptional situations arise. The Clasp compiler also generates DWARF debugging information that can be used by the GDB debugger (and hopefully soon the LLDB debugger) to display Clasp Common Lisp source information interleaved with C++ source information.
To see this start up clasp and type what follows the > prompt:
Top level. > (defun c () (break "In c")) C > (defun b () (c)) B > (defun a () (b)) A > (a) Condition of type: SIMPLE-CONDITION In c Available restarts: (use :r1 to invoke restart 1) 1. (CONTINUE) Return from BREAK. 2. (RESTART-TOPLEVEL) Go back to Top-Level REPL. Broken at frame[14] CORE::REP. File: #<CORE:SOURCE-FILE-INFO #P"/Users/meister/Development/clasp/src/lisp/kernel/lsp/top.lsp"> (Position #573) >>
The double prompt >> indicates that we are now in the Clasp Common Lisp debugger. This debugger is inherited from ECL (because Clasp uses the excellent Common Lisp source code from ECL). To get a list of commands that are available in the debugger type:
>> :h Top level commands: :cf Compile file. :exit or ^D Exit Lisp. :ld Load file. :step Single step form. :tr(ace) Trace function. :untr(ace) Untrace function. :pwd Print the current value of *default-pathname-defaults*. :cd Change the current value of *default-pathname-defaults*. Help commands: :apropos Apropos. :doc(ument) Document. :h(elp) or ? Help. Type ":help help" for more information. Break commands: :q(uit) Return to some previous break level. :pop Pop to previous break level. :c(ontinue) Continue execution. :b(acktrace) Print backtrace. :f(unction) Show current function. :p(revious) Go to previous function. :d(own) Alias to :previous. :n(ext) Go to next function. :u(p) Alias to :next. :g(o) Go to next function. :fs Search forward for function. :bs Search backward for function. :disassemble Disassemble current function. :l(ambda-)e(expression) Show lisp code for current function. :v(ariables) Show local variables, functions, blocks, and tags. :hide Hide function. :unhide Unhide function. :hp Hide package. :unhp Unhide package. :unhide-all Unhide all variables and packages. :bds Show binding stack. :frs Show frame stack. :m(essage) Show error message. :hs Help stack. :i(nspect) Inspect value of local variable. Restart commands: :r1 Return from BREAK. (CONTINUE). :r2 Go back to Top-Level REPL. (RESTART-TOPLEVEL). >>
Clasp/ECL use Common Lisp keywords to activate debugger functionality.
To generate a backtrace type:
>> :b --------STACK TRACE-------- frame# 0toplevel epilogueForm 0/0 REPL frame# 1/c top.lsp 419/2 CORE::TOP-LEVEL frame# 2/c top.lsp 615/21 CORE::TPL frame# 3/c top.lsp 605/32 CORE::REP frame# 4/b evaluator.cc 2353/0 CORE:TOP-LEVEL-EVAL-WITH-ENV frame# 5/b evaluator.cc 2351/0 CORE:COMPILE-FORM-AND-EVAL-WITH-ENV frame# 6/c -no-file- 1/0 nil frame# 7/c -no-file- 1/0 A frame# 8/c -no-file- 1/0 B frame# 9/c -no-file- 1/0 C frame# 10/c conditions.lsp 457/8 COMMON-LISP:BREAK frame# 11/c top.lsp 1507/9 COMMON-LISP:INVOKE-DEBUGGER frame# 12/c top.lsp 1489/5 CORE::DEFAULT-DEBUGGER frame# 13/c top.lsp 618/7 CORE::TPL -->frame# 14/c top.lsp 605/32 CORE::REP frame# 15/b evaluator.cc 2353/0 CORE:TOP-LEVEL-EVAL-WITH-ENV frame# 16/b evaluator.cc 2351/0 CORE:COMPILE-FORM-AND-EVAL-WITH-ENV frame# 17/c -no-file- 0/0 nil frame# 18/c top.lsp 1088/3 CORE::TPL-BACKTRACE frame# 19/b stacks.cc 712/0 CORE:IHS-BACKTRACE NIL >>
The —-> indicates the current frame that the debugger has stopped on. Since the error handling code and the debugger functions are all written in Common Lisp, those functions also appear on the backtrace. The functions we entered are in frames 7, 8, and 9.
At this point we could go to a specific frame using :g
and view the environment of that frame using :v
or we can print variables by just typing their names.
For now we will just leave the debugger and return to the top level REPL by invoking a restart.
>> :r2 >
Now we are back in the top level REPL and can continue working.
Next I’ll show you how to use the DWARF generated debugging information embedded in compiled Common Lisp code to debug Clasp using GDB or LLDB.