The Perl Debugger

The Perl debugger, a part of the core Perl distribution, is a useful tool to master, allowing close interactive examination of executing Perl code.
Commands (also see the man page)

This tutorial covers the debugger commands that I've found the most useful. The perldebug man page has a complete list of commands.

The most important command that can be entered into the debugger is h, which prints out a help screen. This tends to scroll off the screen, so type h h to see the help screen better formatted to fit your screen. Or, you can type |h, which will pipe the output of the command h into a pager, such as more or less. You can define what pager to use by setting the PAGER environmental variable to whatever pager you prefer. I prefer using less. (You can actually do this from within the debugger by typing:

$ENV{'PAGER'} = "/usr/bin/less"

at the debugger prompt.) This piping mechanism works with more than just the help command, so if you ever do something and the result moves off your screen, try prepending it with a pipe. You can get help with individual commands by typing h command.

Simple Example

Now let's look at actual examples of using the debugger. We'll start with the simple snippet of Perl code in Listing 1, called Notice that we are executing the code with the -d option to perl, invoking the debugger. Upon invoking the script under the debugger, we'll see the following:

Loading DB routines from version 1
Emacs support available.
Enter h or h h for help.
main::(./ if(0) {

The debugger has suspended the normal execution of, and is waiting for a command. Notice that we are given some information concerning where we are in the text of the program. The string main::(./ tells us that we are in the main part of the Perl code, that the program we are executing is ./ and that we are at line three of the code. If we were in the middle of another Perl package, that package name would be listed here. We are also shown that line three is if(0) {. When we see code on a line, we have not yet executed it; rather it is this line in the code that is about to be executed. The next line, DB<1>, is a prompt at which to enter the first command to the debugger. If you enter a command and wish to repeat it, you can enter ! comnum, where comnum is the command number you wish to repeat.

Listing Code

We can see more of the surrounding script by typing l and pressing enter. Be careful not to put white space before this or any other commands. Doing so tells the debugger that what follows is not a command. Instead, the debugger will try to execute the code as normal Perl code and will evaluate it in the current context of the program being debugged. The debugger will do the same thing for any input it doesn't recognize as a debugger command. Using the character ; (semicolon) to end the command is optional.

Entering l (letter l for list) causes the following lines to appear on the screen:

3==> if(0) {
4: print "Can't get here!\n";
5 }
7: while ($i < 10) {
8: $i++;
9 }
11: if($i >= 9) {
12: print "Hello, world!\n";

Notice the arrow, ==>. This represents the current line of code. In this case, it is line 3 and is the first actual line of Perl code. Notice also that all the lines which actually have executable code on them are labeled with a : (colon) after the line number. This is important, because later on when we get into breakpoints and action points, we will only be able to set them at these lines.

Entering l again yields this output:

13 }
15: exit 0;

The l without any arguments reveals the next window of Perl code. Subsequent usage reveals the next window and the next. There is an internal line pointer that gets incremented one window each time l is used. To back up a window, type - (hyphen) and press enter, then press l again.

There are also arguments to the l command, dealing with various ways of specifying what lines are printed based on their line numbers. We will use some of them as we need them. Similar to l is w, which prints out windows of program text. See the perldebug man page for details.