Chapter 20. The Perl DebuggerContents:
Using the Debugger
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: 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 -de 42 The program will halt immediately before the first run-time executable statement (but see the section Section 20.1, "Using the Debugger" 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.% perl -d /path/to/program 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. 20.1. Using the DebuggerThe debugger prompt is something like: or even:DB<8> 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: 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:DB<1> for (1..3) { \ cont: print "ok\n"; \ cont: } ok ok ok 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.% 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> Now, you'd like to stop as soon as your program gets to the infested function, so you establish a breakpoint there like so: The debugger now continues until it hits that function, at which point it says this:DB<1> b infested DB<2> c 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: 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.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\n"; DB<2> 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:
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 requires and INIT blocks will, since they happen after the transition to run phase (see Chapter 18, "Compiling"). 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: 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.$DB::single = 1; Another way to debug a module is to set breakpoint on loading: 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.DB<7> b load c:/perl/lib/Carp.pm Will stop on load of `c:/perl/lib/Carp.pm'. Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|