2

我知道我可以使用命令添加变量和表达式的w监视,是否可以告诉它简单地解析每个命令并在该命令中包含特定文本时停止?

类似于w m/bad command/where$_的字符串包含正在执行的下一个命令。

我现在正在 Windows 上使用 Komodo 进行远程 CGI 调试,但我也可以perl -d在 linux shell 上使用。


更新

我会尽力使这一点更清楚。有一个文件,其中包含磁盘上的数据被删除,我不知道在哪里。我正在调试的程序由许多相互需要的 .pl 文件组成,完整的代码库甚至更大。我当然可以通过 grep 来获取数据文件名称的一部分(我知道扩展名),或者unlink. 但是由于我不知道我的程序正在使用哪些代码文件,所以这并没有让我走得太远。

让我们考虑这段代码,它将被调试:

if ($foo == 1) {
  unlink 'filename.example';
}

现在,当我调试它时,如果将要执行的下一个 perl 命令(来自脚本)包含/example/. 我想要一种在执行下一个命令之前运行的钩子。

这样,我不需要知道我想中断的东西在哪里(比如在哪一行或文件中),也不需要变量名(因为没有变量名)。

我知道这很难解释,但我认为这可能是一个常见问题。也许还有另一种方法?

4

5 回答 5

5

观察点使用 'w' 命令设置:

 BD<1>  w  $cannonballs

每次 $cannonballs 更改时都会中断程序。

 BD<1> w $i == 19

当 $i 的值设置为 19 时将中断。例如

 $ cat  foo.pl 

 foreach $i ( 0..100 ) {
    print "$i\n";
 }

 $ perl -d foo.pl

 Loading DB routines from perl5db.pl version 1.28 Editor support available.

 Enter h or `h h' for help, or `man perldebug' for more help.

 main::(foo.pl:2):       foreach $i ( 0..100 ) {   
   DB<1> w $i == 3   
   DB<2> c 
 0 
 1 
 2 
 Watchpoint 0:   $i == 3 changed:
     old value:  ''
     new value:  '1' 
 main::(foo.pl:3):          print "$i\n";   
   DB<2> p $i 
 3   
   DB<3> q 
 Watchpoint 0:   $i == 3 changed:
     old value:  '1'
     new value:  '' 
   DB<3> q
 $

您可能希望使用变量的完整命名空间,否则任何同名的变量进入或超出范围时都会中断。

于 2012-11-02T14:29:12.867 回答
4

我不知道有一个模块可以完全满足您的要求,但Devel::Trace是一个非常小的模块(20 行代码),它会在执行之前打印每一行。

您可以创建它的子类,并修改 DB::DB 子例程以设置 $DB::single = 1 如果代码匹配您想要的字符串。

请参阅brian d foy关于 Devel::Trace 的帖子以获取更全面的描述,并附有示例。

于 2012-11-02T21:19:17.287 回答
0

调试器已经可以做到这一点(嗯,几乎)。它不称为监视表达式,但称为断点

您可以为行和条件设置断点:

b 33 /pattern/i

但是,您必须指定行号。请参阅Perl 调试

于 2012-11-02T13:47:46.443 回答
0

您可以使用在代码中设置断点

$DB::single = 1;

要在监视配置中使用断点,请将断点括在与您要监视的内容相匹配的条件中。

在你的情况下:

if ( $command =~ /example/ ) {
    $DB::single = 1;
}

应该服务。

于 2015-04-30T15:41:39.550 回答
-1

查看Tie::Trace,它可以提醒您变量值已更改的位置。我想您甚至可以使用$DB::single=1表达式破解它,以便在每次变量值更改时在调试器中中断。

于 2012-11-02T14:17:32.183 回答