I would like to trace my Perl script, but only code in the main
package, and redirect output to a file.
When starting the script with perl -d script.pl
it goes into interactive mode.
I have tried
perl -d:Trace perl_05.pl 2&> output.log
But this also traces all subroutines and modules which I do not want.
I am looking for something like the bash set -o xtrace
or sh -x
.
Most trace sources generate packetized data that might be further formatted by the trace infrastructure. This means that the captured trace data is not in a human-readable format. The trace data must go through extraction, decompression, decode, and processing stages to become human-readable.
The article Trace your Perl programs addresses your concerns regarding the amount of traces and shows you a way to tune the output so you just trace what you want.
You can create your own throw-away module to trace exactly what you want. Since the current directory is usually already in
@INC
, you can create aDevel/MyTrace.pm
.
Read it completely to see how the author modifies the default behavior of the trace function to output first the traces to a file, then to STDERR too and finally limits the output to just trace the primary file.
You can go one step further to exclude all code except for the primary file:
use v5.10; use autodie; BEGIN { my $trace_file = $ENV{TRACE_FILE} // "mytrace.$$"; print STDERR "Saving trace to $trace_file\n"; my $fh = do { if( $trace_file eq '-' ) { \*STDOUT } elsif( $trace_file eq 'STDERR' ) { \*STDERR } else { open my $fh, '>>', $trace_file; $fh; } }; sub DB::DB { my( $package, $file, $line ) = caller; return unless $file eq $0; my $code = \@{"::_<$file"}; print $fh "[@{[time]}] $file $l $code->[$line]"; } } 1;
That last chunk of code is the one that is specially interesting for you. It does exactly what you want.
Using perl with Devel::DumpTrace
is a lot like using bash -x
. Like bash -x
, Devel::DumpTrace
expands and outputs variable values to give you an idea of what your script was doing, not just where it is doing it.
It also has the feature you are looking for: to enable and disable tracing on specific packages. For your use case, you would run it like
perl -d:DumpTrace=-.*,+main my_script.pl
or
perl -d:DumpTrace=-.* my_script.pl
-.*
means "exclude all packages that match /^.*$/
from tracing", which is to say, all packages. +main
means "include package main
in tracing".
The default output can be fairly verbose. If you want less output than that, you can specify quiet
mode:
perl -d:DumpTrace=quiet,-.*,+main my_script.pl
(I am the author of Devel::DumpTrace
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With