First of all, have you tried the use warnings
pragma?
If you invoke Perl with the -d
switch, your program will be run inside the Perl debugger. This works
like an interactive Perl environment, prompting for debugger commands
that let you examine source code, set breakpoints, dump out your
function-call stack, change the values of variables, and so on. Any
command not recognized by the debugger is directly executed (using
eval
) as Perl code in the package of the code
currently being debugged. (The debugger uses the DB
package for its own state information, to avoid trampling yours.) This
is so wonderfully convenient that people often fire up the debugger just
to test out Perl constructs interactively. In that case, it doesn't
matter what program you tell Perl to debug, so we'll choose one without
much meaning:
%
perl -de 42
In Perl, the debugger is not a program completely separate from
the one being debugged, the way it usually is in a typical programming
environment. Instead, the -d
flag tells the
compiler to insert source information into the parse trees it's about to
hand off to the interpreter. That means your code must first compile
correctly for the debugger to work on it. If that is successful, the
intrepreter preloads a special Perl library file containing the debugger
itself.
%
perl -d /path/to/program
The program will halt immediately before the first run-time executable statement (but see Section 20.1 regarding compile-time statements) and ask you to enter a debugger command. Whenever the debugger halts and shows you a line of code, it displays the line that it's about to execute, not the one just executed.
As the debugger encounters a line, it first checks for a
breakpoint, prints it (if the debugger is in trace mode), performs any
actions (created with the a
command described later
in "Debugger Commands"), and finally prompts the user if a breakpoint is
present or if the debugger is in single-step mode. If not, it evaluates
the line normally and continues to the next line.
The debugger prompt is something like:
DB<8>
or even:
DB<<17>>
where the number shows how many commands you've executed. A
csh-like history mechanism allows you to access
previous commands by number. For example, !17
would
repeat command number 17. The number of angle brackets indicates the
depth of the debugger. For example, you get more than one set of
brackets if you're already at a breakpoint and then print out the
result of a function call that itself also has a breakpoint.
If you want to enter a multiline command, such as a subroutine definition with several statements, you may escape the newline that would normally end the debugger command with a backslash. Here's an example:
DB<1> for (1..3) { cont: print "ok "; cont: } ok ok ok
Let's say you want to fire up the debugger on a little program
of yours (let's call it camel_flea) and stop it
as soon as it gets down to a function named
infested
. Here's how you'd do that:
%
perl -d camel_flea
Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(camel_flea:2): pests('bactrian', 4); DB<1>
The debugger halts your program right before the first run-time executable statement (but see below about compile-time statements) and asks you to enter a command. Again, whenever the debugger stops to show you a line of code, it displays the line it's about to execute, not the one it just executed. The line displayed may not look exactly like it did in your source file, particularly if you've run it through any kind of preprocessor.
Now, you'd like to stop as soon as your program gets to the
infested
function, so you establish a breakpoint
there like so:
DB<1> b infested DB<2> c
The debugger now continues until it hits that function, at which point it says this:
main::infested(camel_flea:8): my $bugs = int rand(3);
To look at a "window" of source code around the
breakpoint, use the w
command:
DB<2> w
5 }
6
7 sub infested {
8==>b my $bugs = int rand(3);
9: our $Master;
10: contaminate($Master);
11: warn "needs wash"
12 if $Master && $Master->isa("Human");
13
14: print "got $bugs
";
DB<2>
As you see by the ==>
marker,
your current line is line 8, and by the b
there,
you know it has a breakpoint on it. If you'` had set an action, there
also would also have been an a
there. The line
numbers with colons are breakable; the rest are not.
To see who called whom, ask for a stack backtrace using
the T
command:
DB<2> T
$ = main::infested called from file `Ambulation.pm' line 4
@ = Ambulation::legs(1, 2, 3, 4) called from file `camel_flea' line 5
. = main::pests('bactrian', 4) called from file `camel_flea' line 2
The initial character ($
,
@
, or .) tells whether the function was called in a
scalar, list, or void context, respectively. There are three lines
because you were three functions deep when you ran the stack
backtrace. Here's what each line means:
The first line says you were in the function
main::infested
when you ran the stack trace. It
tells you the function was called in a scalar context from line 4
of the file Ambulation.pm. It also shows that
it was called without any arguments whatsoever, meaning it was
called as &infested
instead of the normal
way, as infested()
.
The second line shows that the function
Ambulation::legs
was called in list context
from line number 5 of the camel_flea file,
with those four arguments.
The third line shows that main::pests
was
called in void context from line 2 of
camel_flea.
If you have compile-phase executable statements such as
code from BEGIN
and CHECK
blocks
or use
statements, these will
not ordinarily be stopped by the debugger,
although require
s and INIT
blocks will, since they happen after the transition to run phase (see
Chapter 18). Compile-phase
statements can be traced with the AutoTrace
option
set in PERLDB_OPTS
.
You can exert a little control over the Perl debugger from within your Perl program itself. You might do this, for example, to set an automatic breakpoint at a certain subroutine whenever a particular program is run under the debugger. From your own Perl code, however, you can transfer control back to the debugger using the following statement, which is harmless if the debugger is not running:
$DB::single = 1;
If you set $DB::single
to 2, it's equivalent
to the n
command, whereas a value of 1 emulates the
s
command. The $DB::trace
variable should be set to 1 to simulate the t
command.
Another way to debug a module is to set breakpoint on loading:
DB<7> b load c:/perl/lib/Carp.pm
Will stop on load of `c:/perl/lib/Carp.pm'.
and then restart the debugger using the R
command. For finer control, you can use the b compile
subname
to stop as soon as possible after a particular
subroutine is compiled.