20.5. Debugger SupportPerl 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 confused with the perl -D options, which are usable only if your Perl was built with -DDEBUGGING support. For example, whenever you call Perl's built-in caller function from the package DB, the arguments that the corresponding stack frame was called with are copied to the the @DB::args array. When you invoke Perl with the -d switch, the following additional features are enabled:
Note that if &DB::sub needs external data for it to work, no subroutine call is possible until this is done. For the standard debugger, the $DB::deep variable (how many levels of recursion deep into the debugger you can go before a mandatory break) gives an example of such a dependency. 20.5.1. Writing Your Own DebuggerThe minimal working debugger consists of one line: which, since it does nothing whatsoever, can easily be defined via the PERL5DB environment variable:sub DB::DB {} Another tiny debugger, slightly more useful, could be created like this:% PERL5DB="sub DB::DB {}" perl -d your-program This little debugger would print the sequential number of each encountered statement and would wait for you to hit a newline before continuing.sub DB::DB {print ++$i; scalar <STDIN>} The following debugger, small though it may appear, is really quite functional: It prints the sequential number of the subroutine call and the name of the called subroutine. Note that &DB::sub must be compiled from the package DB, as we've done here.{ package DB; sub DB {} sub sub {print ++$i, " $sub\n"; &$sub} } If you base your new debugger on the current debugger, there are some hooks that can help you customize it. At startup, the debugger reads your init file from the current directory or your home directory. After the file is read, the debugger reads the PERLDB_OPTS environment variable and parses this as the remainder of an O ... line such as you might enter at the debugger prompt. The debugger also maintains magical internal variables, such as @DB::dbline, %DB::dbline, which are aliases for @{":::_<current_file"} %{"::_<current_file"}. Here current_file is the currently selected file, either explicitly chosen with the debugger's f command or implicitly by flow of execution. Some functions can help with customization. DB::parse_options(STRING) parses a line like the O option. DB::dump_trace(SKIP[,COUNT]) skips the specified number of frames and returns a list containing information about the calling frames (all of them, if COUNT is missing). Each entry is a reference to a hash with keys "context" (either ., $, or @), "sub" (subroutine name, or info about eval), "args" (undef or a reference to an array), "file", and "line". DB::print_trace(FH,SKIP[,COUNT[,SHORT]]) prints formatted info about caller frames to the supplied filehandle. The last two functions may be convenient as arguments to the debugger's < and << commands. 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 print statements here and there and rerun the program. On our better days, we'll even remember to turn on warnings first. That often spotlights the problem right away, thus saving a great deal of wear and tear on our hair (what's left of it). But when that doesn't work, it's nice to know that, waiting for you patiently behind that -d switch, there is a lovely debugger that can do darn near anything except find your bug for you. But if you're going to remember one thing about customizing the debugger, perhaps it is this: don't limit your notion of bugs to things that make Perl unhappy. It's also a bug if your program makes you unhappy. Earlier, we showed you a couple of really simple custom debuggers. In the next section, we'll show you an example of a different sort of custom debugger, one that may (or may not) help you debug the bug known as "Is this thing ever gonna finish?" Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|