AnyEvent-GDB

 view release on metacpan or  search on metacpan

GDB.pm  view on Meta::CPAN

An optional array of parameters to pass to GDB. This should not be
used to load a program executable, use the C<file_exec_and_symbols>,
C<target_attach> or similar MI commands instead.

=item trace => $boolean (default: 0)

If true, then all commands sent to GDB are printed to STDOUT prefixed with
"> ", and all replies received from GDB are printed to STDOUT prefixed
with "< ".

=item verbose => $boolean (default: true if trace is enabled, false otherwise)

If true, then log output and possibly other information is printed to
STDOUT.

=item on_xxxx => $callback->(...)

This specifies a callback for a specific event - see the L<EVENTS> section
later in this document.

=back

=cut

sub new {
   my ($class, %arg) = @_;

   my $self = bless {
      %arg,
   }, $class;

   my $exe = delete $self->{exec} // "gdb";
   my $arg = delete $self->{args} // [qw(-n)];

   $self->{verbose} = 1
      if $self->{trace} && !exists $self->{verbose};

   ($self->{fh}, my $fh2) = AnyEvent::Util::portable_socketpair;

   $self->{pid} = fork;

   open my $stdin , "<&STDIN" ;
   open my $stdout, ">&STDOUT";

   unless ($self->{pid}) {
      if (defined $self->{pid}) {
         open STDIN , "<&", $fh2;
         open STDOUT, ">&", $fh2;
         fcntl $stdin , Fcntl::F_SETFD, 0;
         fcntl $stdout, Fcntl::F_SETFD, 0;
         exec $exe, qw(--interpreter=mi2 -q), @$arg;
         kill 9, 0; # don't want to load the POSIX module just for this
      } else {
         Carp::croak "cannot fork: $!";
      }
   }

   AnyEvent::Util::fh_nonblocking $self->{fh}, 1;

   {
      Scalar::Util::weaken (my $self = $self);
      $self->{rw} = AE::io $self->{fh}, 0, sub {
         my $len = sysread $self->{fh}, $self->{rbuf}, 256, length $self->{rbuf};

         defined $len || $self->eof;

         $self->feed ("$1")
            while $self->{rbuf} =~ s/^([^\r\n]*)\r?\n//;
      };

      $self->{wcb} = sub {
         my $len = syswrite $self->{fh}, $self->{wbuf};
         substr $self->{wbuf}, 0, $len, "";
         delete $self->{ww} unless length $self->{wbuf};
      };
   }

   $self->{stdio} = sprintf "<&%d >&%d", fileno $stdin, fileno $stdout;

   $self->cmd_raw ("set exec-wrapper $self->{stdio}", sub { });

   $self
}

#sub DESTROY {
#)}

sub eof {
   my ($self) = @_;

   $self->event ("eof");

   %$self = ();
}

sub send {
   my ($self, $data) = @_;

   print "> $data"
      if $self->{trace};

   $self->{wbuf} .= $data;
   $self->{ww} ||= AE::io $self->{fh}, 1, $self->{wcb};
}

our %C_ESCAPE = (
   "\\" => "\\",
   '"' => '"',
   "'" => "'",
   "?" => "?",

   a => "\x07",
   b => "\x08",
   t => "\x09",
   n => "\x0a",
   v => "\x0b",
   f => "\x0c",
   r => "\x0d",
);

sub _parse_c_string {



( run in 1.475 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )