【问题标题】:Perl Devel::StackTrace reverse order of framesPerl Devel::StackTrace 反转帧顺序
【发布时间】:2014-09-25 04:33:23
【问题描述】:

我正在尝试使用 Perl 模块 Devel::StackTrace 显示堆栈跟踪错误,帧显示在错误源的底部到顶部,有没有办法颠倒这个顺序以显示错误源帧顶部,因为这是您需要知道的第一件事,然后根据需要跟踪到底部。

下面是重现问题的测试代码。

#!/usr/bin/perl
#!C:\perl\bin\perl.exe

BEGIN {
    $|=1;
    use CGI::Carp qw(fatalsToBrowser set_message);
    use Devel::StackTrace;
    use Devel::StackTrace::AsHTML;
    use PadWalker;
    use Devel::StackTrace::WithLexicals;
    sub handle_errors {
        my $msg = shift;
        #my $trace = Devel::StackTrace->new(indent => 1, message => $msg);
        my $trace = Devel::StackTrace::WithLexicals->new(indent => 1, message => $msg);
        #print $trace->as_html;
        print $trace->as_string;
    }
    set_message(\&handle_errors);
}

show_error();

exit;

以下是文本格式错误提示:

Undefined subroutine &main::show_error called at C:/apache/htdocs/tests/test.cgi line 24.
     at C:\apache\htdocs\tests\test.cgi line 17
        main::handle_errors('Undefined subroutine &main::show_error called at C:/apache/htdocs/tests/test.cgi line 24.^J') called at C:\perl\site\lib\CGI\Carp.pm line 525
        eval {...} at C:\perl\site\lib\CGI\Carp.pm line 524
        CGI::Carp::fatalsToBrowser('Undefined subroutine &main::show_error called at C:/apache/htdocs/tests/test.cgi line 24.^J') called at C:\perl\site\lib\CGI\Carp.pm line 444
        CGI::Carp::die('Undefined subroutine &main::show_error called at C:/apache/htdocs/tests/test.cgi line 24.^J') called at C:\apache\htdocs\tests\test.cgi line 24

【问题讨论】:

  • 已经从上到下显示堆栈帧(最近的帧位于堆栈顶部)。来自docs: "$trace->as_string(\%p) 在每一帧上从上到下调用​​$frame->as_string()..."
  • 那我想要的反正是相反的。
  • 反转堆栈跟踪如何帮助您进行调试?如果函数foo 发生错误,则应该查看该错误,而不是堆栈底部的某个函数。
  • 如果你看到痕迹,最后一个called at C:\apache\htdocs\tests\test.cgi line 24是问题的根源,这应该在痕迹的顶部。
  • 所以你希望最后一件事在顶部执行?这就是你所拥有的。如果对show_error(); 的调用深度为十级,那么这十级将出现在调用show_error() 的行下方

标签: perl


【解决方案1】:

查看模块Devel::StackTrace源代码后,我能够回答我的问题。 该模块具有方法frames,它返回或设置帧。所以我在调用as_stringas_html 方法之前通过这一行简单地颠倒了顺序:

$trace->frames(reverse $trace->frames);

这里是修改后的代码和解决方案:

#!/usr/bin/perl
#!C:\perl\bin\perl.exe

BEGIN {
    $|=1;
    use CGI::Carp qw(fatalsToBrowser set_message);
    use Devel::StackTrace;
    use Devel::StackTrace::AsHTML;
    use PadWalker;
    use Devel::StackTrace::WithLexicals;
    sub handle_errors {
        my $msg = shift;
        my $trace = Devel::StackTrace->new(indent => 1, message => "$msg\n");
        #my $trace = Devel::StackTrace::WithLexicals->new(indent => 1, message => $msg);
        $trace->frames(reverse $trace->frames);
        #print $trace->as_html;
        print $trace->as_string;
    }
    set_message(\&handle_errors);
}

show_error();

exit;

这正是我想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2015-03-05
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2010-12-13
    相关资源
    最近更新 更多