What are some good Perl debugging methods?

2019-01-21 07:07发布

问题:

Are there any other ways for debugging Perl apart from Data::Dumper and perl -d?

回答1:

Available tools for debugging

There are several tools available in Perl for debugging and similar tasks.


Built-in command line debugger.

perl -d yourcode.pl

Devel::ptkdb

Perl/Tk based graphical debugger by Andrew E. Page.


Regex Coach

This a free tool running both on Linux and Windows written in Lisp. Source code is not available.


Rx: A Regex Debugger for Perl

The Perl Regex debugger and an article about it written by Mark Jason Dominus.


A GUI for the Perl Debugger



回答2:

There are lots of things out there to help you:

  • Devel::Trace - print every line that executes
  • Carp::REPL - drop into a REPL* when the code throws a warning
  • Devel::ebug - a debugger you can control from Perl code
  • Enbugger - use debugger at runtime regardless of whether your process was started with debugging


回答3:

I like Devel::Trace. Basically it gives you an execution dump, showing you the code paths.

On another side, Test Driven Development is all the rage now, so you could also be interested in profiling tools like Devel::NYTProf for highly advanced testing. See this Tim bunce's blog post for an interesting overview.



回答4:

I use ActiveState Komodo for step-by-step debugging.

Eclipse has a step by step debugger for its EPIC plugin.

Personally I prefer the ActiveState version. It just seems more solid and stable, but it does cost (and work is paying for me). If it was my money then I would use Eclipse and EPIC as these are free.



回答5:

The best debugging aids are small routines, short scopes, limited side effects, and lots of tests. Stop bugs before they hatch.



回答6:

My usual range of tools is:

  • print statements and Data::Dumper for simple cases
  • perl -d

That's usually enough. There is ddd; I heard it's quite nice, but never played with it.

For some tasks (which are not really debugging, but close to it) I use Devel::NYTProf.



回答7:

Some people use print statements in order to see what's going on in sections of a program that aren't doing what they thought the code would do. (I.e., as a way of checking what is actually contained in a variable at a given point of execution.)

That said, the question is pretty vague. Is there something you are trying to do that Data::Dumper and perl -d aren't helping with?



回答8:

Depending on what you're doing, Log::Log4perl provides an easy way to manage the 'print' style of debugging particularly in bigger applications:

  • provides various logging levels (Debug, Info, Error, Warning, Fatal)
  • controlled from config files (easy to have debugging on development box, only errors on production box, for example)
  • configurable by sections of your application (e.g. web app in one log file at one level, cron scripts in another at a different log level)
  • configurable by Class - easy to quieten noisy modules, or add detailed debugging to somewhere deep within an app


回答9:

Test::More for writing basic tests, Hook::LexWrap, Test::MockObject, Test::Deep, Test::MockTime, Test::WWW::Mechanize and many others for advanced tests. Attribute::Signature for checking sub params. Carp::Assert for contract-based programming.

Devel::Ebug::Wx or Devel::ptkdb (and soon better support in Padre) can be used for easier debugging.



回答10:

Emacs, hands down.

   emacs my_script.pl
   M-x perldb
   Emacs will prompt you :
   Run perldb (like this): perl my_script.pl
   Hit enter (or add command line switches)

   Now use the debugger as usual.
   Type 'c' to continue executing the code, which will now follow
   your code as you execute through it.

   Emacs is fully integrated with its debuggers and will make debugging perl code nearly trivial.


回答11:

Use, Devel::SimpleTrace, for the most elegant seemless stateless-debugging.

perl -MDevel::SimpleTrace -we'warn "main"; sub foo{ warn "outer"; sub { warn "inner" } }; foo()->()'



回答12:

If you don't like perl -d then Devel::REPL and Carp::REPL are both nice alternatives.



回答13:

Personally, I'm a big fan of Smart::Comments. Makes tracing dead simple, no need to strip it out again, either.

use Smart::Comments -ENV;
...
sub myroutine {
    my ($self, @args) = @_ ;
    ### args: @args
    ...
}

If Smart_Comments has been set in the environment, the lines commencing with ### are converted to debug output, with Dumper() used automagically. If the environment variable isn't set, the debug stuff is completely inert.

It has heaps of features, and will produce progress bars, warnings, abort conditions as well as plain old debug output.

Appropriate tests are all good, and I'm not dismissing a good TDD development methodology, but when trying to get to the bottom of an existing bug, Smart::Comments is the go.



回答14:

Generally I use

perl -d

for debugging.

YOu can also use Eclipse Perl Integration (EPIC) plug-in for Eclipse It offers a rich debugging environment available and integrated with the EPIC Perl development environment. You can use it and is generally helpful.



回答15:

During development, I like to embed printf statements in strategic places (not too many) which are enabled with a debug flag like this:

printf("h='$h', j='$j', ... (%d)\n", __LINE__) if $debug;

where the debug flag is defined at the top of the script:

my $debug = $ENV{DEBUG} || 0;

Now instead of having to remember to comment out all of the printf lines, I just run the script as follows:

DEBUG=1 ./script.pl

After testing when everything is ready for production, the debug lines can be removed:

cat script.pl | grep -v 'if $debug;'


回答16:

Writing tests can mostly decrease debugging time, I think.



回答17:

Some Other methods

CGI::Dump

Benchmark

Command-line options 

__DATA__ & <DATA> 

$.

__FILE__ & __LINE__ 

warn() & die() 


回答18:

Debug::Statements provides an easy way to insert and enable/disable print statements for debugging.

The d() function prints the name of your variable, its value, and your subroutine name. The implementation been optimized to minimize programmer keystrokes.

Here is sample code to get you started:

my $myvar = 'some value';
my @list = ('zero', 1, 'two', "3");
my %hash = ('one' => 2, 'three' => 4);

use Debug::Statements;
my $d = 1;
d "Hello world";
d '$myvar';
d '@list %hash';

Output:

DEBUG sub mysub:  Hello world
DEBUG sub mysub:  $myvar = 'some value'
DEBUG sub mysub:  @list = [
  'zero',
  1,
  'two',
  '3'
]
DEBUG sub mysub:  %hash = {
  'one' => 2,
  'three' => 4
}

Many options are available to customize the output. Full documentation can be found on CPAN.