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   1324934 use strict;
  21         218  
  21         682  
4 21     21   94 use warnings;
  21         34  
  21         1006  
5 21     21   93 use Carp;
  21         30  
  21         1645  
6 21     21   10759 use Class::Accessor::Chained::Fast;
  21         76693  
  21         198  
7 21     21   10409 use Devel::StackTrace 2.00;
  21         120647  
  21         713  
8 21     21   10545 use IO::Socket::INET;
  21         452386  
  21         140  
9 21     21   20674 use Proc::Background;
  21         242137  
  21         1239  
10 21     21   8817 use String::Koremutake;
  21         116604  
  21         925  
11 21     21   9499 use YAML;
  21         153494  
  21         1146  
12 21     21   9645 use Module::Pluggable require => 1;
  21         226860  
  21         152  
13 21     21   11632 use File::Which ();
  21         19950  
  21         619  
14 21     21   8886 use FindBin qw($Bin); ## no critic (Freenode::DiscouragedModules)
  21         21094  
  21         2581  
15              
16 21     21   138 use base qw(Class::Accessor::Chained::Fast);
  21         41  
  21         11700  
17              
18             # ABSTRACT: A simple, extensible Perl debugger
19             our $VERSION = '0.62_01'; # TRIAL VERSION
20             $VERSION = eval $VERSION; ## no critic (BuiltinFunctions::ProhibitStringyEval)
21              
22             __PACKAGE__->mk_accessors(qw(
23             backend
24             port
25             program socket proc
26             package filename line codeline subroutine finished));
27              
28             # let's run the code under our debugger and connect to the server it
29             # starts up
30             sub load {
31 42     42 1 66696 my $self = shift;
32 42         172 my $program = $self->program;
33              
34             # import all the plugins into our namespace
35 42         491 eval { $_->import } for $self->plugins;
  378         418349  
36              
37 42         795 my $k = String::Koremutake->new;
38 42         1285 my $rand = int(rand(100_000));
39 42         366 my $secret = $k->integer_to_koremutake($rand);
40 42         2337 my $port = 3141 + ($rand % 1024);
41              
42 42         448 $ENV{SECRET} = $secret;
43 42   33     294 my $backend = $self->backend || do {
44             -x "$Bin/ebug_backend_perl"
45             ? "$Bin/ebug_backend_perl"
46             : File::Which::which("ebug_backend_perl");
47             };
48 42         951 my $command = "$backend $program";;
49 42         544 my $proc = Proc::Background->new(
50             {'die_upon_destroy' => 1},
51             $command
52             );
53 42 50       71555 croak(qq{Devel::ebug: Failed to start up "$program" in load()}) unless $proc->alive;
54 42         5674 $self->proc($proc);
55 42         3886 $ENV{SECRET} = "";
56              
57 42         952 $self->attach($port, $secret);
58             }
59              
60             sub attach {
61 42     42 0 613 my ($self, $port, $key) = @_;
62              
63             # import all the plugins into our namespace
64 42         1308 eval { $_->import } for $self->plugins;
  378         501801  
65              
66             # try and connect to the server
67 42         173 my $socket;
68 42         189 foreach ( 1 .. 10 ) {
69 84         2731 $socket = IO::Socket::INET->new(
70             PeerAddr => "localhost",
71             PeerPort => $port,
72             Proto => 'tcp',
73             Reuse => 1,
74             ReuserAddr => 1,
75             );
76 84 100       87382 last if $socket;
77 42         42010134 sleep 1;
78             }
79 42 50       228 die "Could not connect: $!" unless $socket;
80 42         564 $self->socket($socket);
81              
82 42         2045 my $response = $self->talk(
83             { command => "ping",
84             version => $Devel::ebug::VERSION,
85             secret => $key,
86             }
87             );
88 42         274 my $version = $response->{version};
89             die "Client version $version != our version $Devel::ebug::VERSION"
90 21 50   21   177 unless do { no warnings 'uninitialized'; $version eq $Devel::ebug::VERSION };
  21         56  
  21         4467  
  42         97  
  42         745  
91              
92 42         396 $self->basic; # get basic information for the first line
93             }
94              
95             #
96             # FIXME : this would mean that plugin writers don't need to Export stuff
97             #
98             #sub load_plugins {
99             # my $self = shift;
100             # my $obj = Devel::Symdump->new($self->plugins);
101             #
102             # for ($obj->functions) {
103             # my $name = (split /::/)[-1];
104             # next if substr($name,0,1) eq '_';
105             # *basic = \&$_;
106             # }
107             #
108             #}
109              
110              
111              
112             # at the moment, we talk hex-encoded YAML serialisation
113             # don't worry about this too much
114             sub talk {
115 473     473 0 1407 my($self, $req) = @_;
116 473         1684 my $socket = $self->socket;
117              
118 473         4603 my $data = unpack("h*", Dump($req));
119 473         790108 $socket->print($data . "\n");
120 473         4459473 $data = <$socket>;
121 473 50       3982 if ($data) {
122 473         831 my $res = do {
123 473         1366 $YAML::LoadBlessed = 1;
124 473         6543 Load(pack("h*", $data));
125             };
126 473         1356043 return $res;
127             } else {
128 0           return undef;
129             }
130             }
131              
132             1;
133              
134             __END__