Perl comes with a built-in debugger. Although you could use third-party debuggers such as perltkdb and ActiveState's Komodo, which provide a graphical interface, you already have everything you need if you have Perl. In this article, I show you how to use the Perl debugger to execute arbitrary Perl statements, create and examine variables, and step through and set breakpoints in programs so that you can start using the Perl debugger right away. As you get comfortable with the basics, you can start to explore its other features.
The Perl debugger is started by specifying the -d switch on the command
line. The simplest way to run the debugger is with a command-line script using
the -e option to perl.
The script can be anything that is valid Perl. In this case, I use the single
statement 0
since it is easy to type and will not get in my way
as I explore the debugger. This example script is only half as long as the one
used in the perldebug man page.
perl -d -e 0 |
The debugger starts up and displays some initial information about itself, including its name (perl5db.pl), its version (1.07), and how you can get more information about the debugger.
Default die handler restored. Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `<a href="http://www.perldoc.com/perl5.6/pod/perldebug.html">man perldebug</a>' for more help. main::(-e:1): 0 DB<1> |
The debugger starts at the first executable statement in the script, in this
case 0
, then waits for my instructions. It has not executed anything
yet. I can tell where the debugger is because it displays quite a bit of information
in its prompt. The prompt tells me that the current namespace is main::,
the name of the script is -e (since I invoked
it from the command line), and that the debugger is at line 1, which has the
statement 0
. The debugger is waiting for a command at the DB<1>
prompt, which tells me that I am at the first debugger instruction.
I do not especially care about this simple script since I really want to test some Perl statements without creating a script to go around them. The debugger allows you to enter arbitrary statements. Anything that does not look like an instruction to the debugger is evaled as Perl code.
main::(-e:1): 0 DB<1> @order = ( 1, 'cherry', 3.14 ) DB<2> |
I created an array, @order, and assigned it a list of values. The debugger accepted that statement, evaled it, and prompted me for another instruction. If I enter something that is not a valid Perl statement, the debugger complains and then continues.
DB<2> $y = syntax error at (eval 24)[/System/Library/Perl/perl5db.pl:1513] line 2, at EOF DB<3> |
Now that I have created @order, I want to examine it to check its contents. The debugger has several commands to let me see what is happening in my program. The x command allows me to examine the variable that I specify.
DB<3> x @order 0 1 1 'cherry' 2 3.14 DB<4> |
The debugger pretty prints the array in two columns. The first column is the element index, and the second column is the corresponding value. If I had done this with a hash, the debugger still pretty prints it as a list, but in key-value pairs. Since a hash is unordered, the indices in the first column do not mean much to me.
DB<4> %hash = ( one => 1, two => 2, three => 3 ) DB<5> x %hash 0 'one' 1 1 2 'three' 3 3 4 'two' 5 2 DB<6> |
Even when I create and examine a scalar I see the two column display of the variable when I examine it, although a scalar only ever has one value.
DB<6> $pi = 'apple' DB<7> x $pi 0 'apple' DB<8> |
I can even examine more than one variable at a time, even though the debugger makes me remember in which order I specified them.
DB<8> $n = 3; $m = 4; $o = 6 DB<9> x $n, $m, $o 0 3 1 4 2 6 DB<10> |
I can also use the p command, which does the same thing as the perl
builtin print() function, to print the values in these variables, rather
than dumping the variables as the x command does.
By this time, I think I have forgotten which variables I have defined, but I can use the V command to pretty print all of the variables in a package, defaulting to main::. Try this yourself you may be surprised how many variables are actually defined in main::. I can also limit the variables that V dumps by specifying the package and variables I want to see.
DB<10> V main pi $pi = 'apple' DB<11> |
Notice that I do not need to specify the variable symbol, such as $
,
@
, or %
in front of the variable name. The V
command shows me all values for any variable with that name, including variables
without special symbols.
DB<11> @pi = qw(peach cherry) DB<12> V main pi $pi = 'apple' @pi = ( 0 'peach' 1 'cherry' ) DB<13> |
Try opening a file onto a filehandle named pi and see what V reports.
To make things a bit simpler, I created another variable in a different package by specifying the fully qualified name in the declaration. When I use the V command for that package, I only see the variables in that package.
DB<13> $my_main::foo = 42 DB<14> V my_main $foo = 42 |
The X command does the same thing as the V command, although it defaults to the current package rather than main::.
For extra credit, create a lexical variable using my() and try the V command again. Where is the lexical variable? *
Now the I have shown you some of the basics for using the Perl debugger, let's invoke it on a real (toy) script, which I call test.pl.
1: #!/usr/bin/perl 2: 3: $x = 5; 4: 5: $y = 42; 6: 7: $z = $x + $y; 8: 9: print "z is $z\n"; 10: 11: print "z^2 is " . $z * $z . "\n"; 12: 13: __END__ |
I invoke the debugger as before.
perl -d test.pl |
Again, the debugger stops right before the first executable statement and tells me the current package, the name of the script, the current line number, and current statement. The first thing that I probably want to do is to execute this statement, unless I think there are bugs in the program before I even start running it. I can single step through the program with the s command. The debugger only executes the next statement and then prompts me for additional instructions. I can also examine variables with the x command, or use any other debugger commands.
Default die handler restored. Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(test.pl:3): $x = 5; DB<1> x $x 0 undef DB<2> s main::(test.pl:5): $y = 42; DB<2> x $x 0 5 DB<3> s main::(test.pl:7): $z = $x + $y; DB<3> x $x, $y 0 5 1 42 |
If the next statement includes a subroutine call and I single-step through that statement with the s command, the debugger descends into the subroutine and I can single-step through each subroutine statement. I can skip this descent by using the n command, which executes the subroutine completely and returns control to me at the next program statement after the subroutine call. Simply typing a carriage return at the debugger prompt will repeat the last s or n command.
DB<4> main::(test.pl:9): print "z is $z\n"; DB<4> |
While I step through the program, I can examine the lines that are next or the lines that I just executed. The w command shows a window of lines around the current line and precedes them with their line numbers. It shows lines that are executable statements with a : after the line number, and shows the current line with a ==>.
DB<4> w 6 7: $z = $x + $y; 8 9==> print "z is $z\n"; 10 11: print "z^2 is " . $z * $z . "\n"; 12 13 __END__ |
If I want to examine a different window of lines, I can specify those lines with the l command. This command has many ways to specify which lines to show, but I am just going to specify a range of lines.
DB<4> l 3-7 3: $x = 5; 4 5: $y = 42; 6 7: $z = $x + $y; |
Once I am satisfied that at least some of the statements are executing correctly and as I expect them to, I want to let them execute automatically and stop at the parts of the program that I need to examine more closely. I can set breakpoints at certain lines so that the debugger stops and I can issue debugger commands. There are several ways to set breakpoints, including by line number and by line number if some condition is met (such as a variable having a certain value). All of them are explained in the perldebug man page. Here I am only going to set a breakpoint by line number so I can stop right before the print statement.
When I invoke the debugger, the same thing as before happens. Instead of single-stepping, I use the b command to set a breakpoint at line 9.
Default die handler restored. Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(test.pl:3): $x = 5; DB<1> b 9 DB<2> |
Now that I have set a breakpoint, I use the l command to look at the lines around the breakpoint. Notice that line 9, which has the breakpoint, has a special notation next to its line number to indicate the breakpoint.
DB<2> l 6-12 6 7: $z = $x + $y; 8 9:b print "z is $z\n"; 10 11: print "z^2 is " . $z * $z . "\n"; 12 DB<3> |
To run the program up to the breakpoint without stopping for each statement,
I use the c
command. The program runs up to line 9, then
pauses to prompt me for further commands. At this point, I can do any of the
things that we have seen so far, including executing arbitrary Perl statements
that can influence the state of the program. I can examine and change variable
values if I choose.
DB<3> c main::(test.pl:9): print "z is $z\n"; DB<3> x $z 0 47 DB<4> $z = 5 DB<5> x $z 0 5 DB<6> |
If I no longer need a breakpoint, I can delete it with the d command. When I look at the window again, I no longer see the breakpoint annotation next to line 9. If I want to clear all breakpoints, I use the D command.
DB<6> d 9 DB<7> w 6 7: $z = $x + $y; 8 9==> print "z is $z\n"; 10 11: print "z^2 is " . $z * $z . "\n"; 12 13 __END__ DB<7> |
Besides the commands I have shown in this article, you can do many other things with the debugger, including setting actions for a particular line, changing the behavior of the debugger by setting or changing options, and examining the debugger itself. Now that you know enough to start using the debugger right away, you can explore these other features on your own and start finding those bugs in your own programs.
Happy bug squashing. :)
[*] Obviously the V command dumps everything it finds in the symbol table. These are package variables, which is why you can specify a package with this command. Since lexical variables carry no package information and are not stored in the symbol table, the V command does not know they exist.
brian d foy has been a Perl user since
1994. He is founder of the first Perl users group,
href="http://ny.pm.org/">NY.pm
the Perl advocacy organization. He has been teaching Perl through Stonehenge
Consulting
The Perl Conference, Perl University, YAPC, COMDEX, and Builder.com. Some of
brian's other articles have appeared in The Perl Journal.