Skip to content

Commit e8f5a1a

Browse files
committed
debugging: *break-on-signals*
1 parent 3a7278d commit e8f5a1a

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

debugging.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,66 @@ or using `r` ("restart frame") on a given stackframe).
607607

608608
See also the [Slime-star](https://github.com/mmontone/slime-star) Emacs extension mentioned above to set breakpoints without code annotations.
609609

610+
## Break when a condition occurs: `*break-on-signals*`
611+
612+
[*break-on-signals*](https://cl-community-spec.github.io/pages/002abreak_002don_002dsignals_002a.html)
613+
can be specially helpful when you see that an error (or any condition)
614+
occured, but you didn't get the debugger, and you want to force the
615+
debugger to open *just before* the error (or any condition) is
616+
signaled.
617+
618+
For example, you witness that a `print-object` method of a database
619+
record from a third-party library tells you something wrong happened:
620+
621+
#<DB record: <<ERROR while printing the DB object>> >
622+
623+
However, the library handled the error and you didn't get the interactive debugger.
624+
625+
To debug this, you can set `*break-on-signals` to `'error` (or any symbol referring to an existing condition type).
626+
627+
This is the usual case: `*break-on-signals*` is NIL.
628+
629+
~~~lisp
630+
(ignore-errors
631+
(format t "*break-on-signals* value is: ~a~&" *break-on-signals*)
632+
(error 'simple-error :format-control "Oh no!"))
633+
;; *break-on-signals* value is: NIL <--- stdout
634+
;; NIL <--- first returned value
635+
;; #<SIMPLE-ERROR "Oh no!" {1205C6BC03}> <-- second returned value, the condition object.
636+
~~~
637+
638+
Let's set `*break-on-signals*` to `'error`:
639+
640+
~~~lisp
641+
(let ((*break-on-signals* 'error))
642+
(format t "*break-on-signals* value is: ~a~&" *break-on-signals*)
643+
(ignore-errors
644+
(error 'simple-error :format-control "Oh no!")))
645+
~~~
646+
647+
Even though our `error` is surrounded by `ignore-errors`, we get the interactive debugger:
648+
649+
```
650+
Oh no!
651+
BREAK was entered because of *BREAK-ON-SIGNALS* (now rebound to NIL).
652+
[Condition of type SIMPLE-CONDITION]
653+
654+
Restarts:
655+
0: [CONTINUE] Return from BREAK.
656+
1: [RESET] Set *BREAK-ON-SIGNALS* to NIL and continue.
657+
2: [REASSIGN] Return from BREAK and assign a new value to *BREAK-ON-SIGNALS*.
658+
659+
660+
Backtrace:
661+
662+
```
663+
664+
from the debugger, we can inspect the stack trace, go to the line
665+
signaling the condition, fix it and resume execution.
666+
667+
When the condition signaled is an error, we don't enter the debugger a
668+
second time after we handled the break.
669+
610670

611671
## Advise and watch
612672

0 commit comments

Comments
 (0)