The Perl Debugger

Sticking in extra print statements is one way to debug your Perl code, but a full-featured debugger can give you more information.
Essential Debugger Commands

The following seven commands are sufficient for basic debugging:

  • s: single-step execute the next line, stepping into subroutines.

  • n: single-step execute the next line, stepping over subroutines.

  • r: nonstop execute until the return from the current subroutine.

  • c <line-number>: nonstop execute until a particular line.

  • l <line-number, range or subroutine>: list source code.

  • x <expression>: evaluate and pretty-print <expression>.

  • q: quit debugger.

To try these out, run the test program with the debugger:

perl -d

You should see debugger startup information:

Default die handler restored.
Loading DB routines from version 1.07
Editor support available.
Enter h or h h for help or
man perldebug for more help:

main::(	my $name = "Pengu";

This is the state before the program starts running. The next-to-last line has useful information about the debugging status: you're in the main package, file line 6, and it displays the line that is about to be run.

The last line is a prompt with the command number (incrementing as you enter more commands) and angle brackets, where the number of angle brackets signifies nested commands. You don't need to worry about those here.

Type s at the prompt and press Enter to single-step one line into the program:

  DB<1> s
main::(	foreach (1..20) {

To repeat the command, press Enter; repeat this as long as you like to be convinced that the program is stepping through its paces. Every time you pass the print statement, it is echoed to the screen, interspaced with the debugging materials.

Now, try the command to step over subroutines (n), and press Enter a few times. You go through the loop and receive your subroutine results right away, without stepping through each command in the subroutine.

Next, try the command to return from the current subroutine (r). But wait—if you do it now, it will run until the program finishes, because you're “returning” from the main program. First, do a couple repetitions of s to step into the subroutine. Then, with an r, you should see something like:

  DB<1> s
main::(	foreach (1..20) {
main::(	  &shout($name);
main::shout(	  my $name = shift;
  DB<1> r
*** Pengu ***
void context return from main::shout
main::(	foreach (1..20) {

Notice the void context return from main::shout line. If we had asked for a return value in the main loop, we would see it displayed here. In Perl, functions and subroutines can return different values based on the context of the caller (scalar, array or void). A nice feature of the Perl debugger is the r command, which tells you what context was requested by the caller. It can find the bug if you ask your subroutine for a scalar, but you mistakenly have the subroutine return an array.

Next, we have the l command. Try it now:

  DB<1> l
8==>    foreach (1..20) {
9:        &shout($name);
10      }
12      sub shout {
13:       my $name = shift;
14:       print "*** $name ***\n";
15      }

Alone, l lists a page of the source code, starting at the next line to be executed, with a text arrow pointing to the next line. You also can list a range by specifying the line numbers, such as l 200-230. Additionally, you can list a subroutine by naming it: l shout.

The c command continues execution until you hit a particular line number, so you can jump ahead to a particular piece of code that is interesting:

  DB<1> c 14
main::shout(  print "*** $name ***\n";

You can execute any Perl expression, including code that changes the running program, by typing it at the prompt. This can include setting variables in the program by hand.

The x command evaluates and pretty-prints any expression, prepending a numbered index on each line of output, dereferencing anything that can be dereferenced and indenting each new level of dereferencing. As an example, below we set an array, @sample, and then display it:

  DB<1> @sample = (1..5)

  DB<2> x @sample
0  1
1  2
2  3
3  4
4  5

Notice that hashes are displayed with keys and values, each one on a line. You can display hashes properly by preceeding the hash with a \, which turns the hash into a hash reference, which is properly dereferenced. This looks like:

  DB<4> %sample = (1 .. 8)

  DB<5> x \%sample
0  HASH(0x83d53bc)
   1 => 2
   3 => 4
   5 => 6
   7 => 8

When you are satisfied with the results, quit the debugging exercise with q.


Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

Upcoming Webinar
8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
11am CDT, April 29th
Moderated by Linux Journal Contributor Mike Diehl

Sign up now

Sponsored by Skybot