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

📄 ch20_05.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
字号:
<html><head><title>Debugger Support (Programming Perl)</title><!-- STYLESHEET --><link rel="stylesheet" type="text/css" href="../style/style1.css"><!-- METADATA --><!--Dublin Core Metadata--><meta name="DC.Creator" content=""><meta name="DC.Date" content=""><meta name="DC.Format" content="text/xml" scheme="MIME"><meta name="DC.Generator" content="XSLT stylesheet, xt by James Clark"><meta name="DC.Identifier" content=""><meta name="DC.Language" content="en-US"><meta name="DC.Publisher" content="O'Reilly &amp; Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Debugger Support"><meta name="DC.Type" content="Text.Monograph"></head><body><!-- START OF BODY --><!-- TOP BANNER --><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home"><map name="banner-map"><AREA SHAPE="RECT" COORDS="0,0,466,71" HREF="index.htm" ALT="Programming Perl"><AREA SHAPE="RECT" COORDS="467,0,514,18" HREF="jobjects/fsearch.htm" ALT="Search this book"></map><!-- TOP NAV BAR --><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch20_04.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch20_01.htm">Chapter 20: The Perl Debugger</a></td><td align="right" valign="top" width="172"><a href="ch20_06.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h2 class="sect1">20.5. Debugger Support</h2><p><a name="INDEX-3646"></a>Perl provides special debugging hooks at both compile time and run time for creating debugging environments such as the standard debugger.  These hooks are not to be confusedwith the <em class="emphasis">perl -D</em> options, which are usable only if your Perl wasbuilt with <span class="option">-DDEBUGGING</span> support.</p><p>For example, whenever you call Perl's built-in <tt class="literal">caller</tt> function fromthe package <tt class="literal">DB</tt>, the arguments that the corresponding stack frame wascalled with are copied to the the <tt class="literal">@DB::args</tt> array.  When you invokePerl with the <span class="option">-d</span> switch, the following additional features are enabled:</p><ul><li><p>Perl inserts the contents of <tt class="literal">$ENV{PERL5DB}</tt> (or <tt class="literal">BEGIN {require'perl5db.pl'}</tt> if not present) before the first line of your program.</p></li><li><p>The array <tt class="literal">@{"_&lt;$filename"}</tt> holds the lines of <tt class="literal">$filename</tt> for allfiles compiled by Perl.  The same for <tt class="literal">eval</tt>ed strings that containsubroutines or are currently being executed.  The <tt class="literal">$filename</tt>for <tt class="literal">eval</tt>ed strings looks like <tt class="literal">(eval 34)</tt>.   Code assertionsin regular expressions look like <tt class="literal">(re_eval 19)</tt>.</p></li><li><p>The hash <tt class="literal">%{"_&lt;$filename"}</tt> contains breakpoints and actions keyed byline number.  You can set individual entries as opposed to the wholehash.  Perl only cares about Boolean truth here, although the valuesused by <em class="emphasis">perl5db.pl</em> have the form <tt class="literal">"$break_condition\0$action"</tt>.Values in this hash are magical in numeric context: they are zeros ifthe line is not breakable.</p><p>The same holds for evaluated strings that contain subroutines orare currently being executed.  The <tt class="literal">$filename</tt> for <tt class="literal">eval</tt>edstrings looks like <tt class="literal">(eval 34)</tt> or <tt class="literal">(re_eval 19)</tt>.</p></li><li><p>The scalar <tt class="literal">${"_&lt;$filename"}</tt> contains <tt class="literal">"_&lt;$filename"</tt>.  This isalso the case for evaluated strings that contain subroutines or are currently being executed.  The <tt class="literal">$filename</tt> for <tt class="literal">eval</tt>edstrings looks like <tt class="literal">(eval 34)</tt> or <tt class="literal">(re_eval 19)</tt>.</p></li><li><p>After each <tt class="literal">require</tt>d file is compiled, but before itis executed, <tt class="literal">DB::postponed(*{"_&lt;$filename"})</tt> iscalled if the subroutine <tt class="literal">DB::postponed</tt> exists.Here, the <tt class="literal">$filename</tt> is the expanded name of the<tt class="literal">require</tt>d file, as found in the values of<tt class="literal">%INC</tt>.</p></li><li><p>After each subroutine <em class="replaceable">subname</em> is compiled,the existence of<tt class="literal">$DB::postponed{</tt><em class="replaceable">subname</em><tt class="literal">}</tt>is checked.  If this key exists,<tt class="literal">DB::postponed(</tt><em class="replaceable">subname</em><tt class="literal">)</tt>is called if the <tt class="literal">DB::postponed</tt> subroutine alsoexists.</p></li><li><p>A hash <tt class="literal">%DB::sub</tt> is maintained, whose keys aresubroutine names and whose values have the form<em class="replaceable">filename</em><tt class="literal">:</tt><em class="replaceable">startline-endline</em>.<em class="replaceable">filename</em> has the form <tt class="literal">(eval34)</tt> for subroutines defined inside <tt class="literal">eval</tt>s,or <tt class="literal">(re_eval 19)</tt> for those within regular expressioncode assertions.</p></li><li><p>When the execution of your program reaches a point that might hold abreakpoint, the <tt class="literal">DB::DB()</tt> subroutine is called if any of the variables<tt class="literal">$DB::trace</tt>, <tt class="literal">$DB::single</tt>, or <tt class="literal">$DB::signal</tt> is true.  These variablesare not <tt class="literal">local</tt>izable.  This feature is disabled when executinginside <tt class="literal">DB::DB()</tt>, including functions called from itunless <tt class="literal">$^D &amp; (1&lt;&lt;30)</tt> holds true.</p></li><li><p>When execution of the program reaches a subroutine call, a call to<tt class="literal">&amp;DB::sub(</tt><em class="replaceable">args</em><tt class="literal">)</tt> is made instead, with <tt class="literal">$DB::sub</tt> holding thename of the called subroutine.  This doesn't happen if the subroutinewas compiled in the <tt class="literal">DB</tt> package.</p></li></ul><p>Note that if <tt class="literal">&amp;DB::sub</tt> needs external data for it to work, nosubroutine call is possible until this is done.  For the standarddebugger, the <tt class="literal">$DB::deep</tt> variable (how many levels of recursiondeep into the debugger you can go before a mandatory break) givesan example of such a dependency.</p><h3 class="sect2">20.5.1. Writing Your Own Debugger</h3><p>The minimal working debugger consists of one line:<blockquote><pre class="programlisting">sub DB::DB {}</pre></blockquote>which, since it does nothing whatsoever, can easily be defined via the <tt class="literal">PERL5DB</tt> environmentvariable:<blockquote><pre class="programlisting">% <tt class="userinput"><b>PERL5DB="sub DB::DB {}" perl -d your-program</b></tt></pre></blockquote>Another tiny debugger, slightly more useful, could be createdlike this:<blockquote><pre class="programlisting">sub DB::DB {print ++$i; scalar &lt;STDIN&gt;}</pre></blockquote>This little debugger would print the sequential number of each encounteredstatement and would wait for you to hit a newline before continuing.</p><p>The following debugger, small though it may appear, is reallyquite functional:<blockquote><pre class="programlisting">{    package DB;    sub DB  {}    sub sub {print ++$i, " $sub\n"; &amp;$sub}}</pre></blockquote>It prints the sequential number of the subroutine call and the nameof the called subroutine.  Note that <tt class="literal">&amp;DB::sub</tt> must be compiledfrom the package <tt class="literal">DB</tt>, as we've done here.</p><p>If you base your new debugger on the current debugger, there are somehooks that can help you customize it.  At startup, the debugger readsyour init file from the current directory or your home directory.After the file is read, the debugger reads the<tt class="literal">PERLDB_OPTS</tt> environment variable and parses this asthe remainder of an <tt class="literal">O ...</tt> line such as you mightenter at the debugger prompt.</p><p>The debugger also maintains magical internal variables, such as<tt class="literal">@DB::dbline</tt>, <tt class="literal">%DB::dbline</tt>, whichare aliases for<tt class="literal">@{":::_&lt;</tt><em class="replaceable">current_file</em><tt class="literal">"}%{"::_&lt;</tt><em class="replaceable">current_file</em><tt class="literal">"}</tt>.Here <em class="replaceable">current_file</em> is the currently selectedfile, either explicitly chosen with the debugger's<tt class="literal">f</tt> command or implicitly by flow of execution.</p><p><a name="INDEX-3647"></a><a name="INDEX-3648"></a>Some functions can help with customization.<tt class="literal">DB::parse_options(</tt><em class="replaceable">STRING</em><tt class="literal">)</tt>parses a line like the <tt class="literal">O</tt> option.<tt class="literal">DB::dump_trace(</tt><em class="replaceable">SKIP</em><tt class="literal">[,</tt><em class="replaceable">COUNT</em><tt class="literal">])</tt> skips thespecified number of frames and returns a list containing informationabout the calling frames (all of them, if<em class="replaceable">COUNT</em> is missing).  Each entry is areference to a hash with keys "<tt class="literal">context</tt>" (either<tt class="literal">.</tt>, <tt class="literal">$</tt>, or <tt class="literal">@</tt>),"<tt class="literal">sub</tt>" (subroutine name, or info about<tt class="literal">eval</tt>), "<tt class="literal">args</tt>"(<tt class="literal">undef</tt> or a reference to an array),"<tt class="literal">file</tt>", and "<tt class="literal">line</tt>".<tt class="literal">DB::print_trace(</tt><em class="replaceable">FH</em><tt class="literal">,</tt><em class="replaceable">SKIP</em><tt class="literal">[,</tt><em class="replaceable">COUNT</em><tt class="literal">[,</tt><em class="replaceable">SHORT</em><tt class="literal">]])</tt> printsformatted info about caller frames to the supplied filehandle.  Thelast two functions may be convenient as arguments to the debugger's<tt class="literal">&lt;</tt> and <tt class="literal">&lt;&lt;</tt> commands.</p><p>You don't need to learn all that--most of us haven't.  In fact,when we need to debug a program, we usually just insert a few <tt class="literal">print</tt>statements here and there and rerun the program.</p><p>On our better days, we'll even remember to turn on warnings first.  Thatoften spotlights the problem right away, thus saving a great deal ofwear and tear on our hair (what's left of it).  But when that doesn'twork, it's nice to know that, waiting for you patiently behind that<span class="option">-d</span> switch, there is a lovely debugger that can do darn near anything<em class="emphasis">except</em> find your bug for you.</p><p>But if you're going to remember one thing about customizing thedebugger, perhaps it is this: don't limit your notion of bugs to thingsthat make Perl unhappy.  It's also a bug if your program makes <em class="emphasis">you</em>unhappy.  Earlier, we showed you a couple of really simple customdebuggers.  In the next section, we'll show you an example of adifferent sort of custom debugger, one that may (or may not) help youdebug the bug known as "Is this thing ever gonna finish?"</p><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch20_04.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch20_06.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">20.4. Unattended Execution</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">20.6. The Perl Profiler</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -