Home arrow Perl Programming arrow Page 3 - Debugging Perl

Doing Whatever I Want - Perl

Every developer knows that debugging is one of the most important parts of coding. This two-part article focuses on Perl debuggers. It is excerpted from chapter four of Mastering Perl, written by Brian D Foy (O'Reilly; ISBN: 0596527241). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

  1. Debugging Perl
  2. The Best Debugger in the World
  3. Doing Whatever I Want
  4. Program Tracing
  5. Safely Changing Modules
By: O'Reilly Media
Rating: starstarstarstarstar / 2
July 24, 2008

print this article



I can change the warn and die functions myself by messing with %SIG. I like to use these to peer into code Iím trying to figure out, but I donít use these to add features to code. Itís just part of my debugging toolbox.

The pseudokeys __WARN__ and __DIE__ hold the functions that perform those actions when I use the warn or die 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 about to die!" )

Without going through the entire code base, I can change all of the die calls into the more informative croak calls.ß In this example, I preface the subroutine call with an & and no parentheses to trigger Perlís feature to pass on the current argument list to the next subroutine call so croak gets all of the arguments I pass:

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

  die "I'm going now!"; # really calls croak now

If I only want to do this for part of the code, I can use local (since %SIG is a special variable always in main::). My redefinition stays in effect until the end 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.

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

  use Carp;

  print "Starting program...\n";

  $SIG{__DIE__} = sub {
          local $Carp::CarpLevel = 0;


  foo(); # program dies here

  sub foo { bar() }

  sub bar { die "Dying from bar!\n"; }

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

  Starting program...
  Dying from bar!
at die.pl line 12
                 main::__ANON__('Dying from bar!\x{a}') called at die.pl line 20
                 main::bar() called at die.pl line 18
                 main::foo() called at die.pl line 16

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

  $SIG{__DIE__} = sub {
          local $Carp::CarpLevel = 1;


Now I donít see the unwanted output:

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

For a real-life example 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 way. Instead of an annoying ďServer Error 500Ē message, I can get useful error output by simply loading the module. While loading, CGI::Carp sets $SIG{__WARN__} and $SIG{__DIE__}:

  use CGI::Carp qw(fatalsToBrowser);

The fatalsToBrowser function takes over the resulting page 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 course, I donít recommend that you use this in production code. I donít want users to see the programís errors. They can be handy when I have 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 there I let the public figure out how Iím doing things, and thatís bad for security.

>>> More Perl Programming Articles          >>> More By O'Reilly Media

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Perl Turns 25
- Lists and Arguments in Perl
- Variables and Arguments in Perl
- Understanding Scope and Packages in Perl
- Arguments and Return Values in Perl
- Invoking Perl Subroutines and Functions
- Subroutines and Functions in Perl
- Perl Basics: Writing and Debugging Programs
- Structure and Statements in Perl
- First Steps in Perl
- Completing Regular Expression Basics
- Modifiers, Boundaries, and Regular Expressio...
- Quantifiers and Other Regular Expression Bas...
- Parsing and Regular Expression Basics
- Hash Functions

Developer Shed Affiliates


Dev Shed Tutorial Topics: