Channels ▼
RSS

Using the Perl Debugger


Using the Perl Debugger

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, and Perl Mongers,

the Perl advocacy organization. He has been teaching Perl through Stonehenge

Consulting for the past three years, and has been a featured speaker at

The Perl Conference, Perl University, YAPC, COMDEX, and Builder.com. Some of

brian's other articles have appeared in The Perl Journal.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video