Skip to main content

invoke-debugger

invoke-debugger Function

Syntax:

invoke-debugger condition →

Arguments and Values:

condition—a condition object.

Description:

invoke-debugger attempts to enter the debugger with condition.

If *debugger-hook* is not nil, it should be a function (or the name of a function) to be called prior to entry to the standard debugger. The function is called with *debugger-hook* bound to nil, and the function must accept two arguments: the condition and the value of *debugger-hook* prior to binding it to nil. If the function returns normally, the standard debugger is entered.

The standard debugger never directly returns. Return can occur only by a non-local transfer of control, such as the use of a restart function.

Examples:

(ignore-errors ;Normally, this would suppress debugger entry 
(handler-bind ((error #’invoke-debugger)) ;But this forces debugger entry
(error "Foo.")))
Debug: Foo.
To continue, type :CONTINUE followed by an option number:
1: Return to Lisp Toplevel.
Debug>

Side Effects:

*debugger-hook* is bound to nil, program execution is discontinued, and the debugger is entered.

Affected By:

*debug-io* and *debugger-hook*.

See Also:

error, break

break

Expanded Reference: invoke-debugger

Purpose of invoke-debugger

invoke-debugger enters the debugger with a given condition. Unlike error, it does not signal the condition through the handler chain first. It goes directly to the debugger (or to the *debugger-hook* function).

Using invoke-debugger to Force Debugger Entry

Even when handlers would normally intercept a condition, invoke-debugger bypasses them.

;; Normally ignore-errors would prevent debugger entry, but
;; invoke-debugger overrides that:
;;
;; (ignore-errors
;; (handler-bind ((error #'invoke-debugger))
;; (error "Foo.")))
=> enters the debugger despite ignore-errors

The debugger-hook Protocol

Before entering the standard debugger, invoke-debugger checks *debugger-hook*. If non-nil, the hook function is called with the condition and the previous value of *debugger-hook* (which is bound to nil during the call to prevent recursion).

(let ((*debugger-hook*
(lambda (condition hook)
(declare (ignore hook))
(format t "Custom debugger: ~A~%" condition)
(abort))))
(handler-case
(invoke-debugger (make-condition 'simple-error
:format-control "test error"))
(control-error () :aborted)))
Custom debugger: test error

invoke-debugger Never Returns Normally

invoke-debugger does not return. The only way to leave it is through a non-local transfer of control, such as invoking a restart.

;; (invoke-debugger (make-condition 'simple-condition
;; :format-control "Debug me"))
=> enters debugger; does not return unless a restart transfers control