Chapter 4. Debugging Perl

The standard Perl distribution comes with a debugger, although it's really simply another Perl program, perl5db.pl. Since it is just a program, I tin can use it equally the basis for writing my own debuggers to conform my needs, or I can use the interface perl5db.pl provides to configure its actions. That'southward but the beginning, though. I can write my own debugger or use one of the many debuggers created by other Perl masters.

Earlier Y'all Waste matter Too Much Fourth dimension

Earlier I get started, I'm most required to remind you lot that Perl offers two huge debugging aids: strict and warnings. I have the most trouble with smaller programs for which I don't think I need strict and then I make the stupid mistakes it would have caught. I spend much more than time than I should have tracking down something Perl would have shown me instantly. Mutual mistakes seem to exist the hardest for me to debug. Acquire from the master: don't disbelieve strict or warnings for even modest programs.

Now that I've said that, you're going to expect for it in the examples in this affiliate. Merely pretend those lines are at that place, and the book costs a bit less for the actress half a page that I saved by omitting those lines. Or if you don't similar that, merely imagine that I'm running every program with both strict and warnings turned on from the command line:

$ perl -Mstrict -Mwarnings programme

Forth with that, I accept another problem that bites me much more I should be willing to admit. Am I editing the file on the same machine I'g running it on? I take login accounts on several machines, and my favorite concluding program has tabs and then I can accept many sessions in 1 window. It's like shooting fish in a barrel to checkout source from a repository and work simply nearly anywhere. All of these nifty features conspire to go me into a situation where I'm editing a file in 1 window and trying to run it in another, thinking I'm on the aforementioned automobile. If I'm making changes but nothing is changing in the output or behavior, information technology takes me longer than you'd remember to effigy out that the file I'm running is not the same one I'thou editing. It'southward stupid, but information technology happens. Discount goose egg while debugging!

That's a fleck of a funny story, merely I included it to illustrate a point: when information technology comes to debugging, Humility is ane of the principal virtues of a maintenance programmer.[eleven]My best bet in debugging is to think that I'one thousand the problem. That manner, I don't dominion out anything or attempt to blame the problem on something else, similar I frequently run into in various Perl forums under titles such as "Possible bug in Perl." When I suspect myself offset, I'yard usually right. Appendix B is my guide to solving any problem, which people have found useful for at least figuring out what might be wrong fifty-fifty if they can't ready it.

The Best Debugger in the World

No affair how many different debugger applications or integrated evolution environments I utilise, I still notice that apparently ol' print is my all-time debugger. I could load source into a debugger, prepare some inputs and breakpoints, and watch what happens, but often I can insert a couple of print statements and only run the program unremarkably.[12]I put braces around the variable so I can see any leading or trailing whitespace:

print "The value of var before is [$var]\northward";  #... operations affecting $var;  print "The value of var after is [$var]\n";            

I don't really have to utilise print because I tin can practice the same matter with warn, which sends its output to standard error:

warn "The value of var before is [$var]";  #... operations affecting $var;  warn "The value of var after is [$var]";

Since I've left off the newline at the stop of my warn message, information technology gives me the filename and line number of the warn:

The value of var before is [$var] at program.pl line 123.

If I accept a complex data structure, I employ Data::Dumper to show it. It handles hash and array references just fine, so I use a unlike graphic symbol, the angle brackets in this case, to starting time the output that comes from Data::Dumper:

apply Data::Dumper qw(Dumper); warn "The value of the hash is <\n" . Dumper( \%hash ) . "\due north>\n";

Those warn statements showed the line number of the warn statement. That'south not very useful; I already know where the warn is since I put information technology there! I really want to know where I called that chip of code when information technology became a problem. Consider a divide subroutine that returns the caliber of ii numbers. For some reason, something in the code calls it in such a way that information technology tries to divide by nix:[thirteen]

sub separate         {         my( $numerator, $denominator ) = @_;          return $numerator / $denominator;         }

I know exactly where in the code it blows up considering Perl tells me:

Illegal segmentation past zero at plan.pl line 123.

I might put some debugging code in my subroutine. With warn, I can inspect the arguments:

sub dissever         {         my( $numerator, $denominator ) = @_;         warn "Due north: [$numerator] D: [$denominator]";          return $numerator / $denominator;         }

I might divide in many, many places in the code, so what I really demand to know is which call is the problem. That warn doesn't do anything more useful than show me the arguments.

Although I've called print the best debugger in the world, I actually use a disguised form in the carp function from the Carp module, part of the standard Perl distribution. Information technology'southward like warn, but it reports the filename and line number from the fleck of code that called the subroutine:

#!/usr/bin/perl use Bother qw(bother);  printf "%.2f\n", carve up( 3, 4 ); printf "%.2f\northward", divide( one, 0 ); printf "%.2f\n", carve up( 5, 4 );  sub divide         {         my( $numerator, $denominator ) = @_;         carp "N: [$numerator] D: [$denominator]";          return $numerator / $denominator;         }

The output changes to something much more useful. Not only practise I get my mistake message, merely carp adds some information well-nigh the line of code that chosen it, and it shows me the argument listing for the subroutine. I see that the call from line 4 is fine, but the call on line 5 is the terminal one before Perl kills the program:

$ perl show-args.pl N: [3] D: [four] at show-args.pl line eleven                 principal::divide(3, iv) chosen at show-args.pl line four 0.75 Northward: [1] D: [0] at show-args.pl line eleven                 main::divide(ane, 0) chosen at show-args.pl line 5 Illegal division by zero at show-args.pl line 13.

The carp function is the better-informed version of warn. If I want to do the same affair with die, I use the croak role. It gives the same message as bother, merely just like die, croak stops the plan.

Doing Whatever I Want

I tin can change the warn and die functions myself past messing with %SIG. I similar to use these to peer into code I'm trying to figure out, only I don't employ these to add features to code. It's but part of my debugging toolbox.

The pseudokeys __WARN__ and __DIE__ agree the functions that perform those actions when I utilise the warn or dice functions. I can use a reference to a named subroutine or an anonymous subroutine:

$SIG{__DIE__} = \&my_die_handler; $SIG{__DIE__} = sub { print "I'm nearly to dice!" )

Without going through the unabridged code base of operations, I tin change all of the die calls into the more informative croak calls.[14]In this case, I preface the subroutine call with an & and no parentheses to trigger Perl's feature to laissez passer on the current statement listing to the adjacent subroutine telephone call then croak gets all of the arguments I laissez passer:

use Carp; $SIG{__DIE__} = sub { &Carp::croak };  dice "I'g going at present!";  # really calls croak now              

If I only desire to do this for part of the code, I can employ local (since %SIG is a special variable always in main::). My redefinition stays in consequence until the stop of the scope:

local $SIG{__DIE__} = sub { &Carp::croak };

After either of my customized routines runs, the functions do what they would otherwise do; warn lets the program continue, and die continues its exception processing and eventually stops the program.[fifteen]

Since croak reports each level of the call stack and I chosen information technology from an anonymous subroutine, I get an artifact in my output:

use Carp;  print "Starting program...\northward";  $SIG{__DIE__} = sub {         local $Carp::CarpLevel = 0;          &Carp::croak;         };   foo(); # program dies hither  sub foo { bar() }  sub bar { die "Dying from bar!\n"; }

In the stack trace, I come across a subroutine telephone call from __ANON__ followed by the subroutine calls I expect to bar() and foo():

Starting program... Dying from bar!  at die.pl line 12                 chief::__ANON__('Dying from bar!\ten{a}') chosen at dice.pl line 20                 primary::bar() called at dice.pl line eighteen                 main::foo() chosen at die.pl line 16              

I change my anonymous subroutine to adjust the position in the stack where croak starts its report. I prepare the value of $Carp::CarpLevel to the number of levels I desire to skip, in this case just 1:

$SIG{__DIE__} = sub {         local $Carp::CarpLevel = i;          &Carp::croak;         };

At present I don't run into the unwanted output:

Starting program... Dying from bar!  at die.pl line 12                 main::bar() chosen at die.pl line xviii                 chief::foo() called at die.pl line 16              

