📄 perldebguts.pod
字号:
=head1 NAMEperldebguts - Guts of Perl debugging =head1 DESCRIPTIONThis is not the perldebug(1) manpage, which tells you how to usethe debugger. This manpage describes low-level details rangingbetween difficult and impossible for anyone who isn't incrediblyintimate with Perl's guts to understand. Caveat lector.=head1 Debugger InternalsPerl has special debugging hooks at compile-time and run-time usedto create debugging environments. These hooks are not to be confusedwith the I<perl -Dxxx> command described in L<perlrun>, which isusable only if a special Perl is built per the instructions in theF<INSTALL> podpage in the Perl source tree.For example, whenever you call Perl's built-in C<caller> functionfrom the package DB, the arguments that the corresponding stackframe was called with are copied to the @DB::args array. Thegeneral mechanisms is enabled by calling Perl with the B<-d> switch, thefollowing additional features are enabled (cf. L<perlvar/$^P>):=over 4=item *Perl inserts the contents of C<$ENV{PERL5DB}> (or C<BEGIN {require'perl5db.pl'}> if not present) before the first line of your program.=item *Each array C<@{"_<$filename"}> holds the lines of $filename for afile compiled by Perl. The same for C<eval>ed strings that containsubroutines, or which are currently being executed. The $filenamefor C<eval>ed strings looks like C<(eval 34)>. Code assertionsin regexes look like C<(re_eval 19)>. Values in this array are magical in numeric context: they compareequal to zero only if the line is not breakable.=item *Each hash C<%{"_<$filename"}> contains breakpoints and actions keyedby line number. Individual entries (as opposed to the whole hash)are settable. Perl only cares about Boolean true here, althoughthe values used by F<perl5db.pl> have the formC<"$break_condition\0$action">. The same holds for evaluated strings that contain subroutines, orwhich are currently being executed. The $filename for C<eval>ed stringslooks like C<(eval 34)> or C<(re_eval 19)>.=item *Each scalar C<${"_<$filename"}> contains C<"_<$filename">. This isalso the case for evaluated strings that contain subroutines, orwhich are currently being executed. The $filename for C<eval>edstrings looks like C<(eval 34)> or C<(re_eval 19)>.=item *After each C<require>d file is compiled, but before it is executed,C<DB::postponed(*{"_<$filename"})> is called if the subroutineC<DB::postponed> exists. Here, the $filename is the expanded name ofthe C<require>d file, as found in the values of %INC.=item *After each subroutine C<subname> is compiled, the existence ofC<$DB::postponed{subname}> is checked. If this key exists,C<DB::postponed(subname)> is called if the C<DB::postponed> subroutinealso exists.=item *A hash C<%DB::sub> is maintained, whose keys are subroutine namesand whose values have the form C<filename:startline-endline>.C<filename> has the form C<(eval 34)> for subroutines defined insideC<eval>s, or C<(re_eval 19)> for those within regex code assertions.=item *When the execution of your program reaches a point that can hold abreakpoint, the C<DB::DB()> subroutine is called any of the variables$DB::trace, $DB::single, or $DB::signal is true. These variablesare not C<local>izable. This feature is disabled when executinginside C<DB::DB()>, including functions called from it unless C<< $^D & (1<<30) >> is true.=item *When execution of the program reaches a subroutine call, a call toC<&DB::sub>(I<args>) is made instead, with C<$DB::sub> holding thename of the called subroutine. This doesn't happen if the subroutinewas compiled in the C<DB> package.)=backNote that if C<&DB::sub> needs external data for it to work, nosubroutine call is possible until this is done. For the standarddebugger, the C<$DB::deep> variable (how many levels of recursiondeep into the debugger you can go before a mandatory break) givesan example of such a dependency.=head2 Writing Your Own DebuggerThe minimal working debugger consists of one line sub DB::DB {}which is quite handy as contents of C<PERL5DB> environmentvariable: $ PERL5DB="sub DB::DB {}" perl -d your-scriptAnother brief debugger, slightly more useful, could be createdwith only the line: sub DB::DB {print ++$i; scalar <STDIN>}This debugger would print the sequential number of encounteredstatement, and would wait for you to hit a newline before continuing.The following debugger is quite functional: { package DB; sub DB {} sub sub {print ++$i, " $sub\n"; &$sub} }It prints the sequential number of subroutine call and the name of thecalled subroutine. Note that C<&DB::sub> should be compiled into thepackage C<DB>.At the start, the debugger reads your rc file (F<./.perldb> orF<~/.perldb> under Unix), which can set important options. This file maydefine a subroutine C<&afterinit> to be executed after the debugger isinitialized.After the rc file is read, the debugger reads the PERLDB_OPTSenvironment variable and parses this as the remainder of a C<O ...>line as one might enter at the debugger prompt.The debugger also maintains magical internal variables, such asC<@DB::dbline>, C<%DB::dbline>, which are aliases forC<@{"::_<current_file"}> C<%{"::_<current_file"}>. Here C<current_file>is the currently selected file, either explicitly chosen with thedebugger's C<f> command, or implicitly by flow of execution.Some functions are provided to simplify customization. SeeL<perldebug/"Options"> for description of options parsed byC<DB::parse_options(string)>. The function C<DB::dump_trace(skip[,count])> skips the specified number of frames and returns a listcontaining information about the calling frames (all of them, ifC<count> is missing). Each entry is reference to a hash withkeys C<context> (either C<.>, C<$>, or C<@>), C<sub> (subroutinename, or info about C<eval>), C<args> (C<undef> or a reference toan array), C<file>, and C<line>.The function C<DB::print_trace(FH, skip[, count[, short]])> printsformatted info about caller frames. The last two functions may beconvenient as arguments to C<< < >>, C<< << >> commands.Note that any variables and functions that are not documented inthis manpages (or in L<perldebug>) are considered for internal use only, and as such are subject to change without notice.=head1 Frame Listing Output ExamplesThe C<frame> option can be used to control the output of frame information. For example, contrast this expression trace: $ perl -de 42 Stack dump during die enabled outside of evals. Loading DB routines from perl5db.pl patch level 0.94 Emacs support available. Enter h or `h h' for help. main::(-e:1): 0 DB<1> sub foo { 14 } DB<2> sub bar { 3 } DB<3> t print foo() * bar() main::((eval 172):3): print foo() + bar(); main::foo((eval 168):2): main::bar((eval 170):2): 42with this one, once the C<O>ption C<frame=2> has been set: DB<4> O f=2 frame = '2' DB<5> t print foo() * bar() 3: foo() * bar() entering main::foo 2: sub foo { 14 }; exited main::foo entering main::bar 2: sub bar { 3 }; exited main::bar 42By way of demonstration, we present below a laborious listingresulting from setting your C<PERLDB_OPTS> environment variable tothe value C<f=n N>, and running I<perl -d -V> from the command line.Examples use various values of C<n> are shown to give you a feelfor the difference between settings. Long those it may be, thisis not a complete listing, but only excerpts.=over 4=item 1 entering main::BEGIN entering Config::BEGIN Package lib/Exporter.pm. Package lib/Carp.pm. Package lib/Config.pm. entering Config::TIEHASH entering Exporter::import entering Exporter::export entering Config::myconfig entering Config::FETCH entering Config::FETCH entering Config::FETCH entering Config::FETCH=item 2 entering main::BEGIN entering Config::BEGIN Package lib/Exporter.pm. Package lib/Carp.pm. exited Config::BEGIN Package lib/Config.pm. entering Config::TIEHASH exited Config::TIEHASH entering Exporter::import entering Exporter::export exited Exporter::export exited Exporter::import exited main::BEGIN entering Config::myconfig entering Config::FETCH exited Config::FETCH entering Config::FETCH exited Config::FETCH entering Config::FETCH=item 4 in $=main::BEGIN() from /dev/null:0 in $=Config::BEGIN() from lib/Config.pm:2 Package lib/Exporter.pm. Package lib/Carp.pm. Package lib/Config.pm. in $=Config::TIEHASH('Config') from lib/Config.pm:644 in $=Exporter::import('Config', 'myconfig', 'config_vars') from /dev/null:0 in $=Exporter::export('Config', 'main', 'myconfig', 'config_vars') from li in @=Config::myconfig() from /dev/null:0 in $=Config::FETCH(ref(Config), 'package') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'baserev') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'PERL_VERSION') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'PERL_SUBVERSION') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'osname') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'osvers') from lib/Config.pm:574=item 6 in $=main::BEGIN() from /dev/null:0 in $=Config::BEGIN() from lib/Config.pm:2 Package lib/Exporter.pm. Package lib/Carp.pm. out $=Config::BEGIN() from lib/Config.pm:0 Package lib/Config.pm. in $=Config::TIEHASH('Config') from lib/Config.pm:644 out $=Config::TIEHASH('Config') from lib/Config.pm:644 in $=Exporter::import('Config', 'myconfig', 'config_vars') from /dev/null:0 in $=Exporter::export('Config', 'main', 'myconfig', 'config_vars') from lib/ out $=Exporter::export('Config', 'main', 'myconfig', 'config_vars') from lib/ out $=Exporter::import('Config', 'myconfig', 'config_vars') from /dev/null:0 out $=main::BEGIN() from /dev/null:0 in @=Config::myconfig() from /dev/null:0 in $=Config::FETCH(ref(Config), 'package') from lib/Config.pm:574 out $=Config::FETCH(ref(Config), 'package') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'baserev') from lib/Config.pm:574 out $=Config::FETCH(ref(Config), 'baserev') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'PERL_VERSION') from lib/Config.pm:574 out $=Config::FETCH(ref(Config), 'PERL_VERSION') from lib/Config.pm:574 in $=Config::FETCH(ref(Config), 'PERL_SUBVERSION') from lib/Config.pm:574=item 14 in $=main::BEGIN() from /dev/null:0 in $=Config::BEGIN() from lib/Config.pm:2 Package lib/Exporter.pm. Package lib/Carp.pm. out $=Config::BEGIN() from lib/Config.pm:0 Package lib/Config.pm. in $=Config::TIEHASH('Config') from lib/Config.pm:644 out $=Config::TIEHASH('Config') from lib/Config.pm:644 in $=Exporter::import('Config', 'myconfig', 'config_vars') from /dev/null:0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -