File Coverage

lib/Devel/ebug.pm
Criterion Covered Total %
statement 83 84 98.8
branch 6 10 60.0
condition 1 3 33.3
subroutine 17 17 100.0
pod 1 3 33.3
total 108 117 92.3


line stmt bran cond sub pod time code
1             package Devel::ebug;
2              
3 21     21   1289572 use strict;
  21         222  
  21         644  
4 21     21   101 use warnings;
  21         36  
  21         531  
5 21     21   107 use Carp;
  21         28  
  21         1606  
6 21     21   10201 use Class::Accessor::Chained::Fast;
  21         75960  
  21         218  
7 21     21   11356 use Devel::StackTrace 2.00;
  21         118507  
  21         783  
8 21     21   10892 use IO::Socket::INET;
  21         466533  
  21         138  
9 21     21   21602 use Proc::Background;
  21         250495  
  21         1135  
10 21     21   9470 use String::Koremutake;
  21         126650  
  21         865  
11 21     21   10198 use YAML;
  21         150446  
  21         1206  
12 21     21   10258 use Module::Pluggable require => 1;
  21         234739  
  21         144  
13 21     21   12039 use File::Which ();
  21         21239  
  21         634  
14 21     21   9716 use FindBin qw($Bin); ## no critic (Freenode::DiscouragedModules)
  21         22674  
  21         2874  
15              
16 21     21   167 use base qw(Class::Accessor::Chained::Fast);
  21         40  
  21         12199  
17              
18             # ABSTRACT: A simple, extensible Perl debugger
19             our $VERSION = '0.63'; # VERSION
20              
21             __PACKAGE__->mk_accessors(qw(
22             backend
23             port
24             program socket proc
25             package filename line codeline subroutine finished));
26              
27             # let's run the code under our debugger and connect to the server it
28             # starts up
29             sub load {
30 42     42 1 72200 my $self = shift;
31 42         191 my $program = $self->program;
32              
33             # import all the plugins into our namespace
34 42         524 eval { $_->import } for $self->plugins;
  378         423876  
35              
36 42         888 my $k = String::Koremutake->new;
37 42         1419 my $rand = int(rand(100_000));
38 42         886 my $secret = $k->integer_to_koremutake($rand);
39 42         2780 my $port = 3141 + ($rand % 1024);
40              
41 42         460 $ENV{SECRET} = $secret;
42 42   33     584 my $backend = $self->backend || do {
43             -x "$Bin/ebug_backend_perl"
44             ? "$Bin/ebug_backend_perl"
45             : File::Which::which("ebug_backend_perl");
46             };
47 42         853 my $command = "$backend $program";;
48 42         545 my $proc = Proc::Background->new(
49             {'die_upon_destroy' => 1},
50             $command
51             );
52 42 50       61305 croak(qq{Devel::ebug: Failed to start up "$program" in load()}) unless $proc->alive;
53 42         6193 $self->proc($proc);
54 42         4093 $ENV{SECRET} = "";
55              
56 42         979 $self->attach($port, $secret);
57             }
58              
59             sub attach {
60 42     42 0 662 my ($self, $port, $key) = @_;
61              
62             # import all the plugins into our namespace
63 42         1537 eval { $_->import } for $self->plugins;
  378         507230  
64              
65             # try and connect to the server
66 42         176 my $socket;
67 42         203 foreach ( 1 .. 10 ) {
68 84         3143 $socket = IO::Socket::INET->new(
69             PeerAddr => "localhost",
70             PeerPort => $port,
71             Proto => 'tcp',
72             ReuseAddr => 1,
73             );
74 84 100       96976 last if $socket;
75 42         42007917 sleep 1;
76             }
77 42 50       308 die "Could not connect: $!" unless $socket;
78 42         512 $self->socket($socket);
79              
80 42         2604 my $response = $self->talk(
81             { command => "ping",
82             version => $Devel::ebug::VERSION,
83             secret => $key,
84             }
85             );
86 42         301 my $version = $response->{version};
87             die "Client version $version != our version $Devel::ebug::VERSION"
88 21 50   21   200 unless do { no warnings 'uninitialized'; $version eq $Devel::ebug::VERSION };
  21         73  
  21         4888  
  42         117  
  42         301  
89              
90 42         384 $self->basic; # get basic information for the first line
91             }
92              
93             #
94             # FIXME : this would mean that plugin writers don't need to Export stuff
95             #
96             #sub load_plugins {
97             # my $self = shift;
98             # my $obj = Devel::Symdump->new($self->plugins);
99             #
100             # for ($obj->functions) {
101             # my $name = (split /::/)[-1];
102             # next if substr($name,0,1) eq '_';
103             # *basic = \&$_;
104             # }
105             #
106             #}
107              
108              
109              
110             # at the moment, we talk hex-encoded YAML serialisation
111             # don't worry about this too much
112             sub talk {
113 473     473 0 1238 my($self, $req) = @_;
114 473         1578 my $socket = $self->socket;
115              
116 473         4957 my $data = unpack("h*", Dump($req));
117 473         733000 $socket->print($data . "\n");
118 473         4651090 $data = <$socket>;
119 473 50       4048 if ($data) {
120 473         779 my $res = do {
121 473         1193 $YAML::LoadBlessed = 1;
122 473         6137 Load(pack("h*", $data));
123             };
124 473         1418509 return $res;
125             } else {
126 0           return undef;
127             }
128             }
129              
130             1;
131              
132             __END__