For a existent-life case of this in action, check out the CGI::Carp module. Lincoln Stein uses the %SIG tricks to redefine warn and die in a web-friendly style. Instead of an annoying "Server Error 500" message, I can get useful mistake output by simply loading the module. While loading, CGI::Bother sets $SIG{__WARN__} and $SIG{__DIE__}:

use CGI::Bother qw(fatalsToBrowser);

The fatalsToBrowser office takes over the resulting folio to show me the error, but the module has other interesting functions such as set_message, which can catch compile-time errors and warningsToBrowser, which makes the warnings in HTML comments embedded in the output.

Of grade, I don't recommend that you use this in production code. I don't want users to see the plan's errors. They can be handy when I accept to debug a program on a remote server, but once I figure out the problem, I don't need it anymore. By leaving it in at that place I let the public figure out how I'one thousand doing things, and that'southward bad for security.

Program Tracing

The Bother module too provides the cluck and confess subroutines to dump stack traces. cluck is akin to warn (or bother) in that it prints its bulletin simply lets the plan continue. confess does the same thing, but like die, stops the program once it prints its mess.[16]

Both cluck and confess impress stack traces, which bear witness the list of subroutine calls and their arguments. Each subroutine call puts a frame with all of its information onto the stack. When the subroutine finishes, Perl removes the frame for that subroutine, and then Perl looks on the stack for the next frame to process. Alternately, if a subroutine calls another subroutine, that puts some other frame on the stack.

Here'south a short program that has a chain of subroutine calls. I telephone call the do_it function, which calls multiply_and_divide, which in turn calls the divide. At present, in this situation, I'm not getting the right answer for dividing iv by five. In this short example, you can probably spot the error right away, only imagine this is a huge mess of arguments, subroutine calls, and other madness:

#!/usr/bin/perl use warnings; use Bother qw(cluck);  print bring together " ", do_it( iv, 5 ), "\due north";  sub do_it         {         my( $northward, $m ) = @_;          my $sum = $northward + $thousand;         my( $production, $quotient ) =                 multiply_and_divide( [ $due north, $m ], 6, { cat => 'buster' } );          return ( $sum, $product, $quotient );         }  sub multiply_and_divide         {         my( $n, $m ) = @{$_[0]};          my $product = $n * $m;         my $quotient = divide( $n, $n );          render ( $product, $quotient );         }  sub divide         {         my( $northward, $grand ) = @_;         my $quotient = $n / $chiliad;         }

I suspect that something is not right in the divide subroutine, just I also know that it's at the end of a chain of subroutine calls. I desire to examine the path that got me to dissever, so I want a stack trace. I modify carve up to apply cluck, the warn version of Bother'southward stack tracing, and I put a line of hyphens before and after the cluck() to fix apart its output to go far easier to read:

sub split         {         print "-" x 73, "\n";         cluck();         print "-" x 73, "\north";          my( $n, $yard ) = @_;          my $quotient = $n / $yard;          }

The output shows me the list of subroutine calls, with the most contempo subroutine call start (so, the listing shows the stack order). The stack trace shows me the parcel name, subroutine name, and the arguments. Looking at the arguments to carve up, I see a repeated four. 1 of those arguments should be v. It's non separate'southward fault after all:

-------------------------------------------------------------------------  at confess.pl line 68 -------------------------------------------------------------------------                 primary::divide(4, 4) called at confess.pl line lx                 main::multiply_and_divide('ARRAY(0x180064c)') called at confess.pl line 49                 main::do_it(4, five) called at confess.pl line 41 9 twenty 1

It'due south not a trouble with divide, simply with the information I sent to it. That'southward from multiply_and_divide, and looking at its call to divide I run across that I passed the aforementioned argument twice. If I'd been wearing my glasses, I might have been able to notice that $north might look like $thou, but actually isn't:

my $quotient = dissever( $n, $northward );  # Wrong  my $quotient = divide( $n, $m );  # SHOULD Be LIKE THIS

This was a unproblematic example, and still Carp had some bug with it. In the statement list for multiply_and_divide, I just become 'Array(0x180064c)'. That's non very helpful. Luckily for me, I know how to customize modules (Chapters ix and 10), and by looking at Carp, I find that the argument formatter is in Carp::Heavy. The relevant role of the subroutine has a co-operative for dealing with references:

bundle Carp; # This is in Carp/Heavy.pm  sub format_arg {   my $arg = shift;          ...    elsif (ref($arg)) {           $arg = defined($overload::VERSION) ? overload::StrVal($arg) : "$arg";   }         ...    render $arg; }

If format_arg sees a reference, it checks for the overload module, which lets me define my own deportment for Perl operations, including stringification. If Carp sees that I've somehow loaded overload, it tries to use the overload::StrVal subroutine to plough the reference into something I can read. If I haven't loaded overload, it just interpolates the reference in double quotes, yielding something similar the Array(0x180064c) I saw earlier.

The format_arg function is a bit simple-minded, though. I might have used the overload module in i package, but that doesn't hateful I used information technology in another. Simply checking that I've used it in one case somewhere in the programme doesn't mean it applies to every reference. Additionally, I might not have fifty-fifty used it to stringify references. Lastly, I tin can't really retroactively use overload for all the objects and references in a long stack trace, especially when I didn't create most of those modules. I need a better way.

I can override Carp's format_arg to practise what I demand. I re-create the existing code into a BEGIN cake so I can curve it to my will. First, I load its original source file, Carp::Heavy, then I get the original definition loaded showtime. I replace the subroutine definition by assigning to its typeglob. If the subroutine argument is a reference, I pull in Information::Dumper, set some Dumper parameters to fiddle with the output format, then become its stringified version of the argument:

