你如何打破Perl调试器中require'd文件的特定行?

时间:2010-06-11 21:16:21

标签: perl debugging

我有一个Perl脚本,我们称之为A.pl,前两行看起来像这样:

 require 'B.pl';
 require 'C.pl';

B.plC.pl都有自己的需要行列。我需要在C.pl的特定行上设置断点。在GDB中,我会做类似的事情:

b C.pl:830

然而,这似乎根本不起作用。可能吗?我接近了吗?

4 个答案:

答案 0 :(得分:2)

你也可以编辑C.pl添加这个:

$DB:single = 1;

并且调试器将在执行该行之后立即停止,并在执行下一行之前停止。这类似于Ruby的“调试器”声明。

另请参阅:perldoc DB

答案 1 :(得分:1)

您无法一步完成,但您可以更改为所需的文件,然后在特定行上设置断点:

DB<1> f C.pl
1    #!perl -w
2    # This is C.pl
3    # ...

DB<2> b 830

DB<3> c

答案 2 :(得分:1)

我更喜欢调试器'R'(重启)命令的廉价技巧。这是一个示例程序:

#/usr/bin/perl -d
use strict;
use warnings;
use WWW::Mechanize;

my $agent = WWW::Mechanize->new();

让我们假设我们想要破解LWP :: UserAgent的new()方法。这样做:

bash$ perl -d sample.pl --whatever-arguments
Loading DB routines from perl5db.pl version 1.37
Editor support available.

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

main::(use_mech.pl:7):  my $foo = WWW::Mechanize::Pluggable->new();

加载要设置断点的模块:

  DB<1> use LWP::UserAgent 

打印其@INC条目以确定您刚刚加载的文件(需要执行'f'命令):

  DB<2> p $INC{"LWP/UserAgent.pm"}
/Users/joemcmahon/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0/LWP/UserAgent.pm

使用'f'切换到该文件:

  DB<3> f /Users/joemcmahon/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0/LWP/UserAgent.pm
1   package LWP::UserAgent;
2   
3:  use strict;
4:  use vars qw(@ISA $VERSION);
5   
6:  require LWP::MemberMixin;
7:  @ISA = qw(LWP::MemberMixin);
8:  $VERSION = "6.04";
9   
10: use HTTP::Request ();

我们希望打破new(),所以找到它:

  DB<4> /new
20: sub new

通过'l'查找sub中的第一个可执行语句:

  DB<5> l
20  sub new
21  {
22      # Check for common user mistake
23:     Carp::croak("Options to LWP::UserAgent should be key/value pairs, not hash reference") 
24          if ref($_[1]) eq 'HASH'; 
25  
26:     my($class, %cnf) = @_;
27  
28:     my $agent = delete $cnf{agent};
29:     my $from  = delete $cnf{from};

在此行设置断点:

  DB<5> b 23

重新启动调试器:

  DB<6> R
Warning: some settings and command-line options may be lost!

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

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

main::(use_mech.pl:7):  my $foo = WWW::Mechanize::Pluggable->new();

运行程序,然后在你想要的位置中断。

  DB<6> c
LWP::UserAgent::new(/Users/joemcmahon/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0/LWP/UserAgent.pm:23):
23:     Carp::croak("Options to LWP::UserAgent should be key/value pairs, not hash reference") 
24:         if ref($_[1]) eq 'HASH'; 
  DB<6> 

这种技术对于调试import()问题特别方便;你可以加载有问题的模块。在import()中设置断点,然后重新启动。对于您感兴趣的模块,调试器将在import()中停止。

答案 3 :(得分:0)

如何使用c命令跳过require然后设置断点。例如

main::(prog:6):    require "A.pl";
  DB<1> l 
6==>    require "A.pl";
7   
8:  bar();
  DB<2> c 8
main::(prog:8): bar();
  DB<3> b bar
  DB<4> c
main::bar(C.pl:2):    print "A\n";
  DB<4>