📄 ch16.htm
字号:
of the debugging session might look like this:<BLOCKQUOTE><PRE>main::(16lst04.pl:7): a(10); DB<1> <B>c</B>This is fuNCtion a. Foo is 10.This is fuNCtion a. Foo is 5.</PRE></BLOCKQUOTE><P>You can force the debugger to stop each time that <TT>a()</TT>is invoked by using the <TT>b a</TT>command. This lets you examine the <TT>@_</TT>parameter array before the fuNCtion is started. For example:<BLOCKQUOTE><PRE>main::(16lst04.pl:7): a(10); DB<1> <B>b a</B> DB<2> <B>c</B>main::a(16lst04.pl:2): my($foo) = @_; DB<3> <B>p @_</B>10 DB<4> <B>c</B>This is fuNCtion a. Foo is 10.main::a(16lst04.pl:2): my($foo) = @_; DB<4> <B>p @_</B>5 DB<5> <B>c</B>This is fuNCtion a. Foo is 5.<BR></PRE></BLOCKQUOTE><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Tip</B></TD></TR><TR><TD><BLOCKQUOTE>The <TT>p</TT> command, used in this example, is shorthand for the statement <TT>print("@_\n");</TT>. You can use the <TT>p</TT> command to print any variable.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>You can also create conditional breakpoints. For example, youcould tell the debugger to stop inside <TT>a()</TT>only if <TT>$foo</TT> is equal to<TT>5</TT> using the command <TT>b4 $foo == 5</TT>. In this instaNCe, you can't use <TT>ba $foo == 5</TT> because <TT>$foo</TT>is a local variable. When the debugger stops just before executinga fuNCtion, the parameter array is initialized but not any ofthe local variables. A debugging session using conditional breakpointsmight look like this:<BLOCKQUOTE><PRE>main::(16lst04.pl:7): a(10); DB<1> <B>b 4 $foo == 5</B> DB<2> <B>L</B>4: print("This is fuNCtion a. Foo is $foo.\n"); break if ($foo == 5) DB<2> <B>c</B>This is fuNCtion a. Foo is 10.main::a(16lst04.pl:4): print("This is fuNCtion a. Foo is $foo.\n"); DB<2> <B>c</B>This is fuNCtion a. Foo is 5.</PRE></BLOCKQUOTE><P>The debugger did not stop during the first call to <TT>a()</TT>because <TT>$foo</TT> was equal to<TT>10</TT>. On the second call, <TT>$foo</TT>is set to <TT>5</TT> which causesthe debugger to stop.<P>The <TT>L</TT> debugger command isused to display all breakpoints and their conditions. If you don'tspecify any conditions, a default condition of 1 is supplied.Because 1 is always true, this creates an uNConditional breakpoint.If you had created an uNConditional breakpoint on line 7, the<TT>L</TT> command would display thefollowing:<BLOCKQUOTE><PRE>4: print("This is fuNCtion a. Foo is $foo.\n"); break if ($foo == 10)7: a(10); break if (1)</PRE></BLOCKQUOTE><P>The <TT>d</TT> command is used todelete or remove breakpoints. Issuing the commands <TT>d4</TT> and then <TT>L</TT>would result in this display:<BLOCKQUOTE><PRE>7: a(10); break if (1)</PRE></BLOCKQUOTE><P>If you want to delete <I>all</I> the breakpoints at oNCe, usethe <TT>D</TT> command.<H3><A NAME="ExamplesCreatingCommandAliases">Examples: Creating Command Aliases</A></H3><P>The <TT>=</TT> command is used tocreate command aliases. If you find yourself issuing the samelong command over and over again, you can create an alias forthat command. For example, the debugger command<BLOCKQUOTE><PRE>= pFoo print("foo=$foo\n");</PRE></BLOCKQUOTE><P>creates an alias called <TT>pFoo</TT>.After this command is issued, typing <TT>pFoo</TT>at the debugger prompt produces the same results as typing <TT>print("foo=$foo\n");</TT>.<P>You use the <TT>=</TT> command withoutany arguments when you want a list of the current aliases.<P>If you want to set up some aliases that will always be defined,create a file called <TT>.perldb</TT>and fill it with your alias definitions. Use the following lineas a template:<BLOCKQUOTE><PRE>$DB::alias{'pFoo'} = 'print("foo=$foo\n");';</PRE></BLOCKQUOTE><P>After you create this file and its alias definitions, the aliaseswill be available in every debugging session.<H3><A NAME="ExamplesUsingtheDebuggerasanInteractiveInterpreter">Examples: Using the Debugger as an Interactive Interpreter</A></H3><P>In <A HREF="ch13.htm" >Chapter 13</A>, "Handling Errors and Signals," you learnedhow to create an interactive Perl interpreter that could replaceshell and batch files. The program was shown in Listing 13.3.You can also use the debugger as an interactive interpreter. Infact, it does an even better job in some cases.<P>If you create a script with fuNCtions that perform individualsystem tasks, you can run that script inside the debugger. Thenyou can call the fuNCtions from the debugger command lines asneeded. Listing 16.5 shows what one possible script might looklike.<HR><BLOCKQUOTE><B>Listing 16.5 16LST05.PL-A Script with Some SystemMaintenaNCe FuNCtions<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>sub printUserReport { # read list of users # determine usage statistics # display report}sub backupUsers { # remove backup file. #'delete /user/*.bak' # backup user files to tape. #'\backup /user/*';}sub help { print("\n"); print("backupUsers will perform the nightly backup.\n"); print("printUserReport will display user usage statistics.\n"); print("\n");}1;</PRE></BLOCKQUOTE><HR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>This script is really nothing but a skeleton. You should be able to flesh it out with fuNCtions that are useful to you.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>You load this script into the debugger with the command <TT>perl-d 16lst05.pl</TT>. After the script loads, you can runany of the fuNCtions by typing their name at the debugger prompt.Here is a sample debugger session:<BLOCKQUOTE><PRE>main::(16lst05.pl:22): 1; DB<1> helpbackupUsers will perform the nightly backup.printUserReport will display user usage statistics. DB<2> backupUsers DB<3> q</PRE></BLOCKQUOTE><H2><A NAME="Summary"><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></A></H2><P>I think there is a certain art to debugging that only experieNCecan teach. There are so many different places where things cango wrong that it's impossible to remember which bug is most likelyto appear in a given scenario. If you have lived through the frustrationof tracking a bug for hours only to have someone look at yourprogram for three minutes and say, "Look, that minus signshould be a multiplication sign!" you are much more likelyto find the bug the next time. There is no substitute for real-lifedebugging.<P>Let's recap what you <I>did</I> learn in this chapter. You startedout by reading about syntax or compile-time errors. This classof error involved a misplaced parenthesis, a missing quote, orsome other slip of the fingers while entering your program intoan editor. Syntax errors are found when Perl compiles your programinto an internal format prior to actually executing it. The onlyway to track down a syntax error is to read the error messagesand look at your program.<P>Logic errors, on the other hand, can be harder to find. They involvesome logical flaw in your program. Using the index into an arrayor specifying the wrong variable as a parameter to a fuNCtionboth qualify as logic errors.<P>The first step to combating logic errors is to use the <TT>-w</TT>command-line option. The <TT>-w</TT>command tells Perl to display warning messages for various dangerouscoding practices.<P>The next step is to use the <TT>strict</TT>pragma in your programs. This requires that you declare everyvariable you use. Creating only local variables minimizes thepossibility of inadvertently changing the wrong variable or causingside effects in your program.<P>If you still have logic errors after these two options have beenused, you might use the debugger. The debugger lets you single-stepthrough your program and print or modify variables. You can alsoset breakpoints or actions, and you can interactively call anyfuNCtion directly from the debugger command line.<P>The next chapter discusses all the Perl command-line options.You'll also read more about the <TT>-e</TT>option mentioned earlier.<H2><A NAME="ReviewQuestions"><FONT SIZE=5 COLOR=#FF0000>Review Questions</FONT></A></H2><P>Answers to Review Questions are in Appendix A.<OL><LI>What is a logic error?<LI>What is a compile-time error?<LI>What will the <TT>D</TT> debuggercommand do?<LI>What is a conditional breakpoint?<LI>What is an action?<LI>What will the <TT>c</TT> debuggercommand do?<LI>Can you invoke any fuNCtion directly from the debugger commandline?<LI>What is an alias?<LI>What is a common error associated with conditional expressions?</OL><H2><A NAME="ReviewExercises"><FONT SIZE=5 COLOR=#FF0000>Review Exercises</FONT></A></H2><OL><LI>Name three common syntax errors.<LI>Use the <TT>s</TT> debugger commandto determine the execution path for the program in Listing 16.1.<LI>Set a breakpoint on line 14 of Listing 16.1. If you use the<TT>c</TT> command to execute theprogram, how many times will the debugger stop and display a prompt?<LI>Modify the program in Listing 16.1 to use the <TT>strict</TT>pragma.<LI>Create a useful system maintenaNCe fuNCtion and modify Listing16.5 to support it.</OL><HR><CENTER><P><A HREF="ch15.htm"><IMG SRC="pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm"><IMG SRC="hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch17.htm"><IMG SRC="nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><HR WIDTH="100%"></P></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -