Devel-ebug

 view release on metacpan or  search on metacpan

lib/Devel/ebug.pm  view on Meta::CPAN

package Devel::ebug;

use strict;
use warnings;
use Carp;
use Class::Accessor::Chained::Fast;
use Devel::StackTrace 2.00;
use IO::Socket::INET;
use Proc::Background;
use String::Koremutake;
use YAML;
use Module::Pluggable require => 1;

use base qw(Class::Accessor::Chained::Fast);

# ABSTRACT: A simple, extensible Perl debugger
our $VERSION = '0.64'; # VERSION

__PACKAGE__->mk_accessors(qw(
    backend
    port
    program socket proc
    package filename line codeline subroutine finished));

# let's run the code under our debugger and connect to the server it
# starts up
sub load {
  my $self = shift;
  my $program = $self->program;

  # import all the plugins into our namespace
  eval { $_->import } for $self->plugins;

  my $k = String::Koremutake->new;
  my $rand = int(rand(100_000));
  my $secret = $k->integer_to_koremutake($rand);
  my $port   = 3141 + ($rand % 1024);

  $ENV{SECRET} = $secret;
  my $backend = $self->backend || "$^X -d:ebug::Backend";
  my $command = "$backend $program";
  my $proc = Proc::Background->new(
    {'die_upon_destroy' => 1},
    $command
  );
  croak(qq{Devel::ebug: Failed to start up "$program" in load()}) unless $proc->alive;
  $self->proc($proc);
  $ENV{SECRET} = "";

  $self->attach($port, $secret);
}

sub attach {
    my ($self, $port, $key) = @_;

    # import all the plugins into our namespace
    eval { $_->import } for $self->plugins;

    # try and connect to the server
    my $socket;
    foreach ( 1 .. 10 ) {
        $socket = IO::Socket::INET->new(
            PeerAddr   => "localhost",
            PeerPort   => $port,
            Proto      => 'tcp',
            ReuseAddr => 1,
        );
        last if $socket;
        sleep 1;
    }
    die "Could not connect: $!" unless $socket;
    $self->socket($socket);

    my $response = $self->talk(
        {   command => "ping",
            version => $Devel::ebug::VERSION,
            secret  => $key,
        }
    );
    my $version = $response->{version};
    die "Client version $version != our version $Devel::ebug::VERSION"
        unless do { no warnings 'uninitialized'; $version eq $Devel::ebug::VERSION };

    $self->basic;    # get basic information for the first line
}

#
# FIXME : this would mean that plugin writers don't need to Export stuff
#
#sub load_plugins {
#    my $self = shift;
#    my $obj = Devel::Symdump->new($self->plugins);
#
#    for ($obj->functions) {
#        my $name = (split /::/)[-1];
#        next if substr($name,0,1) eq '_';
#        *basic = \&$_;
#    }
#
#}



# at the moment, we talk hex-encoded YAML serialisation
# don't worry about this too much
sub talk {



( run in 1.403 second using v1.01-cache-2.11-cpan-97f6503c9c8 )