[slime-devel] Simplifying backtraces in the debugger

Steven E. Harris seh at panix.com
Sun Oct 26 23:37:59 UTC 2008


I'm not sure if this grievance falls to CLISP or to SLIME. When I land
in the debugger, there are way too many frames present. Most of them are
just noise, and I usually can't find the interesting frames -- such as
those corresponding to named functions that I wrote -- with lexical
bindings to inspect.

Playing around with CLISP outside of SLIME, I see that one can set the
mode used by the ":bt" command in the debugger. This can help to
simplify the output, though I haven't yet figured out which of the five
modes corresponds to what I'd /like/ to see.

Consider this contrived example:

,----
| CL-USER> (defun foo (n)
|            (/ 3 n))
| FOO
| CL-USER> (foo 0)
`----

Evaluating that second form provokes this view in the debugger:
(Take a deep breath.)

,----
| /: division by zero
|    [Condition of type SYSTEM::SIMPLE-DIVISION-BY-ZERO]
| 
| Restarts:
|  0: [RETRY] Retry SLIME REPL evaluation request.
|  1: [ABORT] Return to SLIME's top level.
|  2: [CLOSE-CONNECTION] Close SLIME connection
|  3: [ABORT] Abort main loop
| 
| Backtrace:
|   0: [366] frame binding variables (~ = dynamically):
|        | ~ SWANK::*SLDB-STEPPING-P* <--> NIL
|   1: [363] frame binding variables (~ = dynamically):
|        | ~ SWANK::*SLDB-LEVEL* <--> 0
|   2: [360] frame binding variables (~ = dynamically):
|        | ~ *PACKAGE* <--> #<PACKAGE COMMON-LISP-USER>
|   3: <1/354> #<COMPILED-FUNCTION SWANK::DEBUG-IN-EMACS>
|      [353] frame binding variables (~ = dynamically):
|        | ~ SWANK::*SLIME-INTERRUPTS-ENABLED* <--> T
|   4: <1/347> #<COMPILED-FUNCTION SWANK:INVOKE-SLIME-DEBUGGER>
|      - #<COMPILED-FUNCTION SWANK::SWANK-DEBUGGER-HOOK-1>
|   5: <1/345> #<COMPILED-FUNCTION SWANK::SWANK-DEBUGGER-HOOK-1>
|      - #<COMPILED-FUNCTION SWANK::SWANK-DEBUGGER-HOOK-1>
|   6: [344] frame binding variables (~ = dynamically):
|        | ~ *DEBUGGER-HOOK* <--> NIL
|   7: <1/340> #<COMPILED-FUNCTION #:|624 629 (DEFINTERFACE CALL-WITH-DEBUGGER-HOOK (HOOK FUN) ...)-61-3-1|>
|      - #<COMPILED-FUNCTION #:|624 629 (DEFINTERFACE CALL-WITH-DEBUGGER-HOOK (HOOK FUN) ...)-61-3-1|>
|   8: <1/335> #<COMPILED-FUNCTION SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK>
|      - #(NIL #<SYSTEM::SIMPLE-DIVISION-BY-ZERO #x10140B4D>)
|   9: <1/331> #<COMPILED-FUNCTION SWANK:SWANK-DEBUGGER-HOOK>
|      [329] frame binding variables (~ = dynamically):
|        | ~ *DEBUGGER-HOOK* <--> #<COMPILED-FUNCTION SWANK:SWANK-DEBUGGER-HOOK>
|  10: <1/326> #<SYSTEM-FUNCTION INVOKE-DEBUGGER> 1
|      [325] frame binding variables (~ = dynamically):
|        | ~ SYSTEM::*PRIN-STREAM* <--> #<UNBOUND>
|  11: [322] frame binding variables (~ = dynamically):
|        | ~ *PRINT-READABLY* <--> NIL
|  12: [319] frame binding variables (~ = dynamically):
|        | ~ *PRINT-ESCAPE* <--> T
|  13: <1/315> #<SYSTEM-FUNCTION /> 2
|      - 3
|  14: [313] EVAL frame for form (/ 3 N)
|       Locals:
|         N = 0
|  15: [309] frame binding environments
|        VAR_ENV <--> NIL
|        FUN_ENV <--> NIL
|        BLOCK_ENV <--> NIL
|        GO_ENV <--> NIL
|        DECL_ENV <--> ((DECLARATION OPTIMIZE DECLARATION))
|  16: [303] frame binding variables #<ADDRESS #x7FF404FC> binds (~ = dynamically):
|        |  N <--> 0
|        Next environment: NIL
|  17: [297] APPLY frame for call (FOO '0)
|  18: <1/293> #<FUNCTION FOO (N) (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (/ 3 N))> 1
|      - #<FUNCTION FOO (N) (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (/ 3 N))>
|  19: [292] EVAL frame for form (FOO 0)
|  20: [289] frame binding environments
|        VAR_ENV <--> NIL
|        FUN_ENV <--> NIL
|        BLOCK_ENV <--> NIL
|        GO_ENV <--> NIL
|        DECL_ENV <--> ((DECLARATION OPTIMIZE DECLARATION))
|  21: <1/284> #<SYSTEM-FUNCTION EVAL>
|      - (FOO 0)
`----

If I ran across this output in a large program, I'd probably be most
interested in frame 14, where the division operator is being
evaluated. Expanding it shows that "N" was bound to 3.

Is there some way to configure SLIME to sift through these frames and
reduce them to something more "interesting"? For instance, by my
criteria, everything in frames 1 through 12 above is irrelevant to the
debugging intent, unless I was trying to debug the debugger.

As an aside, I'd appreciate any comparison in the output to other
implementations besides CLISP. Are they less chatty?

-- 
Steven E. Harris





More information about the slime-devel mailing list