NAME

Devel::hdb::Client - Perl bindings for Devel::hdb's REST interface

DESCRIPTION

Talks to the REST interface of Devel::hdb to control the debugged program. It uses the same interface the HTML/GUI debugger uses, and has all the same capabilities.

SYNOPSIS

my $client = Devel::hdb::Client->new(url => 'http://localhost:8080');
my $status = $client->status();
printf("Stopped in %s at %s:%d\n", @status{'subroutine','filename','line});

$status = $client->step();

$client->exit();

CONSTRUCTOR

my $client = Devel::hdb::Client->new(url => $url);

Create a new client instance. $url is the base url the debugger is listening on. In particular, it does _not_ include '/debugger-gui'. new() also accepts the parameter debug = 1> to turn on the debugging flag; when on, it prints messages to STDERR.

METHODS

All methods will throw an exception if the response from the debugger is not a successful response. See EXCEPTIONS below for more info.

$client->stack();

Perform GET /stack

Return an arrayref of hashrefs. Each hashref is a caller frame. It returns all the same data as Devel::Chitin::StackFrame. Their keys are the same as is returned by the caller() built-in:

filename
line
package
subroutine
wantarray
hasargs
evaltext
is_require
hints
bitmask

and a few derived items

args

An arrayref of arguments to the function. See "PERL VALUES" below.

autoload

If this frame is a call to &AUTOLOAD, then this will be the name this function was called as.

evalfile

If this frame is a string eval, this is the file the string eval appears.

evalline

If this frame is a string eval, this is the line the string eval appears.

subname

The subroutine name without the package name.

level

A number indicating how deep this caller frame actually is.

serial

A unique identifier for this caller frame. It will stay the same as long as this frame is still active.

$client->stack_frame($level);

Perform GET /stack/$level

Get a single caller frame. Returns a hashref representing the requested frame. Frames are numbered starting with 0. Frame 0 is the point the debugged program is stopped at. If using this method to scan for frames by repetedly calling stack_frame() with larger numbers, remember that it will throw an exception when retrieving a frame that does not exist (eg. getting frame 10 when the stack is only 9 deep).

$client->stack_frame_signature($level)

Perform HEAD /stack/$level

Return a 2-element list for the given frame: serial and line. If a particular frame's serial number changes, it is a new function call. If the serial is the same, but the line changes, then the same function call has moved on to a different line.

$client->gui()

Perform GET /debugger-gui and return a string.

$client->status()

Perform GET /status

Return a hashref with short information about the debugged program. It has these keys:

running - Boolean, true if the program has not yet terminated
subroutine - Subroutine name the program is stopped in
filename - File the program is stopped in
line - Line the program is stopped in

Additionally, if there were any asynchronous events since the last status-like call, there's a key 'events' containing a listref of hashrefs, one for each event. See the section EVENTS below.

$client->stepin()

Perform POST /stepin

Tell the debugger to step into the next statement, including function calls. Returns the same hashref as status().

$client->stepover()

Perform POST /stepover

Tell the debugger to step over one statement. If the next statment is a function call, it stops immediately after that subroutine returns. Returns the same hashref as status().

$client->stepout()

Perform POST /stepout

Tell the debugger to continue until the current function returns. The debugger stops before the next statment after the function call. Returns the same hashref as status().

$client->continue()

Perform POST /continue

Tell the debugger to continue running the program. The next time the debugger stops, the call returns the same hashref as status().

$client->exit()

Perform POST /exit

Tell the debugger to exit. Returns true.

$client->create_breakpoint(filename => $file, line => $line, code => $expr, inactive => $bool)
$client->create_action(filename => $file, line => $line, code => $expr, inactive => $bool)

Perform POST /breakpoints or POST /actions

Create a breakpoint or action on the given file and line, which are required arguments.

'code' is a Perl expression to execute before the actual program line. For breakpoints, if this expression evaluates to true, the debugger will stop before executing that line. It defaults to '1' to create an unconditional breakpoint. For actions, the result is ignored, but 'code' is a required argument.

If 'inactive' is true, the breakpoint/action will be saved, but not actually evaluated. Defaults to false.

Returns a scalar value representing the breakpoint/action.

$client->get_breakpoint($bp)
$client->get_action($bp)

Perform GET /breakpoints/<id> or GET /actions/<id>

Return a hashref containing information about the requested breakpoint/action. The arg, $bp, is the scalar returned by create_breakpoint() or create_action(). The returned hashref has these keys:

filename
line
code
inactive
href
$client->delete_breakpoint($bp)
$client->delete_action($bp)

Perform DELETE /breakpoints/<id> or DELETE /actions/<id>

Removes the given breakpoint or action. Returns true. Throws an exception if the given breakpoint/action does not exist.

$client->change_breakpoint($bp, %changes)
$client->change_breakpoint($bp, %changes)

Perform POST /breakpoints/<id> or POST /actions/<id>

Changes parameters for the given breakpoint or action. The only 'code' and 'inactive' may be changed.

$client->get_breakpoints(%filter)
$client->get_actions(%filter)

Perform GET /breakpoints or GET /actions with parameters

Find breakpoints or actions matching the given parameters. The %filter is a list of key/value pairs describing what you're looking for. For example:

$client->get_breakpoints(filename => 'main.pl')

Will return all the breakpoints in the file main.pl.

$client->get_breakpoints(inactive => 0)

Will return all active breakpoints in the program.

You can filter on filename, line, code or inactive. If no filters are used, then it returns all breakpoints or actions.

The return value is a listref of hashrefs.

$client->add_watchpoint($expression)

Add a watchpoint expression. These expressions are evaluated before each statement in the program. If their value ever changes, the program will stop and the status will include a 'watchpoint' event indicating which line caused the change.

$client->delete_watchpoint($expression)

Remove a watchpoint expression. It must have been previously added with add_watchpoint() or an exception will be thrown.

$client->get_watchpoints($expression)

Return a listref of hashrefs with all the currently set watchpoints. Each hashref has these keys

expr

The watchpoint expression

href

A URL uniquely identifying this watchpoint

$client->loaded_files()

Perform GET /source

Return a listref of hashrefs, one for each file currently loaded in the program. Each hashref has a key 'filename' with the name of the file.

$client->file_source_and_breakable()

Perform GET /source/<filename>

Return a listref of 2-element listrefs. For each 2-elt list, the first element is a string containing the perl source code for that line. The second element is true if that line may contain a breakpoint.

$client->eval($expr)

Perform POST /eval

Evaluate an expression in the most recent caller frame of the debugged program. The expression is evaluated in the same context as the call to this method: void, scalar or list.

Returns whatever the expression evaluated to. See "PERL VALUES" below.

$client->get_var_at_level($varname, $level)

Perform GET /getvar/<level>/<varname>

Get the value of the given variable at the given caller frame depth. The variable must contain the sigil. If the frame does not exist, or the variable does not exist at that depth, it will throw an exception.

Returns the value of the variable. See "PERL VALUES" below.

$client->load_config($filename)

Load configuration information from the given filename.

$client->save_config($filename)

Save configuration such as breakpoints, to the given filename.

$client->package_info($package)

Perform GET /packageinfo/$package

Get information about the given package. Returns a hashref with these keys

name

Name of the pckage

packages

Listref of hashrefs, one for each package inside this one. Each hashref has a 'name' key with the name of the package.

subroutines

Listref of hashrefs, one for each subroutine inside this package. Each hashref has a 'name' key with the name of the sub.

$client->sub_info($sub_name)

Perform GET /subinfo/$sub_name

Return a hashref with information about the named sub. $sub_name should include the package, or 'main::' is assummed.

suboroutine

Subroutine name, not including the package

package

Package name

filename

File the sub is in

line

Line the subroutine is defined

end

Last line where the sub is defined

source

If the sub was created in a string eval, this is the file the eval happened in

source_line

Line the string eval happened at

EVENTS

The control methods (stepin, stepout, stepover, continue) and status() all return a data structure that may contain a listref for the key 'events'. Events are asynchronous events that happened since the last status report. They all have a 'type' key. Other keys are type specific.

fork event

When the debugged program fork()s, this event is generated in the parent process.

pid

The processID of the child process

href

URL for the debugger in the child process. You may use this URL to construct another Devel::hdb::Client.

gui_href

URL to bring up the graphical debugger in a browser.

href_continue

URL to POST to tell the child to run without stopping.

watchpoint event

When a watchpoint expression's value changes.

expr

The perl expression whose value changed

old

The old value of the expression. Watchpoint expressions are evaluated in list context, so old will always be a listref.

new

The new value of the expression. Also a listref.

filename
line
package
subroutine

The location where the change likely happened. This is whichever line was executing immediately before the change was detected.

exception event

When the program throws an uncaught exception.

value

The "value" of the exception. Either the string passed to die, or perhaps an exception object

package
filename
line
subroutine

Location information about where the exception was thrown

exit event

When the debugged program has finished. The debugger is still running.

value

The process exit code

hangup event

When the debugger has exited and is no longer listening for requests.

trace_diff event

When execution has differed from the previous run, when run in follow mode.

filename
line
package
subroutine
sub_offset

Where the program is currently stopped. sub_offset is the line number within the subroutine.

expected_filename
expected_line
expected_package
expected_subroutine
expected_sub_offset

Where the debugger expected the program to be.

PERL VALUES

For methods that return Perl values such as eval(), get_var_at_level(), or the argument lists in a stack frame, the data is deserialized with Data::Transform::ExplicitMetadata::decode(). If the variable has special Perl attributes (such as blessed, tied, filehandle), decode() will try to re-create that specialness.

EXCEPTIONS

This class uses Exception classes. They stringify to something reasonable.

Devel::hdb::Client::RequiredParameterMissing is thrown when a method requires a parameter that was missing. The exception's attribute 'params' is a listref of parameter names that were missing.

Devel::hdb::Client::Exception::Eval is thrown by eval() when the evaluated code throws an exception.

Devel::hdb::Client::Exception::Error is thrown when data returned from the debugger is not formatted as expected.

Devel::hdb::Client::Exception::HTTP is thrown when a response is an unsuccessful response code (4XX, 5XX). The exception's attributes http_code, http_message and http_content store the code, message and content from the response.

SEE ALSO

Devel::hdb, Data::Transform::ExplicitMetadata

AUTHOR

Anthony Brummett <brummett@cpan.org>

COPYRIGHT

Copyright 2018, Anthony Brummett. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.