进入调试器最重要的时机是在 Lisp 错误发生时。 这让你可以调查错误的直接原因。
但是,进入调试器并不是错误的常规处理方式。
很多命令在被不当调用时会触发 Lisp 错误,
在普通编辑中,每次都进入调试器会非常不便。
因此,如果你希望错误触发调试器,请将变量 debug-on-error
设为非nil。
(命令 toggle-debug-on-error 提供了简便的切换方式。)
注意,由于技术原因,本节定义的功能无法用于调试 重绘代码所调用的 Lisp 中的错误。 相关帮助请见 See 调试重绘错误。
该变量决定在错误被触发且未被处理时是否调用调试器。
如果 debug-on-error 为 t,
除了 debug-ignored-errors(见下文)中列出的错误外,
所有类型的错误都会调用调试器。
如果为 nil,则所有错误都不会进入调试器。
该值也可以是一个错误条件列表(see 如何发出错误信号)。
此时只有列表中的错误条件才会调用调试器
(同样排除 debug-ignored-errors 中的错误)。
例如,将 debug-on-error 设置为列表 (void-variable),
则调试器只会在变量无值的错误时被调用。
注意,在某些情况下 eval-expression-debug-on-error
会覆盖本变量;见下文。
当该变量为非nil 时,Emacs 不会在进程过滤函数和哨兵函数
外围创建错误处理器。因此这些函数中的错误也会触发调试器。See Processes。
该变量指定无论 debug-on-error 取何值
都**不**进入调试器的错误。
其值为错误条件符号和/或正则表达式的列表。
如果错误具有其中任一条件符号,或错误信息匹配任一正则表达式,
则该错误不会进入调试器。
该变量的默认值包含 user-error,
以及一些编辑中经常出现但很少由 Lisp 程序漏洞导致的错误。
但“很少”不等于“从不”;
如果你的程序触发了匹配此列表的错误,
你可以尝试修改此列表来调试该错误。
最简单的方法通常是将 debug-ignored-errors 设为 nil。
如果该变量为非nil(默认值),
运行命令 eval-expression 时会临时将 debug-on-error 绑定为 t。
See Evaluating Emacs Lisp Expressions in The GNU Emacs Manual。
如果 eval-expression-debug-on-error 为 nil,
则在 eval-expression 执行期间不会改变 debug-on-error 的值。
通常情况下,被 condition-case 捕获的错误永远不会触发调试器。
condition-case 会在调试器之前获得处理错误的机会。
如果你将 debug-on-signal 设为非nil,
则无论是否存在 condition-case,
调试器都会优先获得所有错误的处理机会。
(要触发调试器,错误仍需满足 debug-on-error
和 debug-ignored-errors 指定的条件。)
例如,设置该变量有助于从 emacsclient 的 --eval 选项
所执行的代码中获取调用栈。
如果该变量为非nil,emacsclient 执行的 Lisp 代码触发错误时,
调用栈会在运行中的 Emacs 中弹出。
警告: 将该变量设为非nil 可能产生烦人的效果。
Emacs 的很多部分在正常运行时会捕获错误,
你甚至可能意识不到那里发生了错误。
如果你需要调试被 condition-case 包裹的代码,
可以考虑使用 condition-case-unless-debug(see 编写处理错误的代码)。
如果你将 debug-on-event 设置为某个特殊事件(see Special Events),
Emacs 会在收到该事件时立即尝试进入调试器,
绕过 special-event-map。
目前仅支持对应信号 SIGUSR1 和 SIGUSR2 的值(这是默认值)。
当 inhibit-quit 被设置且 Emacs 无其他响应时,该功能很有用。
如果你将 debug-on-message 设置为正则表达式,
当 Emacs 在回显区显示匹配该表达式的消息时,会进入调试器。
例如,在查找某条消息的产生原因时很有用。
你可以在 ‘*Backtrace*’ 缓冲区中使用 e 命令
对当前栈帧中的表达式求值,在使用 Edebug 时
也可以用 e 和 C-x C-e 做类似操作。
默认情况下,这些命令会抑制调试器(因为此时重新进入调试器
通常会让你脱离当前调试上下文)。
将 debug-allow-recursive-debug 设为非nil
可以允许这些命令递归进入调试器。
要调试启动文件加载过程中发生的错误,
请使用选项 ‘--debug-init’。
它会在加载启动文件期间将 debug-on-error 绑定为 t,
并绕过通常会捕获启动文件错误的 condition-case。