在Emacs的 Perl调试器中,如何更方便地查看调用栈回溯中提到的代码?

编程语言 2026-07-10

在Perl调试器中使用 T 命令会产生一个类似于以下的栈跟踪:

$ = main::infested called from file 'Ambulation.pm' line 10
@ = Ambulation::legs(1, 2, 3, 4) called from file 'camel_flea' line 7
$ = main::pests('bactrian', 4) called from file 'camel_flea' line 4

(示例取自https://perldoc.perl.org/perldebug)。当通过Emacs运行Perl调试器(通过 M-x perldb)时,这样的栈跟踪会以普通文本的形式出现在调试缓冲区中,无法通过任何“神奇的跳转”快速定位到提到的文件中的相应行以查看上下文。我得手动打开相关文件,然后导航至提到的那一行。这能否变得更方便?

解决方案

在GNU Emacs 30.2上,到目前为止我所找到的最佳方法是修改栈跟踪格式,使其与 compilation-mode 兼容,然后使用该模式的导航功能来实现跳转。有没有更好的办法?

要修改栈跟踪格式,请将以下内容添加到perl调试器初始化文件中的 sub afterinit(Windows上为 perldb.ini,其他操作系统为 .perldb,参见 perldb):

  my $old_print_trace = \&DB::print_trace;
  *{DB::print_trace} = sub {
    my $trace = '';
    open my $fh, '>', \$trace;
    $old_print_trace->($fh, 1); # write old trace to $trace
    close $fh;
    # transform trace to compilation-mode format
    my @lines = split /\n/, $trace;
    # this override introduces one extra stack frame; omit it from the
    # trace
    shift @lines;
    my $ix = 0;
    foreach (@lines) {
      ++$ix;
      s/^(.*?) called from file '(.*?)' line (\d+)/$2:$3:[$ix]$1/;
    }
    print $DB::OUT join("\n", @lines), "\n";
  }

这段代码会覆盖 DB::print_trace(由调试器的 T 命令调用)以在输出前重新格式化追踪信息。修改完成后,别忘了再次将perldb文件设为只读,否则Perl将不接受它。

然后启动调试器,最终执行 T 命令时,会产生如下所示的栈跟踪:

Ambulation.pm:10:[1]$ = main::infested
camel_flea:7:[2]@ = Ambulation::legs(1, 2, 3, 4)
camel_flea:4[3]$ = main::pests('bactrian', 4) called from file 'camel_flea' line 4

紧跟在文件名和行号之后的方括号数字(如 [1])表示该栈帧的编号,供调试器的 y 命令使用。在我的系统上,执行两次 M-x compilation-minor-mode(可以缩写为 M-x co-mi),然后 C-x ` to select the current stack trace and open the corresponding file/line in a separate buffer just like when navigating the errors of a compilation. Further C-x ` 依次选择更旧的栈帧。

第一步 M-x co-mi 会把回溯行变成可点击的链接,但会禁用进入更多调试命令。第二步 M-x co-mi 会重新启用输入调试命令,但会再次移除可见的链接。随后执行的 C-x ` 会再次把回溯行变成可点击的链接,同时仍然可以输入更多调试命令。

在我的系统上,执行 C-x ` without having earlier done M-x co-mi 两次似乎不起作用。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章