开发者

How do you break on a specific line of a require'd file in the Perl debugger?

I've got a Perl script, let's call it A.pl where the first two lines look something开发者_C百科 like this:

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

Where both B.pl and C.pl each have their own cavalcade of requires. I need to set a breakpoint on a specific line of C.pl. In GDB I'd do something like:

b C.pl:830

However that doesn't seem to work at all here. Is it possible? Am I close?


I prefer the cheap trick of the debugger's 'R' (restart) command. Here's a sample program:

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

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

and let's assume that we want to break at LWP::UserAgent's new() method. Do this:

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();

Load the module you want to set the breakpoint in:

  DB<1> use LWP::UserAgent 

Print its @INC entry to figure out what file you just loaded (needed to do the 'f' command):

  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

Switch to that file with '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 ();

We want to break in new(), so find it:

  DB<4> /new
20: sub new

Find the first executable statement in the sub via 'l':

  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};

Set a breakpoint at this line:

  DB<5> b 23

Restart the debugger:

  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();

Run the program, and you break at the point you wanted.

  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> 

This technique is particularly handy for debugging import() problems; you can load the module that's having trouble. set a breakpoint in import(), and then restart. The debugger will stop in import() for the module you're interested in.


You could also edit C.pl adding this:

$DB::single = 1;

and the debugger will stop immediately after executing that line, and before executing the next line. This is similar to Ruby's 'debugger' statement.

See also: perldoc DB


You can't do it in one step, but you can change to the file you want and then set a breakpoint on a specific line:

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

DB<2> b 830

DB<3> c


How about using the c command to skip past the requires and then setting a breakpoint. For example

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> 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