The debugger as a perl shell

Starting a Session (perl -d)

For an example of its simplest usage, start the debugger by giving it something innocuous (like a 0 (zero)) as the evaluation argument to the debugger via the command line:

opx-p1200794This way of invoking the debugger works just as well on Microsoft Windows and Mac OS X as it does on the many flavors of Un*x.

A simple expression (perl -d -e 0)
The “-e” supplies a complete program on the command line for Perl to run –
for more info on this see perlrun

perldb@monkey> B<perl -d -e 0>
Default die handler restored.

Loading DB routines from perl5db.pl version 1.19
Editor support available.

Enter h or `h h’ for help, or `man perldebug’ for more help.

main::(-e:1): 0
DB<1>

Perl stops at the first executable statement. In this example, this is 0,
a perfectly valid (though minimal) Perl expression.

If you continue now, you’ll just fall off the end of the program.

Although this example may not immediately appear to be very useful, at this point you can in fact interact completely with the debugger. You can look at any environment variables (“V”) and you can also check out the help (“h”) page/s, and explore your surroundings.

To get the help page simply type “h” at the command prompt:

C<>
DB<1> B<h>
List/search source lines: Control script execution:
l [ln|sub] List source code         T Stack trace
– or . List previous/current line  s [expr] Single step [in expr]
w [line] List around line            n [expr] Next, steps over subs
f filename View source in file    <CR/Enter> Repeat last n or s
/pattern/ ?patt? Search forw/backw r Return from subroutine
v Show versions of modules     c [ln|sub] Continue until position
Debugger controls: L List break/watch/actions
O […] Set debugger options     t [expr] Toggle trace [trace expr]
<[<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint
! [N|pat] Redo a previous command d [ln] or D Delete a/all breakpoints
H [-num] Display last num commands a [ln] cmd Do cmd before line
= [a val] Define/list an alias      W expr Add a watch expression
h [db_cmd] Get help on command A or W Delete all actions/watch
|[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess
q or ^D Quit                           R Attempt a restart
Data Examination: expr Execute perl code, also see: s,n,t expr
x|m expr Evals expr in list context, dumps the result or lists methods.
p expr Print expression (uses script’s current package).
S [[!]pat] List subroutine names [not] matching pattern
V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern.
X [Vars] Same as “V current_package [Vars]”.
For more help, type h cmd_letter, or run man perldebug for all docs.
DB<2>

A perl shell

You can run any Perl code you like in this environment, you can think of it as a form of Perl Shell.

Perhaps you can’t remember whether the results of a regular expression are given in scalar or array context. Instead of looking it up in perlre, you might choose to just try it out.

We’ll use “p”, which is just Perl’s print command in disguise, to see what is happening, first create a string $str.

C<>
DB<2> B<$str = ‘some string’>
DB<3>

Now print $str.

See “p” in examining-data.

C<>
DB<3> B<p $str>
some string
DB<4>

Now use $res to capture the return value of a regex and print the result.

C<>
DB<4> B<$res = $str =~ /(\w+)\s+(\w+)/>
DB<5> B<p $res>
1
DB<6>

Now use @res to capture and print that.

C<>
DB<7> B<@res = $str =~ /(\w+)\s+(\w+)/>
DB<8> B<p @res>
somestring
DB<9>

Use “x” to dump the results to get a clearer picture.

C<>
DB<9> B<x \@res>
0 ARRAY(0x844df5c)
0 ‘some’
1 ‘string’
DB<10>

Extract from the Perl Debugger Pocket Reference book.

Perl debugger pocket reference

The Perl Debugger Pocket Reference provides complete coverage in a conveniently small package.Maybe you write code so clean you never have to look at it twice. opx-p1200794Or perhaps you’d rather focus your energies on writing clean code, rather than learning about the debugger.

But if you need to learn about the Perl debugger in a hurry, the Perl Debugger Pocket Reference is the book you’ll want to have close by. And you can always keep a copy on hand to share with programmers who need it more than you do.

Perl debugger pocket reference

O’Reilly’s Pocket References have become a favorite among programmers everywhere. By providing a wealth of important details in a concise, well-organized format, these handy books deliver just what you need to complete the task at hand. When you’ve reached a sticking point in your work and need to get to a solution quickly, the new Perl Debugger Pocket Reference will get you back on the right track.

From the reviews on Amazon:

“Perl Debugger Pocket Reference” is a relativly short introduction into the command line Perl Debugger (perl -d option). You will find the following main chapters in this book:
– Introductory chapters (partly meta chapters not about the debugger but about good programming)
– Debugger Commands
– Debugger Variables
– Debugging Options
– Debugger Internals, Quick reference, rest
When I bought this book I had hoped for a “…Pocket Guide” and not a “…Pocket Reference” (deeper coverage). I consider this not an extreme “…Pocket Reference” (like e.g. “Perl Pocket Reference”) because this book contains examples for each of the commands and options that it describes. For me examples are the most important part in technical books.
The language, the printing and the index (there is an alphabetic index) are of the usual high O’Reilly standard).

Try it for yourself.

Request Tracker

RT Essentials, co-written by one of the RT’s original core developers, Jesse Vincent, starts off with a quick background opx-p1200796lesson about ticketing systems and then shows you how to install and configure RT.

This comprehensive guide explains how to perform day-to-day tasks to turn your RT server into a highly useful tracking tool. One way it does this is by examining how a company could use RT to manage its internal processes.

Advanced chapters focus on developing add-on tools and utilities using Perl and Mason. There’s also chapter filled with suggested uses for RT inside your organization.

From the reviews on Amazon:

When I first started learning about RT and how to apply the utility to our business, I needed a book that was simple and easy to understand. This taught me all the fundamentals and the examples were easy to follow.

and

Request Tracker (RT) is a great product. I am the only sysadmin at a small company, and having an automated tracking system is going to be an immense benefit for me. I bought “RT Essentials” to help me get up to speed on RT3 really quickly. And, since it was written by the programmer who’s responsible for RT, the book had lots of detail and tips.

Check it out for yourself.

Listing perl code

Using the perl debugger to produce a code listing.

l usage
l [min+incr|min-max|line|subname|$var]

List code within the currently loaded file, in “windowSize” chunks. Note
you can always get back to the current code position with the “.” command
(below).

See options for more information about “windowSize”

opx-p1200794Sometimes the default “windowSize” view of your code just is not
sufficient, and knowing how to modify the view can make the difference
between an easy trouble-shooting session and a hard one.

l
List code from current viewing position

perldb@monkey> B<perl -d linecounter.pl>
<…truncated output…>
main::(linecounter.pl:8): my @args = @ARGV;
DB<1> B<l>
8==> my @args = @ARGV;
9
10 # help requested?
11: my $help = grep(/^-h(elp)*$/i, @args);
12: if ($help) {
13: logg(help());
14: exit 0;
15 }
16
17 # get the pattern to match against.
DB<1>

Now do it again to continue the listing:

C<>
DB<1> B<l>
18: my $REGEX = shift @args || ”;
19
20 # get the files for processing.

21: my @files = grep(!/^-h(elp)*$/i, @args);

22: unless (@files) {

23: push(@files, $0);
24: logg(“using default $0 while no files given”);
25 }
26
27 # loop through the files
DB<1>

l line
List the single line of code at line 11.

C<>
DB<1> B<l 11>
11: my $help = grep(/^-h(elp)*$/i, @args);
DB<2>

l min+incr
List the range of code from line number min and the following incr lines.

C<>
DB<2> B<l 11+3>
11: my $help = grep(/^-h(elp)*$/i, @args);
12: if ($help) {
13: logg(help());
14: exit 0;
DB<3>

l min-max
List the range of code from line number min up to and including line
number max.

C<>
DB<3> B<l 11-14>
11: my $help = grep(/^-h(elp)*$/i, @args);
12: if ($help) {
13: logg(help());
14: exit 0;
DB<4>

l subname
List “windowSize” lines of code of the given subroutine.

C<>
DB<4> B<l report>
56 sub report {
57: my $FH = shift;
58: my $regex = shift;
59: my %report = ();
60: my $i_cnt = 0;
61: while (<$FH>) {
62: $i_cnt++;
63: my $i_match = 0;
64: my $line = $_;
65: if ($line =~ /($regex)/) {
DB<5>

The subroutine may be in any file loaded in %INC.

C<>
DB<5> B<l Carp::croak>
Switching to file ‘/usr/lib/perl5/5.8.0/Carp.pm’.
191: sub croak { die shortmess @_ }
DB<6>

 

Extract from the Perl Debugger Pocket Reference book.

Pro Perl Debugging

Pro Perl Debugging steps in to help resolve the dilemma of application testing and debugging—one of the biggest time commitments in a programmers daily routine.

opx-p1200807What this book will do is rescue you from substandard application testing practices.

The book commences with several chapters that overview the debuggers basic features, then covers common debugging scenarios. The concluding portion examines debugger customization, alternative debugging utilities, and debugging best practices.

From the reviews on Amazon:

I’ve had this book for several weeks and foolishly ignored it. Part of that was because I was busy with a lot of other stuff, but a large part was that I didn’t have much interest: what do I need a perl debugger for? What’s wrong with “print”‘s?

Boy was I wrong. By the second chapter I was kicking myself for being so stupid. Perl’s debugger is a thing of joy – it almost makes me look forward to my next confused Perl program.. well, I’d still rather not have any problem at all, but reading this book gives me a powerful tool to help me figure out where I went wrong.

Try it out for yourself.

The Dump-Value Command: C

The Dump-Value Command: C for the perl debugger.

To dump the entire expression thoroughly, use the x command, which will dump
the given value completely:

DB<13> x @x
0 ‘first’
1 ‘second’
2 ‘third’
3 ‘fourth’
4 ‘fifth’
DB<14>

That’s better, but it’s still a bit clunky, x is better used by giving
it a reference to the variable, this will then be dumped out with proper
indentation offering much more clarity:

DB<14> x \@x
0 ARRAY(0x83560d0)
0 ‘first’
1 ‘second’
2 ‘third’
3 ‘fourth’
4 ‘fifth’
DB<15>

Of course, the same thing can be done with multi-level data structures or
objects, when you can really get to see what an otherwise complex variable
consists of, which is where the indentation really becomes useful.

First we need to create our variable:

DB<15> %x = (\
cont: ‘this’ => ‘that’,\
cont: ‘chars’=> { ‘vowels’ => qw(a e i o u), ‘others’ => qw(s q w r k) },\
cont: ‘obj’ => bless({‘_member’ => ‘variable’, ‘_context’ => ‘init’}, ‘Class’),\
cont: )
DB<16>

We’ll include a self-referential reference too:

DB<16> $x{‘self ref’} = \%x
DB<17>

Now when we dump this out, everything becomes much more obvious. Note in
particular the reused memory reference indicated by the hexadecimal
number: 0x83ca658.

DB<17> x \%x
0 HASH(0x83a50f0)
‘chars’ => HASH(0x83ca658)
‘e’ => ‘i’
‘o’ => ‘u’
‘others’ => ‘s’
‘q’ => ‘w’
‘r’ => ‘k’
‘vowels’ => ‘a’
‘obj’ => Class=HASH(0x83ca838)
‘_context’ => ‘init’
‘_member’ => ‘variable’
‘self ref’ => HASH(0x83a50f0)
-> REUSED_ADDRESS
‘this’ => ‘that’
DB<18>

Although this variable dump looks a lot like that produced by Data::Dumper,
in fact this is produced by a core library called dumpvar.pl.

You can read more in the Pro-Perl-Debugging book.