File Coverage

blib/lib/Devel/Command/DBSub/DB_5_8_6.pm
Criterion Covered Total %
statement 8 442 1.8
branch 1 318 0.3
condition 1 88 1.1
subroutine 3 4 75.0
pod 0 1 0.0
total 13 853 1.5


line stmt bran cond sub pod time code
1             package Devel::Command::DBSub::DB_5_8_6;
2              
3             sub import {
4             # Includes 5.8.6, 5.8.7 and 5.8.8.
5             # Also includes 5.9.2, 5.9.3 and 5.9.4.
6 1 50 0 1   7 if( $] gt "5.008005" or
      33        
7             ( $] gt "5.009001" and
8             $] lt "5.009005"
9             )
10             ) {
11 1         5 return \&DB::alt_586_DB;
12             }
13             else {
14 0           return;
15             }
16             }
17              
18             {
19 1     1   1068 no strict;
  1         9  
  1         27  
20 1     1   5 no warnings;
  1         1  
  1         7336  
21             package DB;
22              
23             sub alt_586_DB {
24              
25             # lock the debugger and get the thread id for the prompt
26 0     0 0   lock($DBGR);
27 0           my $tid;
28 0 0         if ($ENV{PERL5DB_THREADED}) {
29 0           $tid = eval { "[".threads->self->tid."]" };
  0            
30             }
31             else {
32 0           $tid = "";
33             }
34              
35             # Check for whether we should be running continuously or not.
36             # _After_ the perl program is compiled, $single is set to 1:
37 0 0 0       if ( $single and not $second_time++ ) {
38              
39             # Options say run non-stop. Run until we get an interrupt.
40 0 0         if ($runnonstop) { # Disable until signal
    0          
41             # If there's any call stack in place, turn off single
42             # stepping into subs throughout the stack.
43 0           for ( $i = 0 ; $i <= $stack_depth ; ) {
44 0           $stack[ $i++ ] &= ~1;
45             }
46              
47             # And we are now no longer in single-step mode.
48 0           $single = 0;
49              
50             # If we simply returned at this point, we wouldn't get
51             # the trace info. Fall on through.
52             # return;
53             } ## end if ($runnonstop)
54              
55             elsif ($ImmediateStop) {
56              
57             # We are supposed to stop here; XXX probably a break.
58 0           $ImmediateStop = 0; # We've processed it; turn it off
59 0           $signal = 1; # Simulate an interrupt to force
60             # us into the command loop
61             }
62             } ## end if ($single and not $second_time...
63              
64             # If we're in single-step mode, or an interrupt (real or fake)
65             # has occurred, turn off non-stop mode.
66 0 0 0       $runnonstop = 0 if $single or $signal;
67              
68             # Preserve current values of $@, $!, $^E, $,, $/, $\, $^W.
69             # The code being debugged may have altered them.
70 0           &save;
71              
72             # Since DB::DB gets called after every line, we can use caller() to
73             # figure out where we last were executing. Sneaky, eh? This works because
74             # caller is returning all the extra information when called from the
75             # debugger.
76 0           local ( $package, $filename, $line ) = caller;
77 0           local $filename_ini = $filename;
78              
79             # set up the context for DB::eval, so it can properly execute
80             # code on behalf of the user. We add the package in so that the
81             # code is eval'ed in the proper package (not in the debugger!).
82 0           local $usercontext =
83             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;' . "package $package;";
84              
85             # Create an alias to the active file magical array to simplify
86             # the code here.
87 0           local (*dbline) = $main::{ '_<' . $filename };
88              
89             # we need to check for pseudofiles on Mac OS (these are files
90             # not attached to a filename, but instead stored in Dev:Pseudo)
91 0 0 0       if ( $^O eq 'MacOS' && $#dbline < 0 ) {
92 0           $filename_ini = $filename = 'Dev:Pseudo';
93 0           *dbline = $main::{ '_<' . $filename };
94             }
95              
96             # Last line in the program.
97 0           local $max = $#dbline;
98              
99             # if we have something here, see if we should break.
100 0 0 0       if ( $dbline{$line}
101             && ( ( $stop, $action ) = split( /\0/, $dbline{$line} ) ) )
102             {
103              
104             # Stop if the stop criterion says to just stop.
105 0 0         if ( $stop eq '1' ) {
    0          
106 0           $signal |= 1;
107             }
108              
109             # It's a conditional stop; eval it in the user's context and
110             # see if we should stop. If so, remove the one-time sigil.
111             elsif ($stop) {
112 0           $evalarg = "\$DB::signal |= 1 if do {$stop}";
113 0           &eval;
114 0           $dbline{$line} =~ s/;9($|\0)/$1/;
115             }
116             } ## end if ($dbline{$line} && ...
117              
118             # Preserve the current stop-or-not, and see if any of the W
119             # (watch expressions) has changed.
120 0           my $was_signal = $signal;
121              
122             # If we have any watch expressions ...
123 0 0         if ( $trace & 2 ) {
124 0           for ( my $n = 0 ; $n <= $#to_watch ; $n++ ) {
125 0           $evalarg = $to_watch[$n];
126 0           local $onetimeDump; # Tell DB::eval() to not output results
127              
128             # Fix context DB::eval() wants to return an array, but
129             # we need a scalar here.
130 0           my ($val) = join( "', '", &eval );
131 0 0         $val = ( ( defined $val ) ? "'$val'" : 'undef' );
132              
133             # Did it change?
134 0 0         if ( $val ne $old_watch[$n] ) {
135              
136             # Yep! Show the difference, and fake an interrupt.
137 0           $signal = 1;
138 0           print $OUT <
139             Watchpoint $n:\t$to_watch[$n] changed:
140             old value:\t$old_watch[$n]
141             new value:\t$val
142             EOP
143 0           $old_watch[$n] = $val;
144             } ## end if ($val ne $old_watch...
145             } ## end for (my $n = 0 ; $n <= ...
146             } ## end if ($trace & 2)
147              
148             # If there's a user-defined DB::watchfunction, call it with the
149             # current package, filename, and line. The function executes in
150             # the DB:: package.
151 0 0         if ( $trace & 4 ) { # User-installed watch
152             return
153 0 0 0       if watchfunction( $package, $filename, $line )
      0        
      0        
154             and not $single
155             and not $was_signal
156             and not( $trace & ~4 );
157             } ## end if ($trace & 4)
158              
159             # Pick up any alteration to $signal in the watchfunction, and
160             # turn off the signal now.
161 0           $was_signal = $signal;
162 0           $signal = 0;
163              
164             # Check to see if we should grab control ($single true,
165             # trace set appropriately, or we got a signal).
166 0 0 0       if ( $single || ( $trace & 1 ) || $was_signal ) {
      0        
167              
168             # Yes, grab control.
169 0 0         if ($slave_editor) {
    0          
170              
171             # Tell the editor to update its position.
172 0           $position = "\032\032$filename:$line:0\n";
173 0           print_lineinfo($position);
174             }
175              
176             elsif ( $package eq 'DB::fake' ) {
177              
178             # Fallen off the end already.
179 0 0         $term || &setterm;
180 0           print_help(<
181             Debugged program terminated. Use B to quit or B to restart,
182             use B I to avoid stopping after program termination,
183             B, B or B to get additional info.
184             EOP
185              
186             # Set the DB::eval context appropriately.
187 0           $package = 'main';
188 0           $usercontext =
189             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;'
190             . "package $package;"; # this won't let them modify, alas
191             } ## end elsif ($package eq 'DB::fake')
192              
193             else {
194              
195             # Still somewhere in the midst of execution. Set up the
196             # debugger prompt.
197 0           $sub =~ s/\'/::/; # Swap Perl 4 package separators (') to
198             # Perl 5 ones (sorry, we don't print Klingon
199             #module names)
200              
201 0 0         $prefix = $sub =~ /::/ ? "" : "${'package'}::";
  0            
202 0           $prefix .= "$sub($filename:";
203 0 0         $after = ( $dbline[$line] =~ /\n$/ ? '' : "\n" );
204              
205             # Break up the prompt if it's really long.
206 0 0         if ( length($prefix) > 30 ) {
207 0           $position = "$prefix$line):\n$line:\t$dbline[$line]$after";
208 0           $prefix = "";
209 0           $infix = ":\t";
210             }
211             else {
212 0           $infix = "):\t";
213 0           $position = "$prefix$line$infix$dbline[$line]$after";
214             }
215              
216             # Print current line info, indenting if necessary.
217 0 0         if ($frame) {
218 0           print_lineinfo( ' ' x $stack_depth,
219             "$line:\t$dbline[$line]$after" );
220             }
221             else {
222 0           print_lineinfo($position);
223             }
224              
225             # Scan forward, stopping at either the end or the next
226             # unbreakable line.
227 0   0       for ( $i = $line + 1 ; $i <= $max && $dbline[$i] == 0 ; ++$i )
228             { #{ vi
229              
230             # Drop out on null statements, block closers, and comments.
231 0 0         last if $dbline[$i] =~ /^\s*[\;\}\#\n]/;
232              
233             # Drop out if the user interrupted us.
234 0 0         last if $signal;
235              
236             # Append a newline if the line doesn't have one. Can happen
237             # in eval'ed text, for instance.
238 0 0         $after = ( $dbline[$i] =~ /\n$/ ? '' : "\n" );
239              
240             # Next executable line.
241 0           $incr_pos = "$prefix$i$infix$dbline[$i]$after";
242 0           $position .= $incr_pos;
243 0 0         if ($frame) {
244              
245             # Print it indented if tracing is on.
246 0           print_lineinfo( ' ' x $stack_depth,
247             "$i:\t$dbline[$i]$after" );
248             }
249             else {
250 0           print_lineinfo($incr_pos);
251             }
252             } ## end for ($i = $line + 1 ; $i...
253             } ## end else [ if ($slave_editor)
254             } ## end if ($single || ($trace...
255              
256             # If there's an action, do it now.
257 0 0         $evalarg = $action, &eval if $action;
258              
259             # Are we nested another level (e.g., did we evaluate a function
260             # that had a breakpoint in it at the debugger prompt)?
261 0 0 0       if ( $single || $was_signal ) {
262              
263             # Yes, go down a level.
264 0           local $level = $level + 1;
265              
266             # Do any pre-prompt actions.
267 0           foreach $evalarg (@$pre) {
268 0           &eval;
269             }
270              
271             # Complain about too much recursion if we passed the limit.
272 0 0         print $OUT $stack_depth . " levels deep in subroutine calls!\n"
273             if $single & 4;
274              
275             # The line we're currently on. Set $incr to -1 to stay here
276             # until we get a command that tells us to advance.
277 0           $start = $line;
278 0           $incr = -1; # for backward motion.
279              
280             # Tack preprompt debugger actions ahead of any actual input.
281 0           @typeahead = ( @$pretype, @typeahead );
282              
283             # The big command dispatch loop. It keeps running until the
284             # user yields up control again.
285             #
286             # If we have a terminal for input, and we get something back
287             # from readline(), keep on processing.
288             CMD:
289 0   0       while (
      0        
290              
291             # We have a terminal, or can get one ...
292             ( $term || &setterm ),
293              
294             # ... and it belogs to this PID or we get one for this PID ...
295             ( $term_pid == $$ or resetterm(1) ),
296              
297             # ... and we got a line of command input ...
298             defined(
299             $cmd = &readline(
300             "$pidprompt $tid DB"
301             . ( '<' x $level )
302             . ( $#hist + 1 )
303             . ( '>' x $level ) . " "
304             )
305             )
306             )
307             {
308              
309 0 0         defined \&share and share($cmd);
310             # ... try to execute the input as debugger commands.
311              
312             # Don't stop running.
313 0           $single = 0;
314              
315             # No signal is active.
316 0           $signal = 0;
317              
318             # Handle continued commands (ending with \):
319 0 0         $cmd =~ s/\\$/\n/ && do {
320 0           $cmd .= &readline(" cont: ");
321 0           redo CMD;
322             };
323              
324             # Empty input means repeat the last command.
325 0 0         $cmd =~ /^$/ && ( $cmd = $laststep );
326 0           chomp($cmd); # get rid of the annoying extra newline
327 0 0         push( @hist, $cmd ) if length($cmd) > 1;
328 0           push( @truehist, $cmd );
329 0           share(@hist);
330 0           share(@truehist);
331              
332             # This is a restart point for commands that didn't arrive
333             # via direct user input. It allows us to 'redo PIPE' to
334             # re-execute command processing without reading a new command.
335 0           PIPE: {
336 0           $cmd =~ s/^\s+//s; # trim annoying leading whitespace
337 0           $cmd =~ s/\s+$//s; # trim annoying trailing whitespace
338 0           ($i) = split( /\s+/, $cmd );
339              
340             # See if there's an alias for the command, and set it up if so.
341 0 0         if ( $alias{$i} ) {
342              
343             # Squelch signal handling; we want to keep control here
344             # if something goes loco during the alias eval.
345 0           local $SIG{__DIE__};
346 0           local $SIG{__WARN__};
347              
348             # This is a command, so we eval it in the DEBUGGER's
349             # scope! Otherwise, we can't see the special debugger
350             # variables, or get to the debugger's subs. (Well, we
351             # _could_, but why make it even more complicated?)
352 0           eval "\$cmd =~ $alias{$i}";
353 0 0         if ($@) {
354 0           local $\ = '';
355 0           print $OUT "Couldn't evaluate `$i' alias: $@";
356 0           next CMD;
357             }
358             } ## end if ($alias{$i})
359              
360             ### Extended commands
361              
362             ### Define your extended commands in C<%commands> at the top of the file.
363             ### This section runs them.
364              
365 0           foreach my $do (keys %DB::commands) {
366 0 0         next unless $cmd =~ /^$do\s*/;
367 0 0         $commands{$do}->($cmd) and next CMD;
368             # ? next CMD : last CMD;
369             }
370              
371 0 0         $cmd =~ /^q$/ && do {
372 0           $fall_off_end = 1;
373 0           clean_ENV();
374 0           exit $?;
375             };
376              
377 0 0         $cmd =~ /^t$/ && do {
378 0           $trace ^= 1;
379 0           local $\ = '';
380 0 0         print $OUT "Trace = "
381             . ( ( $trace & 1 ) ? "on" : "off" ) . "\n";
382 0           next CMD;
383             };
384              
385 0 0         $cmd =~ /^S(\s+(!)?(.+))?$/ && do {
386              
387 0           $Srev = defined $2; # Reverse scan?
388 0           $Spatt = $3; # The pattern (if any) to use.
389 0           $Snocheck = !defined $1; # No args - print all subs.
390              
391             # Need to make these sane here.
392 0           local $\ = '';
393 0           local $, = '';
394              
395             # Search through the debugger's magical hash of subs.
396             # If $nocheck is true, just print the sub name.
397             # Otherwise, check it against the pattern. We then use
398             # the XOR trick to reverse the condition as required.
399 0           foreach $subname ( sort( keys %sub ) ) {
400 0 0 0       if ( $Snocheck or $Srev ^ ( $subname =~ /$Spatt/ ) ) {
401 0           print $OUT $subname, "\n";
402             }
403             }
404 0           next CMD;
405             };
406              
407 0           $cmd =~ s/^X\b/V $package/;
408              
409             # Bare V commands get the currently-being-debugged package
410             # added.
411 0 0         $cmd =~ /^V$/ && do {
412 0           $cmd = "V $package";
413             };
414              
415             # V - show variables in package.
416 0 0         $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
417              
418             # Save the currently selected filehandle and
419             # force output to debugger's filehandle (dumpvar
420             # just does "print" for output).
421 0           local ($savout) = select($OUT);
422              
423             # Grab package name and variables to dump.
424 0           $packname = $1;
425 0           @vars = split( ' ', $2 );
426              
427             # If main::dumpvar isn't here, get it.
428 0 0         do 'dumpvar.pl' unless defined &main::dumpvar;
429 0 0         if ( defined &main::dumpvar ) {
430              
431             # We got it. Turn off subroutine entry/exit messages
432             # for the moment, along with return values.
433 0           local $frame = 0;
434 0           local $doret = -2;
435              
436             # must detect sigpipe failures - not catching
437             # then will cause the debugger to die.
438 0           eval {
439 0 0         &main::dumpvar(
440             $packname,
441             defined $option{dumpDepth}
442             ? $option{dumpDepth}
443             : -1, # assume -1 unless specified
444             @vars
445             );
446             };
447              
448             # The die doesn't need to include the $@, because
449             # it will automatically get propagated for us.
450 0 0         if ($@) {
451 0 0         die unless $@ =~ /dumpvar print failed/;
452             }
453             } ## end if (defined &main::dumpvar)
454             else {
455              
456             # Couldn't load dumpvar.
457 0           print $OUT "dumpvar.pl not available.\n";
458             }
459              
460             # Restore the output filehandle, and go round again.
461 0           select($savout);
462 0           next CMD;
463             };
464              
465 0 0         $cmd =~ s/^x\b/ / && do { # Remainder gets done by DB::eval()
466 0           $onetimeDump = 'dump'; # main::dumpvar shows the output
467              
468             # handle special "x 3 blah" syntax XXX propagate
469             # doc back to special variables.
470 0 0         if ( $cmd =~ s/^\s*(\d+)(?=\s)/ / ) {
471 0           $onetimedumpDepth = $1;
472             }
473             };
474              
475 0 0         $cmd =~ s/^m\s+([\w:]+)\s*$/ / && do {
476 0           methods($1);
477 0           next CMD;
478             };
479              
480             # m expr - set up DB::eval to do the work
481 0 0         $cmd =~ s/^m\b/ / && do { # Rest gets done by DB::eval()
482 0           $onetimeDump = 'methods'; # method output gets used there
483             };
484              
485 0 0         $cmd =~ /^f\b\s*(.*)/ && do {
486 0           $file = $1;
487 0           $file =~ s/\s+$//;
488              
489             # help for no arguments (old-style was return from sub).
490 0 0         if ( !$file ) {
491 0           print $OUT
492             "The old f command is now the r command.\n"; # hint
493 0           print $OUT "The new f command switches filenames.\n";
494 0           next CMD;
495             } ## end if (!$file)
496              
497             # if not in magic file list, try a close match.
498 0 0         if ( !defined $main::{ '_<' . $file } ) {
499 0 0         if ( ($try) = grep( m#^_<.*$file#, keys %main:: ) ) {
500             {
501 0           $try = substr( $try, 2 );
  0            
502 0           print $OUT "Choosing $try matching `$file':\n";
503 0           $file = $try;
504             }
505             } ## end if (($try) = grep(m#^_<.*$file#...
506             } ## end if (!defined $main::{ ...
507              
508             # If not successfully switched now, we failed.
509 0 0         if ( !defined $main::{ '_<' . $file } ) {
    0          
510 0           print $OUT "No file matching `$file' is loaded.\n";
511 0           next CMD;
512             }
513              
514             # We switched, so switch the debugger internals around.
515             elsif ( $file ne $filename ) {
516 0           *dbline = $main::{ '_<' . $file };
517 0           $max = $#dbline;
518 0           $filename = $file;
519 0           $start = 1;
520 0           $cmd = "l";
521             } ## end elsif ($file ne $filename)
522              
523             # We didn't switch; say we didn't.
524             else {
525 0           print $OUT "Already in $file.\n";
526 0           next CMD;
527             }
528             };
529              
530             # . command.
531 0 0         $cmd =~ /^\.$/ && do {
532 0           $incr = -1; # stay at current line
533              
534             # Reset everything to the old location.
535 0           $start = $line;
536 0           $filename = $filename_ini;
537 0           *dbline = $main::{ '_<' . $filename };
538 0           $max = $#dbline;
539              
540             # Now where are we?
541 0           print_lineinfo($position);
542 0           next CMD;
543             };
544              
545             # - - back a window.
546 0 0         $cmd =~ /^-$/ && do {
547              
548             # back up by a window; go to 1 if back too far.
549 0           $start -= $incr + $window + 1;
550 0 0         $start = 1 if $start <= 0;
551 0           $incr = $window - 1;
552              
553             # Generate and execute a "l +" command (handled below).
554 0           $cmd = 'l ' . ($start) . '+';
555             };
556              
557             # All of these commands were remapped in perl 5.8.0;
558             # we send them off to the secondary dispatcher (see below).
559 0 0         $cmd =~ /^([aAbBeEhilLMoOPvwW]\b|[<>\{]{1,2})\s*(.*)/so && do {
560 0           &cmd_wrapper( $1, $2, $line );
561 0           next CMD;
562             };
563              
564 0 0         $cmd =~ /^y(?:\s+(\d*)\s*(.*))?$/ && do {
565              
566             # See if we've got the necessary support.
567 0 0 0       eval { require PadWalker; PadWalker->VERSION(0.08) }
  0 0          
  0            
568             or &warn(
569             $@ =~ /locate/
570             ? "PadWalker module not found - please install\n"
571             : $@
572             )
573             and next CMD;
574              
575             # Load up dumpvar if we don't have it. If we can, that is.
576 0 0         do 'dumpvar.pl' unless defined &main::dumpvar;
577 0 0 0       defined &main::dumpvar
578             or print $OUT "dumpvar.pl not available.\n"
579             and next CMD;
580              
581             # Got all the modules we need. Find them and print them.
582 0   0       my @vars = split( ' ', $2 || '' );
583              
584             # Find the pad.
585 0   0       my $h = eval { PadWalker::peek_my( ( $1 || 0 ) + 1 ) };
  0            
586              
587             # Oops. Can't find it.
588 0 0         $@ and $@ =~ s/ at .*//, &warn($@), next CMD;
589              
590             # Show the desired vars with dumplex().
591 0           my $savout = select($OUT);
592              
593             # Have dumplex dump the lexicals.
594             dumpvar::dumplex( $_, $h->{$_},
595             defined $option{dumpDepth} ? $option{dumpDepth} : -1,
596             @vars )
597 0 0         for sort keys %$h;
598 0           select($savout);
599 0           next CMD;
600             };
601              
602             # n - next
603 0 0         $cmd =~ /^n$/ && do {
604 0 0 0       end_report(), next CMD if $finished and $level <= 1;
605              
606             # Single step, but don't enter subs.
607 0           $single = 2;
608              
609             # Save for empty command (repeat last).
610 0           $laststep = $cmd;
611 0           last CMD;
612             };
613              
614             # s - single step.
615 0 0         $cmd =~ /^s$/ && do {
616              
617             # Get out and restart the command loop if program
618             # has finished.
619 0 0 0       end_report(), next CMD if $finished and $level <= 1;
620              
621             # Single step should enter subs.
622 0           $single = 1;
623              
624             # Save for empty command (repeat last).
625 0           $laststep = $cmd;
626 0           last CMD;
627             };
628              
629             # c - start continuous execution.
630 0 0         $cmd =~ /^c\b\s*([\w:]*)\s*$/ && do {
631              
632             # Hey, show's over. The debugged program finished
633             # executing already.
634 0 0 0       end_report(), next CMD if $finished and $level <= 1;
635              
636             # Capture the place to put a one-time break.
637 0           $subname = $i = $1;
638              
639             # Probably not needed, since we finish an interactive
640             # sub-session anyway...
641             # local $filename = $filename;
642             # local *dbline = *dbline; # XXX Would this work?!
643             #
644             # The above question wonders if localizing the alias
645             # to the magic array works or not. Since it's commented
646             # out, we'll just leave that to speculation for now.
647              
648             # If the "subname" isn't all digits, we'll assume it
649             # is a subroutine name, and try to find it.
650 0 0         if ( $subname =~ /\D/ ) { # subroutine name
651             # Qualify it to the current package unless it's
652             # already qualified.
653 0 0         $subname = $package . "::" . $subname
654             unless $subname =~ /::/;
655              
656             # find_sub will return "file:line_number" corresponding
657             # to where the subroutine is defined; we call find_sub,
658             # break up the return value, and assign it in one
659             # operation.
660 0           ( $file, $i ) = ( find_sub($subname) =~ /^(.*):(.*)$/ );
661              
662             # Force the line number to be numeric.
663 0           $i += 0;
664              
665             # If we got a line number, we found the sub.
666 0 0         if ($i) {
667              
668             # Switch all the debugger's internals around so
669             # we're actually working with that file.
670 0           $filename = $file;
671 0           *dbline = $main::{ '_<' . $filename };
672              
673             # Mark that there's a breakpoint in this file.
674 0           $had_breakpoints{$filename} |= 1;
675              
676             # Scan forward to the first executable line
677             # after the 'sub whatever' line.
678 0           $max = $#dbline;
679 0   0       ++$i while $dbline[$i] == 0 && $i < $max;
680             } ## end if ($i)
681              
682             # We didn't find a sub by that name.
683             else {
684 0           print $OUT "Subroutine $subname not found.\n";
685 0           next CMD;
686             }
687             } ## end if ($subname =~ /\D/)
688              
689             # At this point, either the subname was all digits (an
690             # absolute line-break request) or we've scanned through
691             # the code following the definition of the sub, looking
692             # for an executable, which we may or may not have found.
693             #
694             # If $i (which we set $subname from) is non-zero, we
695             # got a request to break at some line somewhere. On
696             # one hand, if there wasn't any real subroutine name
697             # involved, this will be a request to break in the current
698             # file at the specified line, so we have to check to make
699             # sure that the line specified really is breakable.
700             #
701             # On the other hand, if there was a subname supplied, the
702             # preceeding block has moved us to the proper file and
703             # location within that file, and then scanned forward
704             # looking for the next executable line. We have to make
705             # sure that one was found.
706             #
707             # On the gripping hand, we can't do anything unless the
708             # current value of $i points to a valid breakable line.
709             # Check that.
710 0 0         if ($i) {
711              
712             # Breakable?
713 0 0         if ( $dbline[$i] == 0 ) {
714 0           print $OUT "Line $i not breakable.\n";
715 0           next CMD;
716             }
717              
718             # Yes. Set up the one-time-break sigil.
719 0           $dbline{$i} =~ s/($|\0)/;9$1/; # add one-time-only b.p.
720             } ## end if ($i)
721              
722             # Turn off stack tracing from here up.
723 0           for ( $i = 0 ; $i <= $stack_depth ; ) {
724 0           $stack[ $i++ ] &= ~1;
725             }
726 0           last CMD;
727             };
728              
729             # r - return from the current subroutine.
730 0 0         $cmd =~ /^r$/ && do {
731              
732             # Can't do anythign if the program's over.
733 0 0 0       end_report(), next CMD if $finished and $level <= 1;
734              
735             # Turn on stack trace.
736 0           $stack[$stack_depth] |= 1;
737              
738             # Print return value unless the stack is empty.
739 0 0         $doret = $option{PrintRet} ? $stack_depth - 1 : -2;
740 0           last CMD;
741             };
742              
743 0 0         $cmd =~ /^T$/ && do {
744 0           print_trace( $OUT, 1 ); # skip DB
745 0           next CMD;
746             };
747              
748 0 0         $cmd =~ /^w\b\s*(.*)/s && do { &cmd_w( 'w', $1 ); next CMD; };
  0            
  0            
749              
750 0 0         $cmd =~ /^W\b\s*(.*)/s && do { &cmd_W( 'W', $1 ); next CMD; };
  0            
  0            
751              
752 0 0         $cmd =~ /^\/(.*)$/ && do {
753              
754             # The pattern as a string.
755 0           $inpat = $1;
756              
757             # Remove the final slash.
758 0           $inpat =~ s:([^\\])/$:$1:;
759              
760             # If the pattern isn't null ...
761 0 0         if ( $inpat ne "" ) {
762              
763             # Turn of warn and die procesing for a bit.
764 0           local $SIG{__DIE__};
765 0           local $SIG{__WARN__};
766              
767             # Create the pattern.
768 0           eval '$inpat =~ m' . "\a$inpat\a";
769 0 0         if ( $@ ne "" ) {
770              
771             # Oops. Bad pattern. No biscuit.
772             # Print the eval error and go back for more
773             # commands.
774 0           print $OUT "$@";
775 0           next CMD;
776             }
777 0           $pat = $inpat;
778             } ## end if ($inpat ne "")
779              
780             # Set up to stop on wrap-around.
781 0           $end = $start;
782              
783             # Don't move off the current line.
784 0           $incr = -1;
785              
786             # Done in eval so nothing breaks if the pattern
787             # does something weird.
788 0           eval '
789             for (;;) {
790             # Move ahead one line.
791             ++$start;
792              
793             # Wrap if we pass the last line.
794             $start = 1 if ($start > $max);
795              
796             # Stop if we have gotten back to this line again,
797             last if ($start == $end);
798              
799             # A hit! (Note, though, that we are doing
800             # case-insensitive matching. Maybe a qr//
801             # expression would be better, so the user could
802             # do case-sensitive matching if desired.
803             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
804             if ($slave_editor) {
805             # Handle proper escaping in the slave.
806             print $OUT "\032\032$filename:$start:0\n";
807             }
808             else {
809             # Just print the line normally.
810             print $OUT "$start:\t",$dbline[$start],"\n";
811             }
812             # And quit since we found something.
813             last;
814             }
815             } ';
816              
817             # If we wrapped, there never was a match.
818 0 0         print $OUT "/$pat/: not found\n" if ( $start == $end );
819 0           next CMD;
820             };
821              
822             # ? - backward pattern search.
823 0 0         $cmd =~ /^\?(.*)$/ && do {
824              
825             # Get the pattern, remove trailing question mark.
826 0           $inpat = $1;
827 0           $inpat =~ s:([^\\])\?$:$1:;
828              
829             # If we've got one ...
830 0 0         if ( $inpat ne "" ) {
831              
832             # Turn off die & warn handlers.
833 0           local $SIG{__DIE__};
834 0           local $SIG{__WARN__};
835 0           eval '$inpat =~ m' . "\a$inpat\a";
836              
837 0 0         if ( $@ ne "" ) {
838              
839             # Ouch. Not good. Print the error.
840 0           print $OUT $@;
841 0           next CMD;
842             }
843 0           $pat = $inpat;
844             } ## end if ($inpat ne "")
845              
846             # Where we are now is where to stop after wraparound.
847 0           $end = $start;
848              
849             # Don't move away from this line.
850 0           $incr = -1;
851              
852             # Search inside the eval to prevent pattern badness
853             # from killing us.
854 0           eval '
855             for (;;) {
856             # Back up a line.
857             --$start;
858              
859             # Wrap if we pass the first line.
860              
861             $start = $max if ($start <= 0);
862              
863             # Quit if we get back where we started,
864             last if ($start == $end);
865              
866             # Match?
867             if ($dbline[$start] =~ m' . "\a$pat\a" . 'i) {
868             if ($slave_editor) {
869             # Yep, follow slave editor requirements.
870             print $OUT "\032\032$filename:$start:0\n";
871             }
872             else {
873             # Yep, just print normally.
874             print $OUT "$start:\t",$dbline[$start],"\n";
875             }
876              
877             # Found, so done.
878             last;
879             }
880             } ';
881              
882             # Say we failed if the loop never found anything,
883 0 0         print $OUT "?$pat?: not found\n" if ( $start == $end );
884 0           next CMD;
885             };
886              
887             # $rc - recall command.
888 0 0         $cmd =~ /^$rc+\s*(-)?(\d+)?$/ && do {
889              
890             # No arguments, take one thing off history.
891 0 0         pop(@hist) if length($cmd) > 1;
892              
893             # Relative (- found)?
894             # Y - index back from most recent (by 1 if bare minus)
895             # N - go to that particular command slot or the last
896             # thing if nothing following.
897 0 0 0       $i = $1 ? ( $#hist - ( $2 || 1 ) ) : ( $2 || $#hist );
      0        
898              
899             # Pick out the command desired.
900 0           $cmd = $hist[$i];
901              
902             # Print the command to be executed and restart the loop
903             # with that command in the buffer.
904 0           print $OUT $cmd, "\n";
905 0           redo CMD;
906             };
907              
908             # $sh$sh - run a shell command (if it's all ASCII).
909             # Can't run shell commands with Unicode in the debugger, hmm.
910 0 0         $cmd =~ /^$sh$sh\s*([\x00-\xff]*)/ && do {
911              
912             # System it.
913 0           &system($1);
914 0           next CMD;
915             };
916              
917             # $rc pattern $rc - find a command in the history.
918 0 0         $cmd =~ /^$rc([^$rc].*)$/ && do {
919              
920             # Create the pattern to use.
921 0           $pat = "^$1";
922              
923             # Toss off last entry if length is >1 (and it always is).
924 0 0         pop(@hist) if length($cmd) > 1;
925              
926             # Look backward through the history.
927 0           for ( $i = $#hist ; $i ; --$i ) {
928              
929             # Stop if we find it.
930 0 0         last if $hist[$i] =~ /$pat/;
931             }
932              
933 0 0         if ( !$i ) {
934              
935             # Never found it.
936 0           print $OUT "No such command!\n\n";
937 0           next CMD;
938             }
939              
940             # Found it. Put it in the buffer, print it, and process it.
941 0           $cmd = $hist[$i];
942 0           print $OUT $cmd, "\n";
943 0           redo CMD;
944             };
945              
946             # $sh - start a shell.
947 0 0         $cmd =~ /^$sh$/ && do {
948              
949             # Run the user's shell. If none defined, run Bourne.
950             # We resume execution when the shell terminates.
951 0   0       &system( $ENV{SHELL} || "/bin/sh" );
952 0           next CMD;
953             };
954              
955             # $sh command - start a shell and run a command in it.
956 0 0         $cmd =~ /^$sh\s*([\x00-\xff]*)/ && do {
957              
958             # XXX: using csh or tcsh destroys sigint retvals!
959             #&system($1); # use this instead
960              
961             # use the user's shell, or Bourne if none defined.
962 0   0       &system( $ENV{SHELL} || "/bin/sh", "-c", $1 );
963 0           next CMD;
964             };
965              
966 0 0         $cmd =~ /^H\b\s*\*/ && do {
967 0           @hist = @truehist = ();
968 0           print $OUT "History cleansed\n";
969 0           next CMD;
970             };
971              
972 0 0         $cmd =~ /^H\b\s*(-(\d+))?/ && do {
973              
974             # Anything other than negative numbers is ignored by
975             # the (incorrect) pattern, so this test does nothing.
976 0 0         $end = $2 ? ( $#hist - $2 ) : 0;
977              
978             # Set to the minimum if less than zero.
979 0 0         $hist = 0 if $hist < 0;
980              
981             # Start at the end of the array.
982             # Stay in while we're still above the ending value.
983             # Tick back by one each time around the loop.
984 0           for ( $i = $#hist ; $i > $end ; $i-- ) {
985              
986             # Print the command unless it has no arguments.
987 0 0         print $OUT "$i: ", $hist[$i], "\n"
988             unless $hist[$i] =~ /^.?$/;
989             }
990 0           next CMD;
991             };
992              
993             # man, perldoc, doc - show manual pages.
994 0 0         $cmd =~ /^(?:man|(?:perl)?doc)\b(?:\s+([^(]*))?$/ && do {
995 0           runman($1);
996 0           next CMD;
997             };
998              
999             # p - print (no args): print $_.
1000 0           $cmd =~ s/^p$/print {\$DB::OUT} \$_/;
1001              
1002             # p - print the given expression.
1003 0           $cmd =~ s/^p\b/print {\$DB::OUT} /;
1004              
1005             # = - set up a command alias.
1006 0 0         $cmd =~ s/^=\s*// && do {
1007 0           my @keys;
1008 0 0         if ( length $cmd == 0 ) {
    0          
1009              
1010             # No args, get current aliases.
1011 0           @keys = sort keys %alias;
1012             }
1013             elsif ( my ( $k, $v ) = ( $cmd =~ /^(\S+)\s+(\S.*)/ ) ) {
1014              
1015             # Creating a new alias. $k is alias name, $v is
1016             # alias value.
1017              
1018             # can't use $_ or kill //g state
1019 0           for my $x ( $k, $v ) {
1020              
1021             # Escape "alarm" characters.
1022 0           $x =~ s/\a/\\a/g;
1023             }
1024              
1025             # Substitute key for value, using alarm chars
1026             # as separators (which is why we escaped them in
1027             # the command).
1028 0           $alias{$k} = "s\a$k\a$v\a";
1029              
1030             # Turn off standard warn and die behavior.
1031 0           local $SIG{__DIE__};
1032 0           local $SIG{__WARN__};
1033              
1034             # Is it valid Perl?
1035 0 0         unless ( eval "sub { s\a$k\a$v\a }; 1" ) {
1036              
1037             # Nope. Bad alias. Say so and get out.
1038 0           print $OUT "Can't alias $k to $v: $@\n";
1039 0           delete $alias{$k};
1040 0           next CMD;
1041             }
1042              
1043             # We'll only list the new one.
1044 0           @keys = ($k);
1045             } ## end elsif (my ($k, $v) = ($cmd...
1046              
1047             # The argument is the alias to list.
1048             else {
1049 0           @keys = ($cmd);
1050             }
1051              
1052             # List aliases.
1053 0           for my $k (@keys) {
1054              
1055             # Messy metaquoting: Trim the substiution code off.
1056             # We use control-G as the delimiter because it's not
1057             # likely to appear in the alias.
1058 0 0         if ( ( my $v = $alias{$k} ) =~ ss\a$k\a(.*)\a$1 ) {
    0          
1059              
1060             # Print the alias.
1061 0           print $OUT "$k\t= $1\n";
1062             }
1063             elsif ( defined $alias{$k} ) {
1064              
1065             # Couldn't trim it off; just print the alias code.
1066 0           print $OUT "$k\t$alias{$k}\n";
1067             }
1068             else {
1069              
1070             # No such, dude.
1071 0           print "No alias for $k\n";
1072             }
1073             } ## end for my $k (@keys)
1074 0           next CMD;
1075             };
1076              
1077             # source - read commands from a file (or pipe!) and execute.
1078 0 0         $cmd =~ /^source\s+(.*\S)/ && do {
1079 0 0         if ( open my $fh, $1 ) {
1080              
1081             # Opened OK; stick it in the list of file handles.
1082 0           push @cmdfhs, $fh;
1083             }
1084             else {
1085              
1086             # Couldn't open it.
1087 0           &warn("Can't execute `$1': $!\n");
1088             }
1089 0           next CMD;
1090             };
1091              
1092             # save source - write commands to a file for later use
1093 0 0         $cmd =~ /^save\s*(.*)$/ && do {
1094 0   0       my $file = $1 || '.perl5dbrc'; # default?
1095 0 0         if ( open my $fh, "> $file" ) {
1096              
1097             # chomp to remove extraneous newlines from source'd files
1098 0 0         chomp( my @truelist =
1099 0           map { m/^\s*(save|source)/ ? "#$_" : $_ }
1100             @truehist );
1101 0           print $fh join( "\n", @truelist );
1102 0           print "commands saved in $file\n";
1103             }
1104             else {
1105 0           &warn("Can't save debugger commands in '$1': $!\n");
1106             }
1107 0           next CMD;
1108             };
1109              
1110             # R - restart execution.
1111             # rerun - controlled restart execution.
1112 0 0         $cmd =~ /^(R|rerun\s*(.*))$/ && do {
1113 0 0         my @args = ($1 eq 'R' ? restart() : rerun($2));
1114              
1115             # Close all non-system fds for a clean restart. A more
1116             # correct method would be to close all fds that were not
1117             # open when the process started, but this seems to be
1118             # hard. See "debugger 'R'estart and open database
1119             # connections" on p5p.
1120              
1121 0           my $max_fd = 1024; # default if POSIX can't be loaded
1122 0 0         if (eval { require POSIX }) {
  0            
1123 0           $max_fd = POSIX::sysconf(POSIX::_SC_OPEN_MAX());
1124             }
1125              
1126 0 0         if (defined $max_fd) {
1127 0           foreach ($^F+1 .. $max_fd-1) {
1128 0 0         next unless open FD_TO_CLOSE, "<&=$_";
1129 0           close(FD_TO_CLOSE);
1130             }
1131             }
1132              
1133             # And run Perl again. We use exec() to keep the
1134             # PID stable (and that way $ini_pids is still valid).
1135 0 0         exec(@args) || print $OUT "exec failed: $!\n";
1136              
1137 0           last CMD;
1138             };
1139              
1140             # || - run command in the pager, with output to DB::OUT.
1141 0 0         $cmd =~ /^\|\|?\s*[^|]/ && do {
1142 0 0         if ( $pager =~ /^\|/ ) {
1143              
1144             # Default pager is into a pipe. Redirect I/O.
1145 0 0         open( SAVEOUT, ">&STDOUT" )
1146             || &warn("Can't save STDOUT");
1147 0 0         open( STDOUT, ">&OUT" )
1148             || &warn("Can't redirect STDOUT");
1149             } ## end if ($pager =~ /^\|/)
1150             else {
1151              
1152             # Not into a pipe. STDOUT is safe.
1153 0 0         open( SAVEOUT, ">&OUT" ) || &warn("Can't save DB::OUT");
1154             }
1155              
1156             # Fix up environment to record we have less if so.
1157 0           fix_less();
1158              
1159 0 0         unless ( $piped = open( OUT, $pager ) ) {
1160              
1161             # Couldn't open pipe to pager.
1162 0           &warn("Can't pipe output to `$pager'");
1163 0 0         if ( $pager =~ /^\|/ ) {
1164              
1165             # Redirect I/O back again.
1166 0 0         open( OUT, ">&STDOUT" ) # XXX: lost message
1167             || &warn("Can't restore DB::OUT");
1168 0 0         open( STDOUT, ">&SAVEOUT" )
1169             || &warn("Can't restore STDOUT");
1170 0           close(SAVEOUT);
1171             } ## end if ($pager =~ /^\|/)
1172             else {
1173              
1174             # Redirect I/O. STDOUT already safe.
1175 0 0         open( OUT, ">&STDOUT" ) # XXX: lost message
1176             || &warn("Can't restore DB::OUT");
1177             }
1178 0           next CMD;
1179             } ## end unless ($piped = open(OUT,...
1180              
1181             # Set up broken-pipe handler if necessary.
1182 0 0 0       $SIG{PIPE} = \&DB::catch
      0        
1183             if $pager =~ /^\|/
1184             && ( "" eq $SIG{PIPE} || "DEFAULT" eq $SIG{PIPE} );
1185              
1186             # Save current filehandle, unbuffer out, and put it back.
1187 0           $selected = select(OUT);
1188 0           $| = 1;
1189              
1190             # Don't put it back if pager was a pipe.
1191 0 0         select($selected), $selected = "" unless $cmd =~ /^\|\|/;
1192              
1193             # Trim off the pipe symbols and run the command now.
1194 0           $cmd =~ s/^\|+\s*//;
1195 0           redo PIPE;
1196             };
1197              
1198             # t - turn trace on.
1199 0           $cmd =~ s/^t\s/\$DB::trace |= 1;\n/;
1200              
1201             # s - single-step. Remember the last command was 's'.
1202 0 0         $cmd =~ s/^s\s/\$DB::single = 1;\n/ && do { $laststep = 's' };
  0            
1203              
1204             # n - single-step, but not into subs. Remember last command
1205             # was 'n'.
1206 0 0         $cmd =~ s/^n\s/\$DB::single = 2;\n/ && do { $laststep = 'n' };
  0            
1207              
1208             } # PIPE:
1209              
1210             # Make sure the flag that says "the debugger's running" is
1211             # still on, to make sure we get control again.
1212 0           $evalarg = "\$^D = \$^D | \$DB::db_stop;\n$cmd";
1213              
1214             # Run *our* eval that executes in the caller's context.
1215 0           &eval;
1216              
1217             # Turn off the one-time-dump stuff now.
1218 0 0         if ($onetimeDump) {
    0          
1219 0           $onetimeDump = undef;
1220 0           $onetimedumpDepth = undef;
1221             }
1222             elsif ( $term_pid == $$ ) {
1223 0           STDOUT->flush();
1224 0           STDERR->flush();
1225              
1226             # XXX If this is the master pid, print a newline.
1227 0           print $OUT "\n";
1228             }
1229             } ## end while (($term || &setterm...
1230              
1231             continue { # CMD:
1232              
1233             # At the end of every command:
1234 0 0         if ($piped) {
1235              
1236             # Unhook the pipe mechanism now.
1237 0 0         if ( $pager =~ /^\|/ ) {
1238              
1239             # No error from the child.
1240 0           $? = 0;
1241              
1242             # we cannot warn here: the handle is missing --tchrist
1243 0 0         close(OUT) || print SAVEOUT "\nCan't close DB::OUT\n";
1244              
1245             # most of the $? crud was coping with broken cshisms
1246             # $? is explicitly set to 0, so this never runs.
1247 0 0         if ($?) {
1248 0           print SAVEOUT "Pager `$pager' failed: ";
1249 0 0         if ( $? == -1 ) {
    0          
1250 0           print SAVEOUT "shell returned -1\n";
1251             }
1252             elsif ( $? >> 8 ) {
1253 0 0         print SAVEOUT ( $? & 127 )
    0          
1254             ? " (SIG#" . ( $? & 127 ) . ")"
1255             : "", ( $? & 128 ) ? " -- core dumped" : "", "\n";
1256             }
1257             else {
1258 0           print SAVEOUT "status ", ( $? >> 8 ), "\n";
1259             }
1260             } ## end if ($?)
1261              
1262             # Reopen filehandle for our output (if we can) and
1263             # restore STDOUT (if we can).
1264 0 0         open( OUT, ">&STDOUT" ) || &warn("Can't restore DB::OUT");
1265 0 0         open( STDOUT, ">&SAVEOUT" )
1266             || &warn("Can't restore STDOUT");
1267              
1268             # Turn off pipe exception handler if necessary.
1269 0 0         $SIG{PIPE} = "DEFAULT" if $SIG{PIPE} eq \&DB::catch;
1270              
1271             # Will stop ignoring SIGPIPE if done like nohup(1)
1272             # does SIGINT but Perl doesn't give us a choice.
1273             } ## end if ($pager =~ /^\|/)
1274             else {
1275              
1276             # Non-piped "pager". Just restore STDOUT.
1277 0 0         open( OUT, ">&SAVEOUT" ) || &warn("Can't restore DB::OUT");
1278             }
1279              
1280             # Close filehandle pager was using, restore the normal one
1281             # if necessary,
1282 0           close(SAVEOUT);
1283 0 0         select($selected), $selected = "" unless $selected eq "";
1284              
1285             # No pipes now.
1286 0           $piped = "";
1287             } ## end if ($piped)
1288             } # CMD:
1289              
1290             # No more commands? Quit.
1291 0 0         $fall_off_end = 1 unless defined $cmd; # Emulate `q' on EOF
1292              
1293             # Evaluate post-prompt commands.
1294 0           foreach $evalarg (@$post) {
1295 0           &eval;
1296             }
1297             } # if ($single || $signal)
1298              
1299             # Put the user's globals back where you found them.
1300 0           ( $@, $!, $^E, $,, $/, $\, $^W ) = @saved;
1301 0           ();
1302             } ## end sub DB
1303              
1304             }
1305              
1306             1;
1307             __END__