【问题标题】:Perl debugger: Trace variable in stacktracePerl 调试器:堆栈跟踪中的跟踪变量
【发布时间】:2016-02-19 09:22:01
【问题描述】:

使用内置的 Perl 调试器,我可以打印堆栈跟踪。但是,我只对某个变量感兴趣,而不是 30k+ 行的完整堆栈跟踪。 是否可以只显示包含指定变量的执行行?

示例

假设我想跟踪变量 $data。然后我只想看到第 4,7,8,10 行而不是其他行。

use strict;
use warnings;

my $data = 1;
my $otherdata = "Diamond";

$data += 1;
my $rename = $data;

if($rename =~ /2/){

    print "hello world";

}

堆栈跟踪

perl -d:Trace script.pl

script.pl:4: my $data = 1;
script.pl:5: my $otherdata = "Diamond";
script.pl:7: $data += 1;
script.pl:8: my $rename = $data;
script.pl:10: if($rename =~ /2/){
script.pl:12:        print "hello world";

【问题讨论】:

  • 我认为您的意思只是“跟踪”而不是“堆栈跟踪”。
  • 我不知道有一种内置方法可以执行您所要求的操作,但是您可以使用监视表达式在变量值更改时暂停调试器。我认为这比查看引用变量的每一行更有用,无论值是否更改。

标签: perl debugging printstacktrace


【解决方案1】:

我通过使用Variable::Magic 找到了一个部分可行的解决方案。变量跟踪器(参见下面的代码)$wiz 附加到变量 $data。每当访问 $data 时,它都会调用 "get" 方法并执行 sub {print "875ABC8768"}。

use strict;
use warnings;
use Variable::Magic qw<wizard cast VMG_OP_INFO_NAME>;

my $data = 1;

{ # A variable tracer
my $wiz = wizard(
get  => sub { print "875ABC8768"},
 );

 cast $data, $wiz;
}

my $otherdata = "Diamond";

$data += 1;
my $rename = $data;

if($rename =~ /2/){

   print "hello world";

}

通过使用以下步骤,我能够提取包含变量 $data 的执行行:

1) 将堆栈跟踪写入文件:

perl -d:Trace script.pl 2> stacktrace.txt

2) 提取带有变量 $data 的行:

use strict;
use warnings;

open(FILE,"<","stacktrace.txt");
my $previous = <FILE>;

     while (my $current = <FILE>) {

        if($current =~ /875ABC8768/){
            print $previous;
        }

        $previous = $current;
     }

close(FILE);

执行脚本:

perl extractor.pl

>> magic.pl:17: $data += 1;
>> magic.pl:18: my $rename = $data;

【讨论】:

    【解决方案2】:

    您可以仅在包含变量的行号上附加(到跟踪命令)这种半自动过滤方式:

    |egrep ":($(echo $(grep -n '$data\b' script.pl|cut -d: -f1)|tr ' ' '|')):"
    

    【讨论】:

    • 这种方法不会遵循参考。假设$foo 是对$bar 的引用:$foo = \$bar;。如果您只对$bar 进行grep,则$$foo = "foo"; 行将被过滤掉,即使它更改了$bar 的值。
    • 我同意 ThisSuitIsBlackNot,因为不会捕获对变量的引用。
    • 看看 Variable::Magic search.cpan.org/~vpit/Variable-Magic-0.59/lib/Variable/Magic.pm 你可以添加一个钩子,在访问变量时打印出变量的值。
    • 谢谢 xxfelixxx,通过使用 Variable::Magic,我可以添加一个变量跟踪器,每次访问变量时都会调用它。
    • @user2134762 您能否将其添加为答案并展示您的实现?这可能对未来有相同问题的访问者有所帮助。
    猜你喜欢
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 2011-05-25
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多