AnyEvent-GDB
view release on metacpan or search on metacpan
=head1 NAME
AnyEvent::GDB - asynchronous GDB machine interface interface
=head1 SYNOPSIS
use AnyEvent::GDB;
=head1 DESCRIPTION
This module is an L<AnyEvent> user, you need to make sure that you use and
run a supported event loop.
It implements the GDB MI protocol, which can be used to talk to GDB
without having to parse the ever changing command syntax aimed at humans.
It properly quotes your commands and parses the data structures returned
by GDB.
At the moment, it's in an early stage of development, so expect changes,
and, over time, further features (such as breakpoint-specific callbacks
and so on).
=head1 EXAMPLE PROGRAM
To get you started, here is an example program that runs F</bin/ls>,
displaying the stopped information when hitting a breakpoint on C<_exit>:
use Data::Dump;
use AnyEvent::GDB;
our $gdb = new AnyEvent::GDB
trace => 1,
on_exec_stopped => sub {
ddx $_[0];
},
;
my $done
ddx $gdb->cmd_sync (file_exec_and_symbols => "/bin/ls");
ddx $gdb->cmd_sync (break_insert => "_exit");
ddx $gdb->cmd_sync ("exec_run");
AE::cv->recv;
=head2 PROTOCOL QUIRKS
=head3 Minus vs. underscores
The MI protocol uses C<-> to separate name components, while in Perl, you
use C<_> for this purpose.
This module usually accepts either form as input, and always converts
names with C<-> to names with C<_>, so the C<library-loaded> notify might
become C<notify_library_loaded>, and the C<host-name> result in that event
is stored in the C<host_name> hash element in Perl.
=head3 Output redirection
Unfortunately, GDB has no (portable) provision to separate GDB
input/output from program input/output. Obviously, without a distinction
between program I/O and GDB I/O it becomes impossible to safely control
delete $self->{thread}{$r->{id}};
}
sub _threads {
my ($self, $id) = @_;
ref $id
? @{ $self->{thread} }{@$id}
: $id eq "all"
? values %{ $self->{thread} }
: $self->{thread}{$id}
}
sub on_exec_running {
my ($self, undef, $r) = @_;
for ($self->_threads ($r->{thread_id})) {
delete $_->{stopped};
$_->{running} = 1;
}
}
sub on_exec_stopped {
my ($self, undef, $r) = @_;
for ($self->_threads ($r->{stopped_threads})) {
delete $_->{running};
$_->{stopped} = $r;
}
# $self->event ("thread_$r->{reason}" => $r, [map $_->{id}, $self->_threads ($r)]);
}
sub _thread_groups {
my ($self, $r) = @_;
exists $r->{thread_group}
? $self->{thread_group}{$r->{thread_group}}
: values %{ $self->{thread_group} }
}
sub on_notify_library_loaded {
my ($self, undef, $r) = @_;
$_->{library}{$r->{id}} = $r
for $self->_thread_groups ($r);
}
sub on_notify_library_unloaded {
my ($self, undef, $r) = @_;
delete $_->{library}{$r->{id}}
for $self->_thread_groups ($r);
}
=back
=head2 EVENTS
AnyEvent::GDB is asynchronous in nature, as the goal of the MI interface
is to be fully asynchronous. Due to this, a user of this interface must
be prepared to handle various events.
When an event is produced, the GDB object will look for the following four
handlers and, if found, will call each one in order with the GDB object
and event name (without C<on_>) as the first two arguments, followed by
any event-specific arguments:
=over 4
=item on_event method on the GDB object
Useful when subclassing.
=item on_event constructor parameter/object member
The callback specified as C<on_event> parameter to the constructor.
=item on_EVENTNAME method on the GDB object
Again, mainly useful when subclassing.
=item on_EVENTNAME constructor parameter/object member
Any callback specified as C<on_EVENTNAME> parameter to the constructor.
=back
You can change callbacks dynamically by simply replacing the corresponding
C<on_XXX> member in the C<$gdb> object:
$gdb->{on_event} = sub {
# new event handler
};
Here's the list of events with a description of their arguments.
=over 4
=item on_eof => $cb->($gdb, "eof")
Called whenever GDB closes the connection. After this event, the object is
partially destroyed and must not be accessed again.
=item on_target => $cb->($gdb, "target", $string)
Output received from the target. Normally, this is sent directly to STDOUT
by GDB, but remote targets use this hook.
=item on_log => $cb->($gdb, "log", $string)
Log output from GDB. Best printed to STDOUT in interactive sessions.
=item on_TYPE => $cb->($gdb, "TYPE", $class, $results)
Called for GDB C<exec>, C<status> and C<notify> event (TYPE is one of
these three strings). C<$class> is the class of the event, with C<->
replaced by C<_> everywhere.
For each of these, the GDB object will create I<two> events: one for TYPE,
and one for TYPE_CLASS. Usuaully you should provide the more specific
( run in 0.811 second using v1.01-cache-2.11-cpan-2398b32b56e )