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.


One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix