Perl
  Home arrow Perl arrow Using The Perl Debugger
Dev Shed Forums 
Administration  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PERL

Using The Perl Debugger
By: icarus, (c) Melonfire
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 21
    2003-06-25

    Table of Contents:
  • Using The Perl Debugger
  • Step By Step
  • Breaking Free
  • A Watchful Eye
  • Acts Of Madness
  • Test Drive

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
     
    ADVERTISEMENT

    TestComplete™ automates software testing for a fraction of what the big guys charge. Easy functional and load testing for all Windows, .NET, Java and Web apps. Download a free trial now.

    Using The Perl Debugger
    (Page 1 of 6 )

    Perl aficionados might find this hard to believe, but to a lot of people, Perl is - to put it bluntly - one of the most terrifying languages on the planet.

    There are a number of reasons for this, and only some of them are unwarranted. Novice developers find the language's sometimes-complex syntax intimidating, and its freewheeling "there's more than one way to do it" attitude confusing. The special symbols and variables that experienced Perl developers sprinkle liberally around their code (can you say @_?), coupled with the intricacies of Perl variable scoping, regular expressions, object-oriented programming and modules, can leave them bewildered and weak at the knees, and the language's terse error messages only serve to increase their frustration when things go wrong.

    I can sympathize. Not so long ago, I too was one of these terrified souls, lost in the darkness of the Perl universe. Until the day a friend introduced me to the Perl debugger. And then there was light.

    {mospagebreak title=Start Me Up}

    Most casual Perl users aren't even aware that Perl ships with a debugger, but it does...and it's quite a good one too. In addition to allowing you to arbitrarily jump around your code, it also allows you to execute statements on a line-by-line basis, set breakpoints and watch-expressions, inspect variables and trace program flow (among other things).

    In order to demonstrate the features of the debugger, I'll be using some sample Perl scripts. Here's the first one, a script which accepts an identifier as input argument, connect to a database, retrieves a list of email addresses and sends them email.


    #!/usr/bin/perl

    # load module
    use DBI();

    unless($ARGV[0])
    {
    print "ERROR: Please provide a valid input ID\n\n";
    }

    # get user input into variable
    my $id = $ARGV[0];

    # connect
    my $dbh = DBI->connect("DBI:mysql:database=db198;host=localhost", "root", "secret", {'RaiseError' => 1}) or die ("Cannot connect to database");

    # set up email message
    my $sendmail = "/usr/sbin/sendmail -t";
    my $reply_to = "Reply-to: foo\@bar.org";
    my $subject = "Subject: FOOBAR";
    my $content = "Hello and how are you doing? This is the message body";

    # now retrieve email addresses and send mail to each
    my $sth = $dbh->prepare("SELECT email FROM users WHERE users.id = '$id'"); $sth->execute(); while(my $ref = $sth->fetchrow_hashref()) {
    my $to = $ref->{'email'};
    open(SENDMAIL, "|$sendmail") or die "Cannot send mail: $!";
    print SENDMAIL $reply_to ."\n";
    print SENDMAIL $subject . "\n";
    print SENDMAIL "To: " . $to . "\n";
    print SENDMAIL "Content-type: text/plain\n\n";
    print SENDMAIL $content;
    close(SENDMAIL);
    }

    # clean up
    $dbh->disconnect();

    Perl's built-in debugger can be invoked simply by adding the -d option to your Perl command line, as below:


    $ perl -d mailer.pl 877
    Loading DB routines from perl5db.pl version 1.19
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(mailer.pl:6): unless($ARGV[0])
    main::(mailer.pl:7): {
    DB<1>

    This will pop you into the debugger and place you at the first line of your script.

    The


    DB<1>

    marker is the debugger command prompt; this is where you will enter debugger commands. The number in angle braces following the prompt keeps track of the number of commands you've entered, so that you can easily reuse a previous command.

    Commands entered at the prompt which are not debugger commands are evaluated as Perl statements, and executed - as illustrated below:


    DB<2> print 8+10;

    DB<3> 18

    DB<3> $a=10/2

    DB<4> print $a;

    DB<5> 5

    You can enter multi-line commands into the debugger by separating them with a backslash, as in the example below:


    DB<2> @flavours = ("vanilla", "chocolate", "strawberry");

    DB<3> for $f (@flavours) { \
    cont: print "$f\n"; \
    cont: };
    vanilla
    chocolate
    strawberry

    Help is available via the "h" command (don't be intimidated, most of the following will be explained over this article),


    DB<1> h
    List/search source lines: Control script execution:
    l [ln|sub] List source code T Stack trace
    - or . List previous/current line s [expr] Single step [in expr]
    v [line] View around line n [expr] Next, steps over subs
    f filename View source in file <CR/Enter> Repeat last n or s
    /pattern/ ?patt? Search forw/backw r Return from subroutine
    M Show module versions c [ln|sub] Continue until position
    Debugger controls: L List break/watch/actions
    o [...] Set debugger options t [expr] Toggle trace [trace
    expr]
    <[<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint
    ! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints
    H [-num] Display last num commands a [ln] cmd Do cmd before line
    = [a val] Define/list an alias A ln|* Delete a/all actions
    h [db_cmd] Get help on command w expr Add a watch expression
    h h Complete help page W expr|* Delete a/all watch exprs
    |[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess
    q or ^D Quit R Attempt a restart
    Data Examination: expr Execute perl code, also see: s,n,t expr
    x|m expr Evals expr in list context, dumps the result or lists
    methods.
    p expr Print expression (uses script's current package).
    S [[!]pat] List subroutine names [not] matching pattern
    V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern.
    X [Vars] Same as "V current_package [Vars]".
    y [n [Vars]] List lexicals in higher scope <n>. Vars same as V.
    For more help, type h cmd_letter, or run man perldebug for all docs.

    and you can obtain detailed help with the "h h" command


    DB<1> h h

    Help is currently only available for the new 580 CommandSet,
    if you really want old behaviour, presumably you know what you're doing ?-)

    T Stack trace.
    s [expr] Single step [in expr].
    n [expr] Next, steps over subroutine calls [in expr].
    <CR> Repeat last n or s command.
    r Return from current subroutine.
    c [line|sub] Continue; optionally inserts a one-time-only breakpoint
    at the specified position.
    l min+incr List incr+1 lines starting at min.
    l min-max List lines min through max.
    l line List single line.
    ...

    Once your script has completed exiting, you can restart it with the "R" command, as below,


    Debugged program terminated. Use q to quit or R to restart,
    use O inhibit_exit to avoid stopping after program termination,
    h q, h R or h O to get additional info.
    DB<10> R
    Warning: some settings and command-line options may be lost!

    Loading DB routines from perl5db.pl version 1.19
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(mailer.pl:6): unless($ARGV[0])
    main::(mailer.pl:7): {
    DB<10>

    or exit the debugger (this works even during script execution) by typing "q", and you will be immediately returned to your command prompt.


    DB<1> q

    Don't do that just yet, though - after all, you're here to learn more about this strange and wonderful new animal, and it would be rude to leave so quickly. Next up, I'll show you how to step through a script and execute it on a line-by-line basis.

    * Moving Up

    Now that you're in the debugger, let's start with something basic: moving around your script. Type "l" at the command prompt, and watch as the debugger goes busily to work listing the first ten lines of your script.


    DB<1> l
    6==> unless($ARGV[0])
    7 {
    8: print "ERROR: Please provide a valid input ID\n\n";
    9 }
    10
    11 # get user input into variable
    12: my $id = $ARGV[0];
    13
    14 # connect
    15 # fix these as per your local settings

    Typing "l" again will take you to the next screen of code,


    DB<1> l
    16==> my $dbh = DBI->connect("DBI:mysql:database=db198;host=localhost",
    "secret", "", {'RaiseError' => 1}) or die ("Cannot connect to database"); 17
    18 # set up email message
    19: my $sendmail = "/usr/sbin/sendmail -t";
    20: my $reply_to = "Reply-to: foo\@bar.org";
    21: my $subject = "Subject: FOOBAR";
    22: my $content = "Hello and how are you doing? This is the message body";
    23
    24 # now retrieve email addresses and send mail to each
    25: my $sth = $dbh->prepare("SELECT email FROM users WHERE users.id =
    '$id'");

    and so on.

    You can have the debugger display a specific line by specifying a line number to the "l" command,


    DB<3> l 19
    19==> my $sendmail = "/usr/sbin/sendmail -t";

    or even display a block of lines by specifying a range of line numbers.


    DB<4> l 20-25
    20==> my $reply_to = "Reply-to: foo\@bar.org";
    21: my $subject = "Subject: FOOBAR";
    22: my $content = "Hello and how are you doing? This is the message body";
    23
    24 # now retrieve email addresses and send mail to each
    25: my $sth = $dbh->prepare("SELECT email FROM users WHERE users.id =
    '$id'");

    You can display the previous line with the "-" command,


    DB<5> -
    10==>
    11 # get user input into variable
    12: my $id = $ARGV[0];
    13
    14 # connect
    15 # fix these as per your local settings
    16: my $dbh = DBI->connect("DBI:mysql:database=db198;host=localhost",
    "root", "secret", {'RaiseError' => 1}) or die ("Cannot connect to database"); 17
    18 # set up email message
    19: my $sendmail = "/usr/sbin/sendmail -t";

    or return to the last executed line with the "." command.


    DB<5> .
    main::(mailer.pl:16): my $dbh =
    DBI->connect("DBI:mysql:database=db198;host=localhost", "root",
    DBI->"secret",
    {'RaiseError' => 1}) or die ("Cannot connect to database");

    You can view the code above and below a specific line with the "v" command,


    DB<3> v 27
    24: my $description = $ref->{'description'};
    25: $sth->finish();
    26
    27 # now use the group ID to get the group text
    28: my $sth = $dbh->prepare("SELECT group_text FROM groups WHERE
    group_id =
    '$gid'");
    29: $sth->execute();
    30: my $ref = $sth->fetchrow_hashref();
    31: my $gtext = $ref->{'group_text'};
    32: $sth->finish();
    33

    or even perform basic search operations within the debugger.


    DB<3> /FOOBAR
    21: my $subject = "Subject: FOOBAR";

    This ability to move around your script comes in very handy when dealing with large and complex scripts.

    More Perl Articles
    More By icarus, (c) Melonfire


     

       

    PERL ARTICLES

    - Perl: Another Round with Hashes
    - Perl Hashes
    - Perl Lists: A Final Look at List::Util
    - Perl Lists: Utilizing List::Util
    - Perl Lists: The Split() Function
    - SQL and CGI with Perl and DBI
    - Perl Lists: More Functions and Operators
    - SELECT Queries and Perl
    - Perl Lists: More on Manipulation
    - Creating a Database with Perl and DBI
    - Perl: Sailing the List(less) Seas
    - Perl and DBI
    - Perl: Concatenating Text and More
    - Perl Text: Quoting Without Quote Marks
    - Perl: Releasing Your Inner Textuality

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway