⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch30.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<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>,

&quot;References.&quot;

<HR>

<BLOCKQUOTE>

<B>Listing 30.1. A sample script to be debugged.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl -d<BR>

&nbsp;2 <BR>

&nbsp;3 sub xyc {<BR>

&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $a = $_[0];<BR>

&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print $a;<BR>

&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

&nbsp;7 # --------------------------------------------------------------

<BR>

&nbsp;8 # Define each state as subroutine. Then create a<BR>

&nbsp;9 # reference to each subroutine. We have four states here.

<BR>

10 # --------------------------------------------------------------

<BR>

11 $s0 = sub {<BR>

12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $a = $_[0];<BR>

13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;State 0 processing

$a \n&quot;;<BR>

14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '0')&nbsp;&nbsp;{ return(0);

}<BR>

15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '1')&nbsp;&nbsp;{ return(1);

}<BR>

16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '2')&nbsp;&nbsp;{ return(2);

}<BR>

17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '3')&nbsp;&nbsp;{ xyc(&quot;hello&quot;);

return(3); }<BR>

18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>

19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<BR>

20 # --------------------------------------------------------------

<BR>

21 $s1 = sub {<BR>

22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local $a = shift @_;<BR>

23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;State 1 processing

$a \n&quot;;<BR>

24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '0')&nbsp;&nbsp;{&nbsp;return(0);

}<BR>

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '1')&nbsp;&nbsp;{&nbsp;return(1);

}<BR>

26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '2')&nbsp;&nbsp;{&nbsp;return(2);

}<BR>

27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '3')&nbsp;&nbsp;{&nbsp;return(3);

}<BR>

28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;<BR>

29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<BR>

30 # --------------------------------------------------------------

<BR>

31 $s2 = sub {<BR>

32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local $a = $_[0];<BR>

33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;State 2 processing

$a \n&quot;;<BR>

34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '0')&nbsp;&nbsp;{&nbsp;return(0);

}<BR>

35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '1')&nbsp;&nbsp;{&nbsp;return(1);

}<BR>

36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '2')&nbsp;&nbsp;{&nbsp;return(2);

}<BR>

37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '3')&nbsp;&nbsp;{&nbsp;return(3);

}<BR>

38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 2;<BR>

39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<BR>

40 # --------------------------------------------------------------

<BR>

41 $s3 = sub {<BR>

42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local $a = shift @_;<BR>

43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;State 3 processing

$a \n&quot;;<BR>

44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '0')&nbsp;&nbsp;{ return(0);

}<BR>

45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '1')&nbsp;&nbsp;{ return(1);

}<BR>

46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '2')&nbsp;&nbsp;{ return(2);

}<BR>

47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($a eq '3')&nbsp;&nbsp;{ return(3);

}<BR>

48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 3;<BR>

49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<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 #&nbsp;&nbsp;&nbsp;set current state to 0<BR>

65 #&nbsp;&nbsp;&nbsp;forever<BR>

66 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get response

<BR>

67 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set current

state to next state based on response.<BR>

68 # --------------------------------------------------------------

<BR>

69 while (1)<BR>

70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>

71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n This state is :

$this -&gt; what next? &quot;;<BR>

72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reply = &lt;STDIN&gt;;<BR>

73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chop($reply);<BR>

74 <BR>

75&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

76&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Stop the machine here<BR>

77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($reply eq 'q') { exit(0);

}<BR>

79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot; Reply = $reply \n&quot;;

<BR>

80 <BR>

81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get the present state function.

<BR>

83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$state = $stateTable[$this];<BR>

85&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get the next state from this

state.<BR>

87&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$next = &amp;$state($reply);<BR>

89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf &quot;Next state = $next

from this state $this\n&quot;;<BR>

90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Now advance present state to

next state<BR>

92&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

93&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this = $next;<BR>

94&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</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&lt;3&gt;</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 + -