If there is an exception a matching error handler will be selected and called in the context of the error. A default handler could be a debugger, a break loop (which is a Lisp REPL), something which asks the user waht to do or it could be a handler provided by the software, which could do anything, including looking for restarts and using one.
For example the variable a is unbound and we try to add 3.
CL-USER 37 > (+ 3 a)
CL shows an UNBOUND-VARIABLE error and provides Restarts. Restart 3 is a USE-VALUE restart.
Error: The variable A is unbound.
1 (continue) Try evaluating A again.
2 Return the value of :A instead.
3 Specify a value to use this time instead of evaluating A.
4 Specify a value to set A to.
5 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
We are now in a break loop, a REPL one level deeper, in the context of the error. Let's see what the condition (-> exception) is:
CL-USER 38 : 1 > :cc
#<UNBOUND-VARIABLE 8010002EC3>
we call one restart (listed above, number 3) interactively, it uses the new value and continues to compute the expression. It asks for a value. I enter 5 -> 5 + 3 = 8
CL-USER 39 : 1 > :c 3
Enter a form to be evaluated: 5
8
We can do it also programmatically. HANDLER-BIND establishes a handler for UNBOUND-VARIABLE. It invokes the restart USE-VALUE with 4 -> 3 + 4 = 7
CL-USER 40 > (handler-bind ((unbound-variable #'(lambda (c)
(invoke-restart 'use-value 4))))
(+ 3 a))
7
All this is the default behavior. There is no special "debug mode", attaching a debugger or "instrumentation of code" needed.