File Coverage

lib/Devel/ebug.pm
Criterion Covered Total %
statement 77 78 98.7
branch 6 10 60.0
condition 1 3 33.3
subroutine 15 15 100.0
pod 1 3 33.3
total 100 109 91.7


line stmt bran cond sub pod time code
1             package Devel::ebug;
2              
3 21     21   1332216 use strict;
  21         229  
  21         640  
4 21     21   108 use warnings;
  21         29  
  21         595  
5 21     21   103 use Carp;
  21         42  
  21         1647  
6 21     21   10523 use Class::Accessor::Chained::Fast;
  21         78381  
  21         219  
7 21     21   12028 use Devel::StackTrace 2.00;
  21         122005  
  21         781  
8 21     21   12164 use IO::Socket::INET;
  21         485790  
  21         153  
9 21     21   23192 use Proc::Background;
  21         306589  
  21         1253  
10 21     21   10839 use String::Koremutake;
  21         128508  
  21         959  
11 21     21   11056 use YAML;
  21         157131  
  21         1296  
12 21     21   11392 use Module::Pluggable require => 1;
  21         242896  
  21         146  
13              
14 21     21   2074 use base qw(Class::Accessor::Chained::Fast);
  21         45  
  21         11942  
15              
16             # ABSTRACT: A simple, extensible Perl debugger
17             our $VERSION = '0.64'; # VERSION
18              
19             __PACKAGE__->mk_accessors(qw(
20             backend
21             port
22             program socket proc
23             package filename line codeline subroutine finished));
24              
25             # let's run the code under our debugger and connect to the server it
26             # starts up
27             sub load {
28 42     42 1 64623 my $self = shift;
29 42         182 my $program = $self->program;
30              
31             # import all the plugins into our namespace
32 42         551 eval { $_->import } for $self->plugins;
  378         432816  
33              
34 42         952 my $k = String::Koremutake->new;
35 42         1440 my $rand = int(rand(100_000));
36 42         319 my $secret = $k->integer_to_koremutake($rand);
37 42         2557 my $port = 3141 + ($rand % 1024);
38              
39 42         446 $ENV{SECRET} = $secret;
40 42   33     235 my $backend = $self->backend || "$^X -d:ebug::Backend";
41 42         1082 my $command = "$backend $program";
42 42         515 my $proc = Proc::Background->new(
43             {'die_upon_destroy' => 1},
44             $command
45             );
46 42 50       67483 croak(qq{Devel::ebug: Failed to start up "$program" in load()}) unless $proc->alive;
47 42         6097 $self->proc($proc);
48 42         4161 $ENV{SECRET} = "";
49              
50 42         1976 $self->attach($port, $secret);
51             }
52              
53             sub attach {
54 42     42 0 574 my ($self, $port, $key) = @_;
55              
56             # import all the plugins into our namespace
57 42         1085 eval { $_->import } for $self->plugins;
  378         518327  
58              
59             # try and connect to the server
60 42         153 my $socket;
61 42         255 foreach ( 1 .. 10 ) {
62 84         3396 $socket = IO::Socket::INET->new(
63             PeerAddr => "localhost",
64             PeerPort => $port,
65             Proto => 'tcp',
66             ReuseAddr => 1,
67             );
68 84 100       103146 last if $socket;
69 42         42008597 sleep 1;
70             }
71 42 50       320 die "Could not connect: $!" unless $socket;
72 42         652 $self->socket($socket);
73              
74 42         2730 my $response = $self->talk(
75             { command => "ping",
76             version => $Devel::ebug::VERSION,
77             secret => $key,
78             }
79             );
80 42         270 my $version = $response->{version};
81             die "Client version $version != our version $Devel::ebug::VERSION"
82 21 50   21   170 unless do { no warnings 'uninitialized'; $version eq $Devel::ebug::VERSION };
  21         42  
  21         4720  
  42         98  
  42         263  
83              
84 42         781 $self->basic; # get basic information for the first line
85             }
86              
87             #
88             # FIXME : this would mean that plugin writers don't need to Export stuff
89             #
90             #sub load_plugins {
91             # my $self = shift;
92             # my $obj = Devel::Symdump->new($self->plugins);
93             #
94             # for ($obj->functions) {
95             # my $name = (split /::/)[-1];
96             # next if substr($name,0,1) eq '_';
97             # *basic = \&$_;
98             # }
99             #
100             #}
101              
102              
103              
104             # at the moment, we talk hex-encoded YAML serialisation
105             # don't worry about this too much
106             sub talk {
107 473     473 0 1333 my($self, $req) = @_;
108 473         1793 my $socket = $self->socket;
109              
110 473         5305 my $data = unpack("h*", Dump($req));
111 473         802494 $socket->print($data . "\n");
112 473         4684504 $data = <$socket>;
113 473 50       4998 if ($data) {
114 473         910 my $res = do {
115 473         1396 $YAML::LoadBlessed = 1;
116 473         7638 Load(pack("h*", $data));
117             };
118 473         1536235 return $res;
119             } else {
120 0           return undef;
121             }
122             }
123              
124             1;
125              
126             __END__