Brainstorm { apply Carp::Heavy;  no warnings 'redefine'; *Bother::format_arg = sub {         package Bother;         my $arg = shift;          if( non defined $arg )                 { $arg = 'undef' }         elsif( ref $arg )                 {                 use Data::Dumper;                 local $Data::Dumper::Indent = 0; # salt to sense of taste                 local $Information::Dumper::Terse  = 0;                 $arg = Dumper( $arg );                 $arg =~ southward/^\$VAR\d+\s*=\south*//;                 $arg =~ south/;\southward*$//;                 }         else                 {                 $arg =~ s/'/\\'/g;                 $arg = str_len_trim($arg, $MaxArgLen);                 $arg = "'$arg'" unless $arg =~ /^-?[\d.]+\z/;                 }          $arg =~ s/([[:cntrl:]]|[[:^ascii:]])/sprintf("\\10{%x}",ord($1))/eg;         render $arg;         }; }

I practise a little flake of actress piece of work on the Dumper output. It normally gives me something I tin can utilise in eval, so it'due south a Perl expression with an assignment to a scalar and a trailing semicolon. I use a couple of substitutions to get rid of these extras. I want to get rid of the Data::Dumper artifacts on the ends:

$VAR = ... ; # exit just the ...

At present, when I run the same programme I had earlier, I get better output. I tin can meet in elements of the anonymous array that I passed to multiply_and_divide:

-------------------------------------------------------------------------  at confess.pl line 65                 main::carve up(iv, 4) called at confess.pl line 57                 main::multiply_and_divide([4,5]) chosen at confess.pl line 46                 main::do_it(4, v) chosen at confess.pl line 38 nine 20 1              

The all-time part of all of this, of course, is that I simply had to add together cluck in i subroutine to go all of this information. I've used this for very complex situations with lots of arguments and complex data structures, giving me a Perl-style stack dump. Information technology may be tricky to go through, but information technology's almost painless to get (and to disable, also).

Safely Changing Modules

In the previous section I changed &Carp::format_arg to do something different. The general idea is very useful for debugging since I'm non merely going to find bugs in the code that I write, only most often in the modules I apply or in code that someone else wrote.

When I need to debug these things in other files, I want to add some debugging statements or change the lawmaking somehow to encounter what happens. All the same, I don't desire to modify the original source files; whenever I exercise that I tend to make things worse no thing how careful I am to restore them to their original state. Whatsoever I exercise, I want to erase any harm I do and I don't want it to affect anyone else.

I do something uncomplicated: copy the questionable module file to a new location. I set up a special directory for the debugging section just to ensure that my mangled versions of the modules won't infect annihilation else. Once I do that, I prepare the PERL5LIB environment variable and then Perl finds my mangled version get-go. When I'k done debugging, I tin clear PERL5LIB to use the original versions once again.

For instance, I recently needed to check the inner workings of Net::SMTP because I didn't recall it was handling the socket code correctly. I choose a directory to concord my copies, in this example ~/my_debug_lib, and set PERL5LIB to that path. I then create the directories I need to shop the modified versions, then re-create the module into information technology:

$ export PERL5LIB=~/my_debug_lib $ mkdir -p ~/my_debug_lib/Net/ $ cp `perldoc -l Net::SMTP` ~/my_debug_lib/Net/.

Now, I can edit ~/my_debug_lib/Net/SMTP.pm, run my code to meet what happens, and piece of work toward a solution. None of this has affected anyone else. I can practise all the things I've already showed in this affiliate, including inserting confess statements at the right places to get a quick dump of the call stack. Every fourth dimension I wanted to investigate a new module, I copied it into my temporary debugging library directory.

Wrapping Subroutines

I don't have to re-create a module file to change its behavior. I can override parts of it directly in my code. Damian Conway wrote a wonderful module chosen Claw::LexWrap to wrap a subroutine around another subroutine. That means that my wrapper subroutine can encounter the arguments coming in and the render values going out. I tin inspect the values, or even change them if I similar.

I'll start with my simple example plan that adds a couple of numbers. Equally before, it has some problems because I'm passing it the wrong arguments since I can't tell the deviation between $n and $grand, and have used $northward twice in my call to add. Just running the program gives me the incorrect answer, but I don't know where the problem is:

#!/usr/bin/perl  # @ARGV = qw( 5 six );  my $n = shift @ARGV; my $m = $ARGV[0];  print "The sum of $n and $m is " . add( $due north, $northward ) . "\n";  sub add         {         my( $n, $m ) = @_;          my $sum = $north + $yard;          return $sum;         }              

I don't want to modify anything in the code, or, I should say, I desire to look at what's happening without affecting the statements that are already in that location. Equally before, I want everything dorsum to normal when I'm finished debugging. Non editing the subroutine makes that easier.

The Claw::LexWrap gives me a chance to do something correct after I make a subroutine call and right before the subroutine returns. Every bit the name suggests, it wraps the subroutine with another i to provide the magic. The Hook::LexWrap::wrap function takes the name of the subroutine it volition wrap, add in this instance, and so anonymous subroutines as pre- and posthandlers:

#!/usr/bin/perl  use Hook::LexWrap qw(wrap);  my $n = shift @ARGV; my $one thousand = $ARGV[0];  wrap add,         pre  => sub { print "I got the arguments: [@_]\due north" },         mail service => sub { print "The return value is going to be $_[-1]\n" }         ;  # this line has the error impress "The sum of $northward and $m is " . add( $n, $n ) . "\n";  sub add         {         my( $northward, $m ) = @_;          my $sum = $n + $m;          render $sum;         }              

The prehandler sees the aforementioned statement list as my call to add. In this instance I just output the list so I can see what it is. The posthandler gets the same arguments, but Hook::LexWrap adds some other element, the render value, on the end of @_. In the posthandler, $_[-1] is always the return value. My program now outputs some useful debugging output, and I meet that I'm passing the aforementioned argument twice:

$ perl add_numbers.pl v 6 I got the arguments: [v v ] The return value is going to be 10 The sum of v and half-dozen is 10              

In that output, notice the space after the last 5. Since wrap added an element to @_, even though it's undef, I get a space between it and the preceding 5 when I interpolate the assortment in the double-quoted cord.

Claw::LexWrap has the magic to handle all the calling contexts too. Information technology's smart enough to handle scalar, list, and void contexts. In list context, that terminal element of @_ in the posthandler will be an array reference. In void context, information technology won't exist anything.

It gets even better than that, though. Claw::LexWrap actually adds that extra element to @_ before it does anything. Look at the last output carefully. Subsequently the 2d argument, there's a space between the second v and the closing square bracket. That'southward the space between five and the undef value of the extra element in @_.

In the prehandler, I tin assign to that element, signaling to Hook::LexWrap that it should presume that information technology already has the return value, so information technology doesn't demand to actually run the original subroutine. If the subroutine isn't doing what I demand, I tin force it to return the right value:

#!/usr/bin/perl  use Hook::LexWrap;  my $n = shift @ARGV; my $m = $ARGV[0];  {  wrap add,         pre  => sub {                 print "I got the arguments: [@_]\northward";                 $_[-i] = "11";                 },         post => sub { print "The render value is going to be $_[-1]\due north" }         ; print "The sum of $northward and $m is " . add together( $n, $thou ) . "\north"; }  sub add         {         my( $due north, $m ) = @_;          my $sum = $due north + $m;          return $sum;         }              

Now that I've assigned to $_[-one] in my prehandler, the output is different. It doesn't run the subroutine or the posthandler, and I go back 11:

$ perl add_numbers.pl 5 6 I got the arguments: [5 6 ] The sum of 5 and 6 is eleven              

With my fake return value, I can give myself the right answer and go on with the right program, and practise it without irresolute the subroutine I want to investigate. This tin can be specially handy if I'm working on a big trouble where other things are broken, too. I know what I need to return from the subroutine so I get in do that until I fix the other parts, or at least investigate the rest of the plan while the subroutine returns what it should. Sometimes eliminating a source of error, fifty-fifty temporarily, makes it easier to ready other things.

perl5db.pl

We introduced the standard Perl debugger in Intermediate Perl and then we could examine circuitous data structures. It'southward well documented in the perldebug , and Richard Foley devoted an unabridged book, Pro Perl Debugging (Apress), to it, and so I volition just comprehend enough of the basics here so I can move on to the fancier debuggers.

I invoke the Perl debugger with Perl's -d switch:

perl -d add_number.pl 5 6

Perl compiles the program, merely stops before running the statements, giving me a prompt. The debugger shows me the plan proper name, line number, and the adjacent statement information technology volition execute:

Loading DB routines from perl5db.pl version 1.25 Editor support available.  Enter h or `h h' for assistance, or `man perldebug' for more help.  main::(Scripts/debugging/add_numbers.pl:3): iii:      my $due north = shift @ARGV;   D<i>

From there I can practice the usual debugging things, such every bit unmarried-stepping through code, setting breakpoints, and examining the program land.

I can likewise run the debugger on a plan I specify on the command line with the -e. I yet become the debugger prompt, just information technology's not very useful for debugging a programme. Instead, I accept access to the debugger prompt where I can try Perl statements:

$ perl -d -e 0  Loading DB routines from perl5db.pl version one.25 Editor support available.  Enter h or `h h' for help, or `man perldebug' for more than help.  main::(-due east:1):   0   D<1> $n = 1 + two;    D<2> ten $north 0  three   D<three>

We showed this debugger in Intermediate Perl , and it's well documented in perldebug and many other tutorials, so I won't spend time on it here. Cheque the references in the final department in this chapter, Further Reading," for sources of more information.

Alternative Debuggers

Too the standard perl5db.pl , there are several other sorts of debuggers that I can use, and there are several code analysis tools which use the debugging infrastructure. There's a long listing of Devel:: modules on CPAN, and one of them probably suits your needs.

Using a Different Debugger with -D

I tin can use an culling debugger by giving the -d switch an statement. In this case, I want to run my program under the Devel::DProf module. The -d switch implies the Devel::, so I leave that off. I'll cover profilers in depth in Chapter 5.

$ perl -d:DProf plan.pl

If I write my own debugging module, I tin can laissez passer arguments to the module simply like I can with the -M switch. I add the arguments as a comma-separated list after the module name and an equal sign. In this case, I load the Devel::MyDebugger with the arguments foo and bar:

$ perl -d:MyDebugger=foo,bar

Every bit normal Perl code, this is the same as loading Devel::MyDebugger with use.

use Devel::MyDebugger qw( foo bar );

Devel::ptkdb

I can use a Tk-based debugger that provides a graphical interface to the same features I have from perl5db.pl . The Devel::ptkdb module does not come with Perl, so I have to install it myself.[17]I beginning ptkdb by specifying it as the debugger I desire to use with the -d switch:

$ perl -d:ptkdb programme.pl              

Information technology starts by creating an awarding window. In the left pane, I run across the program lines around the current line, along with their line numbers (Figure 4-one). Buttons along the code pane allow me to search through the code. In the right pane, I have tabs to examine expressions, subroutines, and the list of current breakpoints.

The Devel::ptkdb provides a graphical debugger using Tk

Figure 4-1. The Devel::ptkdb provides a graphical debugger using Tk

The "Subs" tab gives me a hierarchal list of package names and the subroutines divers in them (Effigy 4-ii). These are all of the loaded modules, and I tin immediately display the code for any of those functions by selecting the 1 I want to see. I tin select ane either past double-clicking or navigating with the pointer keys and hitting <Return> when I get to the one I want. It doesn't change the country of my plan, and I can use the "Subs" tab to decide to step into a subroutine to sentry its execution, or stride over it and go on with the execution of the program.

In the Subs tab, I can see the subroutine in any loaded package

Figure four-ii. In the Subs tab, I tin see the subroutine in whatsoever loaded package

The "Exprs" tab is especially useful. It has two text entries at the top. "Quick Expr" allows me to enter a Perl expression, which it then replaces with its result, and affects the land of the programme if my quick expression sets or changes variables. This is the equivalent of trying a one-off expression in the terminal debugger. That'south nice, but the "Enter Expr" is even better. I enter a Perl expression and it adds it to the list of expressions in the pane below the tabs (Figure iv-3). As I run my code, these expressions update their results based on the current state of the program. I can add the variables I want to track, for instance, and lookout their values update.

I can track variable values in the Exprs tab

Effigy 4-three. I tin rail variable values in the Exprs tab

I start with a elementary programme where I want to add 2 numbers. It'southward not something that I need to debug (I hope), but I can utilise it to show the expressions tab doing its thing. At the start of the programme, I'm at the commencement of the programme and nothing has run yet. I single-step over the kickoff line of code and can encounter the values for $m and $northward, which I had previously entered as expressions. I could enter much more complex expressions, too, and ptkdb will update them as I move through the code.

Devel::ebug

The Devel::ebug module by Léon Brocard provides an object-oriented interface to Perl'due south debugger facility. It's a piece of work in progress, so what I say here might be different by the time you read this. The principal features should still be at that place, though.

Information technology comes with its own last-based debugger named ebug. It'south a fleck of an odd name until you realize how you lot phone call it. The missing d in the name comes from Perl's -d switch.

$ perl -d:ebug program.pl

I don't need to utilise the -d switch, though, since I can telephone call it direct with the ebug program, simply I have to call it by quoting the unabridged control line:[18]

$ ebug "add_numbers.pl 5 6" * Welcome to Devel::ebug 0.46 main(add_numbers.pl#iii): my $n = shift @ARGV; ebug: x @ARGV --- 5 --- half dozen  chief(add_numbers.pl#3): my $north = shift @ARGV; ebug: s principal(add_numbers.pl#four): my $thou = $ARGV[0]; ebug: x $n --- v              

The ebug program is actually but a wrapper around Devel::ebug::Panel, and I can telephone call Devel::ebug in many different ways. At the core of its design is a discrete procedure. The backend runs the program nether the debugger, and the frontend communicates with information technology over TCP. This means, for instance, I can debug the program on a different machine than on the one it's running.

The Devel::ebug::HTTP module uses the aforementioned Devel::ebug backend, but sets up a mini web server.[19]I start the ebug_http the aforementioned way I did with the console version, merely instead of giving me a prompt, information technology tells me the URL I need to admission to see the debugger:[20]

$ ebug_http "add_numbers.pl iv v" Y'all tin can connect to your server at http://albook.local:8321              

The spider web page shows me a blank bones debugger interface (Figure iv-iv). Remember, this is basically a proof of concept, merely even as that it'south very impressive and can serve every bit the ground for your ain tailor-made programs.

The Devel::ebug::HTTP module lets me debug a program on a remote server through my browser

Figure 4-four. The Devel::ebug::HTTP module lets me debug a program on a remote server through my browser

Other Debuggers

Ballsy

Eclipse[21]is an open up source development environment that runs on a variety of platforms. It'due south a Coffee application, but don't let that scare you off. It has a modular blueprint then people can extend it to meet their needs. Epic[22]is the Perl plug-in for Eclipse.

Eclipse is not just a debugger though, and that'due south probably not even its most interesting features. From the source code of my Perl program I can inspect classes, call back parts of the Perl documentation, and do quite a bit more.

Komodo

ActiveState'southward Komodo (Figure iv-5) started off every bit an integrated development surround for Perl on Microsoft Windows, although it's at present bachelor on Solaris, Linux, and Mac OS X. Information technology handles Perl every bit well as several other languages, including Tcl, Reddish, PHP, and Python.

ActiveState's Komodo is a complete development environment and even comes with a tutorial on its use

Figure four-5. ActiveState's Komodo is a consummate development surroundings and fifty-fifty comes with a tutorial on its use

Affrus

Affrus is a Perl-only debugger from Tardily Night Software[*]for Mac OS 10. Since I work almost exclusively on Mac, I really appreciate a debugger that'south quite Mac-similar. Late Nighttime Software started with Script Debugger for AppleScript, so they're tuned into Macs. Besides that, Affrus has the usual debugging features.

One of the features I find peculiarly useful is Affrus's Arguments pane. I can add invocations of my program, and so select which ane I want to run. In Effigy 4-6, I've added two different command lines and selected the first 1, which has the solid diamond next to it. When I run the plan, @ARGV gets the elements 5 and 6. If I salvage this as an Affrus file, the next fourth dimension I open the program with Affrus I still take access to those command lines.

Affrus allows me to configure several different command lines to use with my program; it updates expressions as my program runs

Figure 4-6. Affrus allows me to configure several different command lines to utilize with my program; it updates expressions every bit my plan runs

Like other debuggers, Affrus has a window where I tin can track the values of expressions. Affrus uses a separate window to display those. I can as well expect in the Debugging pane to see a list of all of the variables at any time (Figure 4-seven).

Affrus shows me the values of package variables in the Debugging pane

Effigy iv-7. Affrus shows me the values of packet variables in the Debugging pane

Summary

I can debug my Perl program at almost any level I desire, from inserting debugging code around that office I want to audit, or tweaking it from the outside with an integrated evolution environs. I tin can even debug the program on a machine other than the one I run information technology on. I don't take to stick with one arroyo, and might use many of them at the same fourth dimension. If I'm not satisfied with the existing debuggers, I can even create my own and tailor information technology for my particular task.

Further Reading

Perl Debugged by Peter Scott and Ed Wright (Addison-Wesley) is i of the best books about actually programming with Perl. Non simply practise they testify you lot how to effectively debug a Perl program, but they also prove y'all how to not get yourself into some of the mutual traps that force y'all to debug a program. Sadly, this book appears to be out of impress, but don't let the $1.99 price for a used version on Amazon.com color your notion of its usefulness.

Pro Perl Debugging (Apress) past Richard Foley tells you everything you need to know about the perl5db.pl debugger, which comes with Perl. If you like Perl'due south default debugger, this book will tell you everything yous want to know about information technology.

My first ever piece of Perl writing was a little piece for The Perl Journal number 9 chosen "Dice-ing on the Web." Information technology's bachelor at my personal web site: http://www.pair.com/comdog/Articles/Die_and_the_Web.txt.

I talk more about Hook::LexWrap in "Wrapping Subroutines" in the July 2005 event of The Perl Journal . The article originally appeared in The Perl Journal and at present appears in the "Lightweight Languages" section on Dr. Dobb'south Journal Online: http://www.ddj.com/dept/lightlang/184416218.

The Practise of Programming past Brian W. Kernighan and Rob Freeway (Addison-Wesley) discusses their approach to debugging. Although this isn't a Perl book, information technology actually doesn't demand to exist about any language. It'southward practical communication for any sort of programming.

Get Mastering Perl at present with O'Reilly online learning.

O'Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.