📄 ch30.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 30 -- Using the Perl Debugger</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 30</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Using the Perl Debugger</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#ASampleSession" >A Sample Session</A>
<LI><A HREF="#SteppingThroughCode" >Stepping Through Code</A>
<LI><A HREF="#LookingatValues" >Looking at Values</A>
<LI><A HREF="#Breakpoints" >Breakpoints</A>
<LI><A HREF="#Actions" >Actions</A>
<LI><A HREF="#SearchingforPatterns" >Searching for Patterns</A>
<LI><A HREF="#Subroutines" >Subroutines</A>
<LI><A HREF="#Caveats" >Caveats</A>
<LI><A HREF="#CustomizingYourDebuggerEnvironment" >Customizing Your Debugger Environment</A>
<LI><A HREF="#ForMoreInformation" >For More Information</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
This chapter introduces you to the internal Perl debugger. Perl
has modules with debugging facilities to help you catch bugs in
your Perl scripts. The use of the debugger will prove to be invaluable
when you're debugging complicated Perl scripts, especially when
writing or working with your own Perl modules. Admittedly, the
debugging facilities in Perl are not as fancy as those found in
packages for C, C++, or BASIC; however, they can be very powerful
tools in catching nasty bugs that are not caught by the Perl compiler
or by the warning facility in Perl.
<P>
There are two switches to Perl you should be aware of: the <TT><FONT FACE="Courier">-d</FONT></TT>
switch for turning on the debugger for a script and the <TT><FONT FACE="Courier">-w
</FONT></TT>switch for printing out warning messages when ambiguous
code is encountered. We will be covering the <TT><FONT FACE="Courier">-d</FONT></TT>
switch through most of this chapter. Warning messages are printed
by the Perl interpreter when suspect code is encountered. To turn
on the ability to print warnings in header code, add the <TT><FONT FACE="Courier">-w</FONT></TT>
to the header comment as shown below:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/usr/bin/perl -w </FONT></TT>
</BLOCKQUOTE>
<P>
You will find, though, that simply getting warning messages is
not enough to debug your code. What if you need to monitor the
values of variables in a program? For such a feature, you will
have to use a debugger.
<P>
To invoke the debugger you simply invoke your script with the
<TT><FONT FACE="Courier">-d</FONT></TT> option. It's also possible
to place the <TT><FONT FACE="Courier">-d</FONT></TT> option in
the first line of script. Here's an example:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/usr/bin/perl -d</FONT></TT>
</BLOCKQUOTE>
<P>
The debugger is invoked when the script is run. You are presented
a message about the version of the debugger and a prompt to type
your commands. You issue the cryptic one-character commands at
the prompt in order to get the debugger to execute the program,
set breakpoints, view or edit variable contents, and so on.
<P>
The debugger is a Perl module called <TT><FONT FACE="Courier">DB</FONT></TT>
and comes with the Perl 5.002 distribution files. All required
source code for the <TT><FONT FACE="Courier">DB</FONT></TT> module
is in the file <TT><FONT FACE="Courier">perl5db.pl</FONT></TT>
in your <TT><FONT FACE="Courier">/usr/lib/perl5</FONT></TT> directory.
You must have the <TT><FONT FACE="Courier">perl5db.pl</FONT></TT>
file in your <TT><FONT FACE="Courier">PERLLIBDIR</FONT></TT> path
for the debugger to work. The <TT><FONT FACE="Courier">perl5db.pl</FONT></TT>
file contains the entire list of commands available to you. (Look
in the middle of the source file around line 128 to see what commands
are available.)
<P>
When the debugger is invoked, you have a set of one- or two-character
commands that you can use. Typing the <TT><FONT FACE="Courier">h</FONT></TT>
command gives you a list of all commands available to you. Unfortunately,
unless you have a very long screen, the output scrolls by very
quickly. Therefore, if you are not familiar with the Perl debugger,
I strongly recommend at least going through the debugger commands
detailed in this chapter once before you attempt a debug session
on an important Perl program on your own.
<H2><A NAME="ASampleSession"><B><FONT SIZE=5 COLOR=#FF0000>A Sample
Session</FONT></B></A></H2>
<P>
Use the sample script shown in Listing 30.1 to run a sample debug
session. You have seen this script before in <A HREF="ch3.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch3.htm" >Chapter 3</A>,
"References."
<HR>
<BLOCKQUOTE>
<B>Listing 30.1. A sample script to be debugged.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl -d<BR>
2 <BR>
3 sub xyc {<BR>
4 my $a = $_[0];<BR>
5 print $a;<BR>
6 }<BR>
7 # --------------------------------------------------------------
<BR>
8 # Define each state as subroutine. Then create a<BR>
9 # reference to each subroutine. We have four states here.
<BR>
10 # --------------------------------------------------------------
<BR>
11 $s0 = sub {<BR>
12 my $a = $_[0];<BR>
13 print "State 0 processing
$a \n";<BR>
14 if ($a eq '0') { return(0);
}<BR>
15 if ($a eq '1') { return(1);
}<BR>
16 if ($a eq '2') { return(2);
}<BR>
17 if ($a eq '3') { xyc("hello");
return(3); }<BR>
18 return 0;<BR>
19 };<BR>
20 # --------------------------------------------------------------
<BR>
21 $s1 = sub {<BR>
22 local $a = shift @_;<BR>
23 print "State 1 processing
$a \n";<BR>
24 if ($a eq '0') { return(0);
}<BR>
25 if ($a eq '1') { return(1);
}<BR>
26 if ($a eq '2') { return(2);
}<BR>
27 if ($a eq '3') { return(3);
}<BR>
28 return 1;<BR>
29 };<BR>
30 # --------------------------------------------------------------
<BR>
31 $s2 = sub {<BR>
32 local $a = $_[0];<BR>
33 print "State 2 processing
$a \n";<BR>
34 if ($a eq '0') { return(0);
}<BR>
35 if ($a eq '1') { return(1);
}<BR>
36 if ($a eq '2') { return(2);
}<BR>
37 if ($a eq '3') { return(3);
}<BR>
38 return 2;<BR>
39 };<BR>
40 # --------------------------------------------------------------
<BR>
41 $s3 = sub {<BR>
42 local $a = shift @_;<BR>
43 print "State 3 processing
$a \n";<BR>
44 if ($a eq '0') { return(0);
}<BR>
45 if ($a eq '1') { return(1);
}<BR>
46 if ($a eq '2') { return(2);
}<BR>
47 if ($a eq '3') { return(3);
}<BR>
48 return 3;<BR>
49 };<BR>
50 <BR>
51 # --------------------------------------------------------------
<BR>
52 # Create an array of pointers to subroutines. The index<BR>
53 # into this array is the current state.<BR>
54 # --------------------------------------------------------------
<BR>
55 @stateTable = ($s0, $s1, $s2, $s3);<BR>
56 <BR>
57 # --------------------------------------------------------------
<BR>
58 # Intialize the state to 0.<BR>
59 # --------------------------------------------------------------
<BR>
60 $this = 0;<BR>
61 <BR>
62 # --------------------------------------------------------------
<BR>
63 # Implement the state machine.<BR>
64 # set current state to 0<BR>
65 # forever<BR>
66 # get response
<BR>
67 # set current
state to next state based on response.<BR>
68 # --------------------------------------------------------------
<BR>
69 while (1)<BR>
70 {<BR>
71 print "\n This state is :
$this -> what next? ";<BR>
72 $reply = <STDIN>;<BR>
73 chop($reply);<BR>
74 <BR>
75 #<BR>
76 # Stop the machine here<BR>
77 #<BR>
78 if ($reply eq 'q') { exit(0);
}<BR>
79 print " Reply = $reply \n";
<BR>
80 <BR>
81 #<BR>
82 # Get the present state function.
<BR>
83 #<BR>
84 $state = $stateTable[$this];<BR>
85 #<BR>
86 # Get the next state from this
state.<BR>
87 #<BR>
88 $next = &$state($reply);<BR>
89 printf "Next state = $next
from this state $this\n";<BR>
90 #<BR>
91 # Now advance present state to
next state<BR>
92 #<BR>
93 $this = $next;<BR>
94 }</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
When you first run this program, you are presented the screen
shown in Figure 30.1. The filename, line number, and line of code
that will be executed next are shown before the prompt.
<P>
<A HREF="f30-1.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f30-1.gif" ><B>Figure 30.1 : </B><I>Using the Perl debugger.</I></A>
<P>
The prompt has a number between the less-than and greater-than
signs to signify the calling level. As the program execution continues,
the number will indicate the number of debugger commands in the
history of commands in the debugger. For example, if you have
three commands in the debugger history list, your prompt will
look like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">DB<3></FONT></TT>
</BLOCKQUOTE>
<P>
Let's first see how we can list the contents of the program we
are debugging. To list the contents of the file, you have to use
the <TT><FONT FACE="Courier">l</FONT></TT> command. By default,
10 lines of the source code are listed. Every time you type an
<TT><FONT FACE="Courier">l</FONT></TT> command, the next 10 lines
of the file are listed, as shown in Figure 30.2.
<P>
<A HREF="f30-2.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f30-2.gif" ><B>Figure 30.2 : </B><I>Listing the source with the 1 command.</I></A>
<P>
You can look at just one specific line by specifying the line
number as a parameter to the <TT><FONT FACE="Courier">l</FONT></TT>
command. For example, the command to print the code on line 23
would be <TT><FONT FACE="Courier">l 23</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">l</FONT></TT> command can also take
one set of line numbers to specify a range of parameters. The
ranges have to be specified in the following form. Lines numbers
in a range are inclusive.
<BLOCKQUOTE>
<TT><I><FONT FACE="Courier">startLine-endLine.</FONT></I></TT>
</BLOCKQUOTE>
<P>
Don't specify the <TT><I><FONT FACE="Courier">endLine</FONT></I></TT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -