NAME
Devel::DumpTrace - Evaluate and print out each line before it is executed.
VERSION
0.09
SYNOPSIS
perl -d:DumpTrace program.pl
perl -d:DumpTrace=verbose program.pl
perl -d:DumpTrace=quiet program.pl
perl -d:DumpTrace=<n> program.pl
perl -d:DumpTrace::PPI program.pl
perl -d:DumpTrace::noPPI program.pl
DESCRIPTION
Similar to Devel::Trace, this module will cause a message to be printed to standard error for each line of source code that is executed. In addition, this module will attempt to identify variable names in the source code and substitute the values of those variables. In this way you can say the path of execution through your program as well as see the value of your variables at each step of the program.
For example, if your program looks like this:
#!/usr/bin/perl
# a demonstration of Devel::DumpTrace
$a = 1;
$b = 3;
$c = 2 * $a + 7 * $b;
@d = ($a, $b, $c + $b);
then the DumpTrace
output will look like:
$ 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);
There are also more verbose modes which will produce even more detailed output:
$ perl -d:DumpTrace=verbose demo.pl
>> demo.pl:3:
>>> $a = 1;
>>>>> 1 = 1;
-------------------------------------------
>> demo.pl:4:
>>> $b = 3;
>>>>> 3 = 3;
-------------------------------------------
>> demo.pl:5:
>>> $c = 2 * $a + 7 * $b;
>>>> $c = 2 * 1 + 7 * 3;
>>>>> 23 = 2 * 1 + 7 * 3;
-------------------------------------------
>> demo.pl:6:
>>> @d = ($a, $b, $c + $b);
>>>> @d = (1, 3, 23 + 3);
>>>>> (1,3,26) = (1, 3, 23 + 3);
-------------------------------------------
See $Devel::DumpTrace::TRACE
under the "VARIABLES" section for more details about the different levels of verbosity.
This distribution comes with both a basic parser and a PPI-based parser. If the PPI module is installed on your system, then this module will automatically use the PPI-based parser to analyze the traced code. You can force this module to use the basic parser by running with the -d:DumpTrace::noPPI
argument or by setting the DUMPTRACE_NOPPI
environment variable:
# use PPI if available, otherwise use basic parser
$ perl -d:DumpTrace program.pl
# fails if PPI is not available
$ perl -d:DumpTrace::PPI program.pl
# always uses basic parser
$ perl -d:DumpTrace::noPPI program.pl
$ DUMPTRACE_NOPPI=1 perl -d:DumpTrace program.pl
There is also a Devel::DumpTrace::PPI module in this distribution which relies on PPI to understand the source code.
See the "BUGS AND LIMITATIONS" section for important, er, limitations of this module, especially for the basic parser.
SUBROUTINES/METHODS
None of interest.
VARIABLES
$Devel::DumpTrace::TRACE
Controls whether and how much output is produced by this module. Setting $Devel::DumpTrace::TRACE
to zero will disable the module. Since this module can produce a lot of output and has other overhead that can considerably slow down your program, you may find it useful to toggle this variable for critical sections of your code rather than leave it set for the entire program. For example:
BEGIN { $Devel::DumpTrace::TRACE = 0 }
&some_non_critical_code_that_more_or_less_works();
$Devel::DumpTrace::TRACE = 'normal';
&the_critial_code_you_want_to_debug();
$Devel::DumpTrace::TRACE = 0;
&some_more_non_critical_code();
or to enable tracing in a local
block:
{
local $Devel::DumpTrace::TRACE = 1;
&the_critical_code;
}
In general higher values of $Devel::DumpTrace::TRACE
will cause more output to be produced. Let's consider this simple program to see how the different $Devel::DumpTrace::TRACE
settings affect the output:
@a = (1 .. 40);
$b = $a[4];
$Devel::DumpTrace::TRACE
== 1-
is the quietest mode. One line of output for each statement evaluated. The name of each variable in the source code and its value are included in the same line of output. Values of long scalars, long arrays, or long hash tables are heavily abbreviated:
$ perl -d:DumpTrace=1 littledemo.pl >>>>> littledemo.pl:1:[__top__]: @a:(1,2,3,4,5,6,...,40) = (1 .. 40); >>>>> littledemo.pl:2:[__top__]: $b:5 = $a:(1,2,3,4,5,6,...,40)[4];
$Devel::DumpTrace::TRACE
== 2-
uses a single line of output for each statement evaluated. The name of each variable in the source code and its source code are included in the same line of output. Values of long scalar, arrays, and hashes are less heavily abbreviated.
$ perl -I. -d:DumpTrace=2 littledemo.pl >>>>> littledemo.pl:1:[__top__]: @a:(1,2,3,4,5,6,7,8,9,10,11,12,13,14, \ 15,16,17,18,19,20,21,22,23,24,25,26,27,...,40) = (1 .. 40); >>>>> littledemo.pl:2:[__top__]: $b:5 = $a:(1,2,3,4,5,6,7,8,9,10,11,12, \ 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,...,40)[4];
$Devel::DumpTrace::TRACE
== 3-
produces one line of output for each statement evaluated. The name of each variable in the source code and its source code are included in the same line of output. Values of long scalar, arrays, and hashes are not abbreviated at all. This is the default setting for the module.
$ perl -I. -d:DumpTrace=3 littledemo.pl >>>>> littledemo.pl:1:[__top__]: @a:(1,2,3,4,5,6,7,8,9,10,11,12,13,14, \ 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, \ 38,39,40) = (1 .. 40); >>>>> littledemo.pl:2:[__top__]: $b:5 = $a:(1,2,3,4,5,6,7,8,9,10,11,12, \ 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35, \ 36,37,38,39,40)[4];
$Devel::DumpTrace::TRACE
== 4-
produces up to four lines of output for each statement evaluated:
the source (file and line number) of the statement being evaluated
the origianl source code for the statement being evaluated
a valuation of the code before the statement has been evaluated by the Perl interpreter.
a valuation of the code after the statement has been evaluated by the Perl interpreter
A separator line will also be displayed between statements. Long scalar, arrays, and hashes may be abbreviated. Example output:
$ perl -d:DumpTrace=4 littledemo.pl >> littledemo.pl:1:[__top__]: >>> @a = (1 .. 40); >>>>> (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, \ 21,22,23,24,25,26,27,...,40) = (1 .. 40); ------------------------------------------- >> littledemo.pl:2:[__top__]: >>> $b = $a[4] + $a[5]; >>>> $b = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \ 20,21,22,23,24,25,26,27,...,40)[4]; >>>>> 5 = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \ 20,21,22,23,24,25,26,27,...,40)[4]; -------------------------------------------
$Devel::DumpTrace::TRACE
== 5-
Like
$TRACE
4, but long scalars, arrays, and hashes are not abbreviated.$ perl -I. -d:DumpTrace=5 littledemo.pl >> littledemo.pl:1:[__top__]: >>> @a = (1 .. 40); >>>>> (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, \ 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40) = (1 .. 40); ------------------------------------------- >> littledemo.pl:2:[__top__]: >>> $b = $a[4] + $a[5]; >>>> $b = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40)[4]; >>>>> 5 = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, \ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40)[4];
As these demos suggest, you can pass the $TRACE
variable through the command line using the syntax -d:DumpTrace=level
. In place of a number, you may also use the keywords quiet
or verbose
which will set the $TRACE
variable to 1 and 5, respectively.
By default Devel::DumpTrace
does not evaluate statements in any "system" modules, which are defined as any module from a file that resides under an absolute path in your system's @INC
list of directories. If the $TRACE
variable is set to a value larger than 100, then this module will drill down into such modules. See also "EXCLUDE_PKG" and "INCLUDE_PKG" for another way to exercise control over what packages this module will explore.
For convenience, the $Devel::DumpTrace::TRACE
variable is aliased to the $Devel::Trace::TRACE
variable. This way you can enable settings in your program that can be used by both Devel::Trace and Devel::DumpTrace
.
$Devel::DumpTrace::DUMPTRACE_FH
By default, all output from the Devel::DumpTrace
module is written to standard error. This behavior can be changed by setting $Devel::DumpTrace::DUMPTRACE_FH
to the desired I/O handle:
BEGIN {
# if Devel::DumpTrace is loaded, direct output to xtrace-output.txt
if ($INC{'Devel/DumpTrace.pm'}) {
open $Devel::DumpTrace::DUMPTRACE_FH, '>', '/path/xtrace-output.txt';
}
}
The output stream for the Devel::DumpTrace
module can also be controlled with the environment variable DUMPTRACE_FH
. If this variable is set to STDOUT
, then output will be directed to standard output. If this variable contains another value that looks like a filename, this module will open a file with that name and write the trace output to that file.
Backwards-incompatible change: in v0.06, this variable was called XTRACE_FH
.
$Devel::DumpTrace::ARRAY_ELEM_SEPARATOR = ','
$Devel::DumpTrace::HASH_ENTRY_SEPARATOR = ';'
$Devel::DumpTrace::HASH_PAIR_SEPARATOR = '=>'
The Devel::DumpTrace
module uses the preceding default values as delimiters when creating string representations of arrays, hashes, and array/hash references. If you wish to use different delimiters for whatever reason (maybe your arrays have a lot of elements with commas in them), you can change these values.
$Devel::DumpTrace::XEVAL_SEPARATOR = ':'
In normal (non-verbose) mode, Devel::DumpTrace
will display this token between the name of a variable and its value (e.g., $c:23
). The default token is a colon (:
), but you may change it by changing the value of the variable $Devel::DumpTrace::XEVAL_SEPARATOR
.
%Devel::DumpTrace::EXCLUDE_PKG, %Devel::DumpTrace::INCLUDE_PKG
Sets of packages that this module will never/always explore. These settings take precedence over the setting of the $Devel::DumpTrace::TRACE
variable, and the settings of %Devel::DumpTrace::INCLUDE_PKG
take precendence over the settings of %Devel::DumpTrace::EXCLUDE_PKG
(that is, a package that is specified in both %EXCLUDE_PKG
and %INCLUDE_PKG
will be included).
CONFIGURATION AND ENVIRONMENT
Devel::DumpTrace
uses the DUMPTRACE_FH
and DUMPTRACE_LEVEL
environment variables to configure some package variables. See "VARIABLES". The DUMPTRACE_NOPPI
variable can be set to force this module to use the basic code parser and to ignore the PPI-based version.
This is an incompatible change from v0.06, which recognized the vars XTRACE_FH
and XTRACE_LEVEL
.
INCOMPATIBILITIES
None known.
EXPORT
Nothing is or can be exported from this module.
DIAGNOSTICS
Nothing interesting.
DEPENDENCIES
Devel::DumpTrace
requires the PadWalker and Scalar::Util modules.
BUGS AND LIMITATIONS
Parser limitations
Some known cases where the output of this module will be incorrect or misleading include:
Multiple statements on one line
$b = 7;
$a=4; $b=++$a;
>>>>> 4 = 4; 7 = 4;
$a=4; $b=++$a;
>>>>> 5 = 4; 5 = 5;
All statements on a line are evaluated, not just the statement currently being executed.
Statements with chained assignments; complex assignment expressions (*)
($a,$b) = ('','bar');
$a = $b = 'foo';
>>>>> 'foo' = 'bar' = 'foo';
$rin=$ein=3;
>> select $rout=$in,undef,$eout=$ein,0;
>>> select $rout=3,undef,undef=3,0;
>>>>> select 3=3,undef,undef=3,0;
Everything to the right of the first assignment operator in a statement is evaluated before the statement is executed.
Multiple lines for one statement (*)
$a = ($b + $c # ==> oops, all this module sees is
+ $d + $e); # $a = ($b + $c
Only the first line of code in an expression is evaluated.
Displayed value of @_ variable is unreliable
The displayed value of @_
inside a subroutine is subject to some of the issues described in "caller" in perlfunc:
... be aware that setting @DB::args is best effort, intended for
debugging or generating backtraces, and should not be relied upon
... a side effect of the current implementation means that effects
of shift @_ can normally be undone (but not pop @_ or other splicing,
and not if a reference to @_ has been taken, and subject to the caveat
about reallocated elements), so @DB::args is actually a hybrid of the
current state and initial state of @_ . Buyer beware.
That is, the displayed value of @_
inside a subroutine may be corrupted. Different versions of Perl may have different behavior.
Basic parser limitations
This distribution ships with a PPI-based parser and a more basic parser that will be used if PPI
is not available (or if you explicitly request to use the basic parser). This parser is quite crude compared to the PPI-based parser, and suffers from these additional known issues:
String literals that contain variable names
print STDERR "\$x is $x\n"; # ==> print STDERR "\4 is 4\n";
$email = 'mob@cpan.org'; # ==> $email = 'mob().org'
The parser is not sophisticated enough to tell whether a sigil is inside non-interpolated quotes.
Implicit $_
, @_
It would be nice if this parser could detect when Perl was implicitly using some variables and display the implicit variable.
/expression/; # actually $_ =~ /expression/
my $self = shift; # actually my $self = shift(@_);
That is not currently a capability of this module.
Special Perl variables are not recognized
$a = join $/, 'foo', 'bar'; # ==> $a = join $/, 'foo', 'bar'
Special variables with pure alphanumeric names like @ARGV
, $_
, and $1
will still be interpolated. Do see "caller" in perlfunc for some important caveats about how @_
is represented by this module.
For some of these limitations, there are easy workarounds (break up chained assignments, put all statements on separate lines, etc.) if you think the extra information provided by this module is worth the effort to make your code more friendly for this module.
Other bugs or feature requests
Please report any other bugs or feature requests to bug-devel-xtrace at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel-DumpTrace. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Devel::DumpTrace
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
SEE ALSO
dumpvar.pl, as used by the Perl debugger.
Devel::DumpTrace::PPI is part of this distribution and provides similar functionality using PPI to parse the source code.
Devel::TraceVars is a very similar effort to Devel::DumpTrace
, but this module handles arrays, hashes, references, objects, lexical our
variables, and addresses more edge cases.
Tie::Trace provides facilities to watch the values of specific variables, including stack trace information about where and how the variables values were changed.
AUTHOR
Marty O'Brien, <mob at cpan.org>
LICENSE AND COPYRIGHT
Copyright 2010-2011 Marty O'Brien.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.