45

I have a system script in perl. I need some equivalent of bash -x to determine what is going wrong with the script. Is there something equivalent?

EDIT: What bash -x does is that it prints each line as it is evaluated. This makes debugging code that is just missing some path variable or file very easy.

Randall
  • 2,859
  • 1
  • 21
  • 24
Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • 1
    Explain what you want to do in terms of what you're wanting to do. Not in terms of specific arbitrary shell. – Evan Carroll Oct 04 '10 at 02:00
  • 1
    possible duplicate of [How can I make Perl and Python print each line of the program being executed?](http://stackoverflow.com/questions/2872089/how-can-i-make-perl-and-python-print-each-line-of-the-program-being-executed) – daxim Oct 04 '10 at 05:44
  • possible duplicate of [What are some good Perl debugging methods?](http://stackoverflow.com/questions/1037583/what-are-some-good-perl-debugging-methods) – Ether Oct 04 '10 at 16:14

6 Answers6

49

Take a look at Devel::Trace or Devel::ebug.

Given this program named w.pl:

#!/usr/bin/perl

use strict;
use warnings;

my $answer = 42;

if ($answer == 6 * 9) {
    print "everything is running fine.\n";
} else {
    warn "there must be a bug somewhere...\n";
}

You can use Devel::Trace to watch the execution:

perl -d:Trace w.pl

Which produces the following output:

>> w.pl:6: my $answer = 42;
>> w.pl:8: if ($answer == 6 * 9) {
>> w.pl:11:     warn "there must be a bug somewhere...\n";
there must be a bug somewhere...
Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
9

The Devel::DumpTrace module has been available since 2011.

Sample usage:

$ cat demo.pl
# demo.pl
# a demonstration of Devel::DumpTrace
$a = 1;
$b = 3;
$c = 2 * $a + 7 * $b;
@d = ($a, $b, $c + $b);

$ perl -d:DumpTrace demo.pl
>>>>> demo.pl:3:        $a:1 = 1;
>>>>> demo.pl:4:        $b:3 = 3;
>>>>> demo.pl:5:        $c:23 = 2 * $a:1 + 7 * $b:3;
>>>>> demo.pl:6:        @d:(1,3,26) = ($a:1, $b:3, $c:23 + $b:3);
mob
  • 117,087
  • 18
  • 149
  • 283
7

You should look at "perl -d" (turn on debugger) or "perl -c" (check your script before executing

Raghuram
  • 51,854
  • 11
  • 110
  • 122
  • 5
    Be warned, "before executing" doesn't mean no code runs. Any code in a `BEGIN` block (or in a module than has been included with `use`) will run even if you use the `-c` option: `perl -cle 'BEGIN { print "oops, this runs" } print "but this does not"'`. – Chas. Owens Oct 04 '10 at 02:12
2

Always include these statements in your perl scripts:

use strict;
use warnings;

If you want to debug it, use the -d switch. And here are the commands: http://www.domainavenue.com/pl-debug.htm

Hope that helps.

ysth
  • 96,171
  • 6
  • 121
  • 214
Ruel
  • 15,438
  • 7
  • 38
  • 49
2

If you are running a current version of perl you can use Devel::Agent.

perl -d:Agent -MDevel::Agent::EveryThing myscript.pl
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 31 '21 at 13:52
1

In the Perl debugger (run your program by prefixing perl -d to it) you can use the t (trace) command in the interactive debugger to toggle tracing. After reloading your program (R) the status of the trace is reset. Unfortunately tracing can significantly slow down your program, especially if loops are executed many times.

Here is some example output:

...
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:10):
10:         my($class, $key, $hasher, $block_size) =  @_;
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:11):
11:         $block_size ||= 64;
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:12):
12:         $key = $hasher->new->add($key)->digest if length($key) > $block_size;
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:14):
14:         my $self = bless {}, $class;
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:15):
15:         $self->{k_ipad} = $key ^ (chr(0x36) x $block_size);
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:16):
16:         $self->{k_opad} = $key ^ (chr(0x5c) x $block_size);
Digest::HMAC::new(/usr/lib/perl5/vendor_perl/5.18.2/Digest/HMAC.pm:17):
17:         $self->{hasher} = $hasher->new->add($self->{k_ipad});
Digest::SHA::new(/usr/lib/perl5/5.18.2/x86_64-linux-thread-multi/Digest/SHA.pm:45):
45:             my($class, $alg) = @_;
...
U. Windl
  • 3,480
  • 26
  • 54
  • BTW: Does anybody know a way to restrict tracing to specific subroutines only (to reduce the slow-down)? – U. Windl Jul 06 '23 at 11:53