The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Debug::Client - client side code for perl debugger

SYNOPIS

  use Debug::Client;
  my $debugger = Debug::Client->new(host => $host, port => $port);
  $debugger->listen;

Where $host is the hostname to be used by the script under test (SUT) to acces the machine where Debug::Client runs. If they are on the same machine this should be localhost. $port can be any port number where the Debug::Client could listen.

This is the point where the external SUT needs to be launched by first setting

  $ENV{PERLDB_OPTS} = "RemotePort=$host:$port"

then running

  perl -d script

Once the script under test wa launched we can call the following:

  my $out = $debugger->get;

  $out = $debugger->step_in;

  $out = $debugger->step_over;


  my ($prompt, $module, $file, $row, $content) = $debugger->step_in;
  my ($module, $file, $row, $content, $return_value) = $debugger->step_out;
  my $value = $debugger->get_value('$x');

  $debugger->run();         # run till end of breakpoint or watch
  $debugger->run( 42 );     # run till line 42  (c in the debugger)
  $debugger->run( 'foo' );  # run till beginning of sub

  $debugger->execute_code( '$answer = 42' );

  $debugger->execute_code( '@name = qw(foo bar)' );

  my $value = $debugger->get_value('@name');  $value is the dumped data?

  $debugger->execute_code( '%phone_book = (foo => 123, bar => 456)' );

  my $value = $debugger->get_value('%phone_book');  $value is the dumped data?
  
  
  $debugger->set_breakpoint( "file", 23 ); #    set breakpoint on file, line

  $debugger->get_stack_trace

Other planned methods:

  $debugger->set_breakpoint( "file", 23, COND ); #      set breakpoint on file, line, on condition
  $debugger->set_breakpoint( "file", subname, [COND] )

  $debugger->set_watch
  $debugger->remove_watch
  $debugger->remove_breakpoint


  $debugger->watch_variable   (to make it easy to display values of variables)

example

  my $script = 'script_to_debug.pl';
  my @args   = ('param', 'param');
  
  my $perl = $^X; # the perl might be a different perl
  my $host = 'localhost';
  my $port = 12345;
  my $pid = fork();
  die if not defined $pid;
  
  if (not $pid) {
        local $ENV{PERLDB_OPTS} = "RemotePort=$host:$port"
        exec("$perl -d $script @args");
  }
  
  
  require Debug::Client;
  my $debugger = Debug::Client->new(
    host => $host,
    port => $port,
  );
  $debugger->listen;
  my $out = $debugger->get;
  $out = $debugger->step_in;
  # ...

DESCRIPTION

new

The constructor can get two parameters: host and port.

  my $d = Debug::Client->new;

  my $d = Debug::Client->new(host => 'remote.hots.com', port => 4242);
   

Immediately after the object creation one needs to call

  $d->listen;
  

TODO: Is there any reason to separate the two?

listen

See new

buffer

Returns the content of the buffer since the last command

  $debugger->buffer;

quit

show_line

step_in

step_over

step_out

 my ($prompt, $module, $file, $row, $content, $return_value) = $debugger->step_out;

Where $prompt is just a number, probably useless

$return_value will be undef if the function was called in VOID context

It will hold a scalar value if called in SCALAR context

It will hold a reference to an array if called in LIST context.

TODO: check what happens when the return value is a reference to a complex data structure or when some of the elements of the returned array are themselves references

get_stack_trace

Sends the stack trace command T to the remote debugger and returns it as a string if called in scalar context. Returns the prompt number and the stack trace string when called in array context.

toggle_trace

Sends the stack trace command t Toggle trace mode (see also the AutoTrace option).

list_subroutine_names

Sends the stack trace command S [[!]pattern] List subroutine names [not] matching pattern.

run

  $d->run;
  

Will run till the next breakpoint or watch or the end of the script. (Like pressing c in the debugger).

  $d->run($param)

set_breakpoint

 $d->set_breakpoint($file, $line, $condition);

remove_breakpoint

show_breakpoints

The data as (L) prints in the command line debugger.

 $d->show_breakpoints();

list_break_watch_action

In scalar context returns the list of all the breakpoints and watches as a text output. The data as (L) prints in the command line debugger.

In list context it returns the promt number, and a list of hashes. Each hash has

  file =>
  line =>
  cond => 

to provide the filename, line number and the condition of the breakpoint. In case of no condition the last one will be the number 1.

execute_code

  $d->execute_code($some_code_to_execute);

get_value

 my $value = $d->get_value($x);

If $x is a scalar value, $value will contain that value. If it is a reference to a SCALAR, ARRAY or HASH then $value should be the value of that reference?

get_y_zero

From perldebug, but defaulted to y 0

 y [level [vars]]

Display all (or some) lexical variables (mnemonic: mY variables) in the current scope or level scopes higher. You can limit the variables that you see with vars which works exactly as it does for the V and X commands. Requires the PadWalker module version 0.08 or higher; will warn if this isn't installed. Output is pretty-printed in the same style as for V and the format is controlled by the same options.

  $d->get_y_zero();

get_v_vars

V [pkg [vars]]

Display all (or some) variables in package (defaulting to main ) using a data pretty-printer (hashes show their keys and values so you see what's what, control characters are made printable, etc.). Make sure you don't put the type specifier (like $ ) there, just the symbol names, like this:

 $d->get_v_vars(regex);

get_x_vars

X [vars] Same as V currentpackage [vars]

 $d->get_v_vars(regex);

_parse_dumper

_get

_prompt

_process_line

get

Actually I think this is an internal method....

In SCALAR context will return all the buffer collected since the last command.

In LIST context will return ($prompt, $module, $file, $row, $content) Where $prompt is the what the standard debugger uses for prompt. Probably not too interesting. $file and $row describe the location of the next instructions. $content is the actual line - this is probably not too interesting as it is in the editor. $module is just the name of the module in which the current execution is.

_send

send_get

filename

row

_logger

See Also

GRID::Machine::remotedebugtut

AUTHORS

Gabor Szabo <gabor@szabgab.com>

Breno G. de Oliveira <garu at cpan.org>

Kevin Dawson <bowtie@cpan.org>

COPYRIGHT

Copyright 2008-2011 Gabor Szabo. http://szabgab.com/

LICENSE

This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5 itself.

BUGS AND LIMITATIONS

Debug::Client 0.12 tests are failing, due to changes in perl debugger, when using perl5db.pl v1.34 Debug::Client 0.13_01 skips added to failing tests.

 c [line|sub]

Continue, optionally inserting a one-time-only breakpoint at the specified line or subroutine.

 c is now ignoring options [line|sub]

and just performing c on it's own

WARRANTY

There is no warranty whatsoever. If you lose data or your hair because of this program, that's your problem.

CREDITS and THANKS

Originally started out from the remoteport.pl script from Pro Perl Debugging written by Richard Foley.