Today's lesson describes the Perl debugging facility. You'll
learn the following:
The following sections describe how to start the Perl debugger
and how to exit.
To debug a Perl program, specify the -d option when you
run the program. For example, to debug a program named debugtest,
specify the following command:
$ perl -d debugtest
You can supply other options along with d if you
want to.
When the Perl interpreter sees the d option, it
starts the Perl debugger. The debugger begins by displaying a
message similar to the following one on your screen:
Loading DB routines from $RCSfile: perldb.pl,v $$Revision: 4.0.1.3 $$Date: 92/06/08 13:43:57 $ Emacs support available. Enter h for help. main::(debugtest:3): $dircount = 0; DB<1>
The first few lines display the date on which this version of
the debugger was created. The only lines of interest are the last two.
The second-to-last line in this display lists the line that
the debugger is about to execute. When the debugger starts, the
first executable line of the program is displayed.
When the debugger displays a line that it is about to execute,
it also provides the following information about the line:
The last line of the display prompts you for a debugging
command. The number enclosed in angle brackets indicates the command
number; in this case, the number is 1, because you are
about to specify the first debugging command.
Later today you will learn how to use the debugging command
number to re-enter debugging commands you have previously executed.
Note: To enter the debugger without supplying a program, supply the -e option with the -d option:
$ perl -d -e "1;"
This line starts the debugger with a "program" consisting of the single statement
1;
(which is an expression that doesn't do anything meaningful).
Starting the debugger without a program enables you to examine the predefined system variables or supply statements to be executed. You will learn how to perform both of these tasks later in today's lesson.
To exit the debugger, enter the debugging command q:
DB<1> q
This command halts program execution immediately and returns
you to the command shell.
You can list any part of your program from within the
debugger. The following sections describe debugging commands that perform
the display operations.
The simplest way to list part of your program is with the l
command, which lists the next few statements in your program:
DB<1> l
3: $dircount = 0;
4: $curdir = "";
5: while (1) {
6: # if we don't have a current directory, get one
7: if ($curdir eq "") {
8: print ("Enter directory to list:\n");
9: $curdir = <STDIN>;
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
The l command lists a window of executable statements,
which is a group of statements small enough to be easily
displayed on your screen. A window usually consists of about ten
statements. The line number of each statement is displayed at the beginning
of its line.
Note: The statements displayed in today's lesson are taken from the program presented in "Week 2 in Review."
Entering the l command again displays the window of
statements immediately following the last displayed line, which
in this example is line 12:
DB<1> l 13: } 14: $curdir = &menudir($curdir); 15: } 16: 17: 18: # Find all subdirectories of the given directory, 19: # and store them in an associative array. 20: # 21: # The associative array subscripts and values are: 22: # <directory name>: 1
You can specify the lines displayed by the l command.
If you specify a single line number with the l command, it
displays that line:
DB<1> l 10 10: $curdir =~ s/^\s+|\s+$//g;
To display a range of lines, specify the first and last line
number, and separate them with a hyphen:
DB<1> l 10-15 10: $curdir =~ s/^\s+|\s+$//g; 11: $curdir = &followlink($curdir); 12: &readsubdirs($curdir); 13: } 14: $curdir = &menudir($curdir); 15: }
To display a specified number of lines starting at a certain
point, supply the starting line number, a + character, and
a number of additional lines to display:
DB<1> l 10+5 10: $curdir =~ s/^\s+|\s+$//g; 11: $curdir = &followlink($curdir); 12: &readsubdirs($curdir); 13: } 14: $curdir = &menudir($curdir); 15: }
You also can use the l command to specify a subroutine
to display. To do this, provide the name of the subroutine to
display:
DB<1> l readsubdirs
26: sub readsubdirs {
27: local ($dirname) = @_;
28: local ($dirvar, $subdircount, $name, $index);
29:
30: # open the current directory;
31: # $dircount ensures that each file variable is unique
32: $dirvar = "DIR" . ++$dircount;
33: if (!opendir ($dirvar, $dirname)) {
34: warn ("Can't open $dirname\n");
35: return;
This command lists the statements in the subroutine. If the
subroutine is too large to fit in a single window, only the first
few statements are listed; you can list subsequent statements by
entering l with no arguments.
You can display the lines immediately preceding the last
displayed line by entering the command. For
example, the following command lists the window of
lines immediately preceding the subroutine readsubdirs.
DB<1> - 16: 17: 18: # Find all subdirectories of the given directory, 19: # and store them in an associative array. 20: # 21: # The associative array subscripts and values are: 22: # <directory name>: 1 23: # (indicates that directory has been read) 24: # <directory name>.<num> the <num>th subdirectory 25:
Subsequent commands go back further in the file.
To list a window of lines containing a specified line, use the w
command, and specify the number of the line to be included:
DB<1> w 7
4: $curdir = "";
5: while (1) {
6: # if we don't have a current directory, get one
7: if ($curdir eq "") {
8: print ("Enter directory to list:\n");
9: $curdir = <STDIN>;
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
13: }
The w command displays the three lines before the
specified line and fills the window with the lines following it.
You can search for a line containing a particular pattern by
enclosing the pattern in slashes:
DB<1> /Find/ 18: # Find all subdirectories of the given directory,
The debugger searches forward from the last displayed line for
a line matching the specified pattern. If it finds such a line,
the line is displayed.
To search backward for a particular pattern, enclose the
pattern in question marks:
DB<1> ?readsubdirs? 12: &readsubdirs($curdir);
This command starts with the last displayed line and searches
backward until it finds a line matching the specified pattern.
Note: Patterns specified by // and ?? can contain any special character understood by the Perl interpreter.
You optionally can omit the final / or ? character when you match a pattern.
The S command lists all the subroutines in the current
file, one subroutine per line:
DB<> S main::display main::followlink main::menudir main::readsubdirs
Each subroutine name is preceded by the package name and a
single quotation mark.
One of the most useful features of the Perl debugger is the
capability to execute a program one statement at a time. The following
sections describe the statements that carry out this action.
To execute a single statement of your program, use the s
command:
DB<2> s main::(debugtest:4): $curdir = "";
This command executes one statement of your program and then
displays the next statement to be executed. If the statement executed
needs to read from the standard input file, the debugger waits until
the input is provided before displaying the next line to execute.
Tip: If you have forgotten which line is the next line to execute (because, for example, you have displayed lines using the l command), you can list the next line to execute using the L command:
DB<2> L 3: $dircount = 0;
The L command lists the last lines executed by the program. It also lists any breakpoints and line actions that have been defined for particular lines. Breakpoints and line actions are discussed later today.
If the statement executed by the s command calls a
subroutine, the Perl debugger enters the subroutine but does not
execute any statements in it. Instead, it stops at the first
executable statement in the subroutine and displays it. For
example, if the following is the current line:
main::(debugtest:12): &readsubdirs($curdir);
specifying the s command tells the Perl debugger to
enter readsubdirs and display the following, which is the
first executable line of readsubdirs:
main::readsubdirs(debugtest:27): local ($dirname) = @_;
The s command assumes that you want to debug the
subroutine you have entered. If you know that a particular
subroutine works properly and you don't want to step through it
one statement at a time, use the n command, described in
the following section.
The n command, like the s command, executes one
line of your program and displays the next line to be executed:
DB<2> n
main::(debugtest:5): while (1) {
The n statement, however, does not enter any
subroutines. If the statement executed by n contains a subroutine
call, the subroutine is executed in its entirety. After the
subroutine is executed, the debugger displays the line
immediately following the call.
For example, if the current line is
main::(debugtest:12): &readsubdirs($curdir);
the n command tells the debugger to execute readsubdirs
and then display the next line in the program, which is
main::(debugtest:13:): }
Combining the use of s and n ensures that the
debugger examines only the subroutines you want to see.
Note: The Perl debugger does not enable you to enter any library functions. You can enter only subroutines that you have created yourself or that have been created previously and added to a subroutine library.
The f command tells the Perl debugger to execute the
remainder of the statements in the current subroutine and then
display the line immediately after the subroutine call. This is
useful when you are looking for a bug and have determined that
the current subroutine does not contain the problem.
If you are stepping through a program using s or n,
you can save yourself some typing by just pressing Enter when you
want to execute another statement. When you press Enter, the
debugger repeats the last s or n command executed.
For example, to step from line 5 to line 7, you can use the s
command as usual:
DB<3> s
main::(debugtest:7): if ($curdir eq "") {
(Line 6 is skipped because it contains no executable
statements.) To execute line 7, you can now just press Enter:
DB<2>
main::(debugtest:8): print ("Enter directory to list:\n");
Note: Pressing Enter has no effect if you have not specified any s or n commands.
If you are inside a subroutine and decide that you no longer
need to step through it, you can tell the Perl debugger to finish executing
the subroutine and return to the statement after the subroutine call. To
do this, use the r command:
DB<4> r main::(debugtest:13:): }
The statement displayed by the debugger is the first statement
following the call to the subroutine.
Another powerful feature of the Perl debugger is the
capability to display the value of any variable at any time. The
following sections describe the commands that perform this
action.
The X command displays variables in the current package
(which is main if no other package has been specified). If
the X command is specified by itself, it lists all the
variables in the current package, including the system-defined
variables and the variables used by the Perl interpreter itself. Usually,
you won't want to use the X command by itself, because
there are a lot of system-defined and internal variables known to
the Perl interpreter.
To print the value of a particular variable or variables,
specify the variable name or names with the X command:
DB<5> X dircount $dircount = '0'
This capability often is useful when you are checking for
errors in your program.
Caution: You must not supply the $ character with the variable name when you use the X command. If you supply the $ character (or the @ or % characters for arrays), the debugger displays nothing.
You can use X to display the values of array variables
and associative array variables.
DB<6> X regarray @regarray = ( 0 14 1 'hello' 2 36 ) DB<7> X assocarray %assoc_array = ( 'hi' 1 'there' 2 )
Each command prints the subscripts of the array and their
values. Regular arrays are printed in order of subscript;
associative arrays are printed in no particular order.
Note: If you have an array variable and a scalar variable with the same name, the X command prints both variables:
DB<8> X var $var = '0' @var = ( 0 'test1' 1 'test2' )
There is no way to use X to display one variable but not the other.
The V command is identical to the X command
except that it prints the values of variables in any package. If
you specify just a package name, as in the following, this
command displays the values of all variables in the package
(including system-defined and internal variables):
DB<9> V mypack
If you specify a package name and one or more variable names,
as in the following, the debugger prints the values of the variables
(if they are defined in that package):
DB<10> V main dircount $dircount = '0'
As you have seen, you can tell the Perl debugger to execute
one statement at a time. Another way of controlling program execution
is to tell the debugger to execute up to a certain specified
point in the program, called a breakpoint.
The following sections describe the commands that create
breakpoints, and the command that executes until a breakpoint is detected.
To set a breakpoint in your program, use the b command.
This command tells the debugger to halt program execution whenever
it is about to execute the specified line. For example, the
following command tells the debugger to halt when it is about to
execute line 10:
DB<11> b 10
(If the line is not breakable, the debugger will return Line
10 is not breakable.)
Note: You can have as many breakpoints in your program as you want. The debugger will halt program execution if it is about to execute any of the statements at which a breakpoint has been defined.
The b command also accepts subroutine names:
DB<12> b menudir
This sets a breakpoint at the first executable statement of
the subroutine menudir.
You can use the b command to tell the program to halt
only when a specified condition is true. For example, the
following command tells the debugger to halt if it is about to
execute line 10 and the variable $curdir is equal to the
null string:
DB<12> b 10 ($curdir eq "")
The condition specified with the b statement can be any
legal Perl conditional expression.
Caution: If a statement is longer than a single line, you can set a breakpoint only at the first line of the statement:
71: print ("Test",
72: " here is more output");
Here, you can set a breakpoint at line 71, but not line 72.
After you have set a breakpoint, you can tell the debugger to
execute until it reaches either the breakpoint or the end of the program.
To do this, use the c command:
DB<13> c main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g; DB<14>
When the debugger detects that it is about to execute line 10--the
line at which the breakpoint was set--it halts and displays the
line. (Recall that the debugger always displays the line it is about to
execute.)
The debugger now prompts you for another debugging command.
This action enables you to start executing one statement at a
time using n or s, continue execution using c,
set more breakpoints using b, or perform any other
debugging operation.
You can specify a temporary (one-time-only) breakpoint with
the c command by supplying a line number:
DB<15> c 12 main::(debugtest:12): &readsubdirs($curdir);
The argument 12 supplied with the c command
tells the debugger to define a temporary breakpoint at line 12
and then resume execution. When the debugger reaches line 12, it
halts execution, displays the line, and deletes the breakpoint.
(The line itself still exists, of course.)
Using c to define a temporary breakpoint is useful if
you want to skip a few lines without wasting your time executing
the program one statement at a time. Using c also means
that you don't have to bother defining a breakpoint using b
and deleting it using d (described in the following
section).
Tip: If you intend to define breakpoints using c or b, it is a good idea to ensure that each line of your program contains at most one statement. If you are in the habit of writing lines that contain more than one statement, such as
$x++; $y++;
you won't get as much use out of the debugger, because it can't stop in the middle of a line.
To list all of your breakpoints, use the L command.
This command lists the last few lines executed, the current line,
the breakpoints you have defined, and the conditions under which
the breakpoints go into effect.
DB<16> L
3: $dircount = 0;
4: $curdir = "";
5: while (1) {
7: if ($curdir eq "") {
10: $curdir =~ s/^\s+|\s+$//g;
break if (1)
Here, the program has executed lines 3-7, and a breakpoint is
defined for line 10. (Line 6 is not listed because it is a comment.)
You can distinguish breakpoints from executed lines by looking
for the breakpoint conditional expression, which immediately
follows the breakpoint. Here, the conditional expression is (1),
which indicates that the breakpoint is always in effect.
When you are finished with a breakpoint, you can delete it
using the d command.
DB<16> d 10
This command tells the debugger to delete the breakpoint at
line 10. The line itself remains in the program.
If you do not specify a breakpoint to delete, the debugger
assumes that a breakpoint is defined for the next line to be executed,
and deletes it.
main::(debugtest:12): &readsubdirs($curdir); DB<17> d
Here, line 12 is the next line to be executed, so the debugger
deletes the breakpoint at line 12.
To delete all your breakpoints, use the D command.
DB<18> D
This command deletes all the breakpoints you have defined with
the b command.
When you run a program using the Perl debugger, you can tell
it to display each line as it is executed. When the debugger is doing
this, it is said to be in trace mode.
To turn on trace mode, use the T command.
DB<18> t Trace = on
When a statement is executed in trace mode, the statement is
displayed. For example, if the current line is line 5 and the command c
10 (which executes up to line 10) is entered, the following is displayed:
DB<18> c 10
main::(debugtest:5): while (1) {
main::(debugtest:7): if ($curdir eq "") {
main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g;
DB<19>
The debugger prints and executes line 5 and line 7, then
displays line 10 and waits for further instructions.
To turn off trace mode, specify the t command again.
DB<19> t Trace = off
At this point, trace mode is turned off until another t
command is entered.
The Perl debugger enables you to specify one or more
statements to be executed whenever the program reaches a
specified line. Such statements are known as line actions. The
most common line actions are printing the value of a variable and resetting
a variable containing an erroneous value to the value you want.
The following sections describe the debugging commands that
define line actions.
To specify a line action for a particular line, use the a
command.
DB<19> a 10 print ("curdir is $curdir\n");
This command tells the debugger to execute the statement
print ("curdir is $curdir\n");
whenever it is about to execute line 10 of the program. The
debugger performs the action just after it displays the current
line and before it asks for the next debugging command.
To create a line action containing more than one statement,
just string the statements together. If you need more than one
line for the statements, put a backslash at the end of the first
line.
DB<20> a 10 print ("curdir is $curdir\n"); print \
("this is a long line action\n");
In this case, when the debugger reaches line 10, it executes
the following statements:
print ("curdir is $curdir\n");
print ("this is a long line action\n");
To delete the line actions defined using the a command,
use the A command.
DB<21> A
This command deletes all line actions currently defined.
Note: The A command does not affect the < and > commands, described in the following section.
To define a line action that is to be executed before the
debugger executes any further statements, use the >
command.
DB<21> > print ("curdir before execution is $curdir\n");
This command tells the debugger to print the value of $curdir
before continuing.
Similarly, the < command defines a line action that
is to be performed after the debugger has finished executing
statements and before it asks for another debugging command:
DB<22> < print ("curdir after execution is $curdir\n");
This command tells the debugger to print the value of $curdir
before halting execution again.
The < and > commands are useful when you
know that one of your variables has the wrong value, but you
don't know which statement assigned the wrong value to the
variable. By single-stepping through the program using s
or n, and printing the variable either before or after
executing each statement, you can determine where the variable
was given its incorrect value.
Note: To delete a line action defined by the < command, enter another < command with no line action defined.
DB<23> <
Similarly, the following command undoes the effects of a > command:
DB<24> >
The L command prints any line actions you have defined
using the a command (as well as breakpoints and executed
lines). For example, suppose that you have defined a line action
using the following command:
DB<25> a 10 print ("curdir is $curdir\n");
The L command then displays this line action as shown
here:
main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g;
action: print ("curdir is $curdir\n");
The line action is always displayed immediately after the line
for which it is defined. This method of display enables you to distinguish
lines containing line actions from other lines displayed by the L command.
The following sections describe the debugging commands not
previously covered.
In the debugger, anything that is not a debugging command is
assumed to be a Perl statement and is performed right away. For
example
DB<4> @array = (1, 2, 3);
You can use statements such as this to alter values in your
program as it is being executed. This capability is useful when
you are testing your code.
Note: If you wish, you can omit the semicolon at the end of the statement.
The H (for "history") command lists the
preceding few commands you have entered.
DB<4> H 3: b 7 2: b 14 1: b 13
The commands are listed in reverse order, with the most
recently executed command listed first. Each command is preceded by
its command number, which is used by the ! command
(described in the following section).
Note: The debugger saves only the commands that actually affect the debugging environment. Commands such as l and s, which perform useful work but do not change how the debugger behaves, are not listed by the H command.
This is not a significant limitation because you can enter the letter again if needed.
Each command that is saved by the debugger and can be listed
by the H command has a command number. You can use this command
number to repeat a previously executed command. For example, to
repeat command number 5, make the following entry:
DB <11> !5 b 8 DB <12>
The debugger displays command number 5--in this case, the
command b 8-- and then executes it.
If you omit the number, the debugger repeats the last command
executed.
DB <12> $foo += $bar + 1 DB <13> ! $foo += $bar + 1 DB <14>
If you specify a negative number with !, the debugger
skips back that many commands:
DB <14> $foo += $bar + 1 DB <15> $foo *= 2 DB <16> ! -2 $foo += $bar + 1 DB <17>
Here, the ! -2 command refers to the command $foo +=
$bar + 1.
Caution: You can use ! only to repeat commands that are actually repeatable. Use the H command to list the commands that the debugger has saved and that can be repeated.
The T command enables you to display a stack trace,
which is a collection of all the subroutines that have been
called, listed in reverse order. Here is an example:
DB <16> T
$ = &main::sub2('hi') from file debug1 line 7
$ = &main::sub1('hi') from file debug1 line 3
Here, the T command indicates that the program is
currently inside subroutine sub2, which was called from
line 7 of your program; this subroutine is part of the main
package. The call to sub2 was passed the argument 'hi'.
The $ = preceding the subroutine name indicates that
the subroutine call is expecting a scalar return value. If the
call is expecting a list to be returned, the characters @ =
appear in front of the subroutine name.
The next line of the displayed output tells you that sub2
was called by another subroutine, sub1. This subroutine
was also passed the argument 'hi', and it was called by
line 3 of the program. Because the stack trace lists no more
subroutines, line 3 is part of your main program.
Note: The list of arguments passed to a subroutine that is displayed by the stack trace is the list of actual values after variable substitution and expression evaluation are performed. This procedure enables you to use the stack trace to check whether your subroutines are being passed the values you expect.
An easy way to print the value of an expression from inside
the debugger is to use the p command.
DB <17> p $curdir + 1 1
The p command evaluates the expression and displays the
result.
Note: The p command writes to the screen even when the program has redirected STDOUT to a file.
If you find yourself repeatedly entering a long debugging
command and you want to save yourself some typing, you can define an
alias for the long command by using the = command. For
example:
DB <15> = pc print ("curdir is $curdir\n");
= pc print ("curdir is $curdir\n");
The = command prints the alias you have just defined
and then stores it in the associative array %DB'alias
(package DB, array name alias) for future
reference. From here on, the command
DB <16> pc
is equivalent to the command
DB <16> print ("curdir is $curdir\n");
To list the aliases you have defined so far, enter the =
command by itself:
DB <17> =
pc = print ("curdir is $curdir\n")
This command displays your defined aliases and their
equivalent values.
You can define aliases that are to be created every time you
enter the Perl debugger.
When the debugger starts, it first searches for a file named .perldb
in your home directory. If the debugger finds this file, it executes
the statements contained there.
To create an alias, add it to the .perldb file. For
example, to add the alias
= pc print ("curdir is $curdir\n");
add the following statement to your .perldb file:
$DB'alias{"pc"} = 's/^pc/print ("curdir is $curdir\n");/';
Here's how this works: when the Perl debugger creates an
alias, it adds an element to the $DB'alias associative
array. The subscript for this element is the alias you are
defining, and the value is a substitution command that replaces
the alias with the actual command you want to use. In the preceding
example, the substitution takes any command starting with pc
and replaces it with
print ("curdir is $curdir\n");
Caution: Be careful when you define aliases in this way. For example, your substitution should match only the beginning of a command, as in /^pc/. Otherwise, the alias will replace any occurrence of the letters pc with your print command, which is not what you want.
The h (for help) command provides a list of each of the
debugger commands listed in today's lesson, along with a one-line explanation
of each. This is handy if you are in the middle of debugging a program
and forget the syntax of a particular command.
Today, you have learned about the Perl debugger. This debugger
enables you to perform the following tasks, among others:
DB <11> system ("ls");
DB <12> system ("sh");
The Workshop provides quiz questions to help you solidify your
understanding of the material covered.