如何在 Emacs 的 Perl debugger 中快速跳转到堆栈回溯对应的源码?
可以。在 perldb 缓冲区中启用 compilation-shell-minor-mode,再为 called from file '…' line … 添加解析规则,就可以用 Emacs 的位置跳转命令查看对应源码。
为什么需要添加解析规则?
回溯文本中已有文件名和行号,Emacs 还需要解析规则才能提取它们。compilation-error-regexp-alist 用于定义这类位置格式,通过 minor mode,也可以在其他缓冲区使用解析功能。参见 Compilation Mode 手册。
配置 perldb 缓冲区
将下面的代码加入 Emacs 初始化文件并求值:
(require 'compile)
(defun my-perldb-backtrace-setup ()
"Enable source navigation for Perl debugger backtraces."
(interactive)
(setq-local compilation-error-regexp-alist
(copy-sequence compilation-error-regexp-alist))
(add-to-list
'compilation-error-regexp-alist
'("called from file '\\([^'\n]+\\)' line \\([0-9]+\\)"
1 2))
(compilation-shell-minor-mode 1))
(add-hook 'perldb-mode-hook #'my-perldb-backtrace-setup)
正则表达式的第一个捕获组提取文件名,第二个提取行号;规则末尾的 1 2 指定这两个组的用途。代码使用缓冲区局部变量,同时保留已有解析规则。规则格式和 compilation-shell-minor-mode 的行为可查阅 Emacs 的 compile.el 源码。
这项配置放在 perldb-mode-hook 中,会在 Perl 调试器启动时执行。参见 GUD Customization 手册。如果调试会话已经打开,可以切换到调试器缓冲区,执行 M-x my-perldb-backtrace-setup。
如何跳转到源码?
在 Perl debugger 中再次执行 T,然后:
- 将光标移到某条回溯的
called from file … line …部分,按M-RET或执行M-x compile-goto-error。 - 使用
M-g M-n(next-error)和M-g M-p(previous-error),依次查看解析到的位置。
按给出的示例,第一条回溯对应 Ambulation.pm 的第 10 行。这里使用的是 Emacs 的位置导航功能,命令名称中的 error 不表示该回溯条目本身是错误。
文件找不到时检查什么?
对于回溯中的相对文件名,Emacs 需要能从调试器缓冲区的 default-directory 或配置的源码搜索路径中找到对应文件。如果模块位于其他目录,可以为该缓冲区设置 compilation-search-path,加入实际源码目录;不要假定它会自动沿用 Perl 的 @INC。
这条正则针对题目展示的单引号文件名格式。如果实际输出格式不同,或文件名中含有单引号,需要相应调整。跳转只用于查看源码位置,不会改变 Perl debugger 的执行位置或变量上下文。
备注:内容仅供参考。
