File Coverage

blib/lib/Devel/Command/DBSub/DB_5_10.pm
Criterion Covered Total %
statement 8 442 1.8
branch 1 316 0.3
condition 1 89 1.1
subroutine 3 4 75.0
pod 0 1 0.0
total 13 852 1.5


line stmt bran cond sub pod time code
1             package Devel::Command::DBSub::DB_5_10;
2              
3             sub import {
4 1 50 33 1   17 if (my($sub_version) =
5             # 5.9.5's debugger is based on the 5.10 release.
6             # 5.11 is (so far) based on 5.10 as well.
7             ($] =~ /^5.010(.*)/ or
8             $] =~ /^5.011(.*)/ or
9             $] =~ /^5.009005/)
10             ) {
11 0         0 return \&DB::alt_510_DB;
12             }
13             else {
14             # Not 5.10 or 5.9.5.
15 1         7 return undef;
16             }
17             }
18              
19             {
20 1     1   1506 no strict;
  1         2  
  1         83  
21 1     1   6 no warnings;
  1         2  
  1         7913  
22              
23             package DB;
24              
25             sub alt_510_DB {
26              
27             # lock the debugger and get the thread id for the prompt
28 0     0 0   lock($DBGR);
29 0           my $tid;
30 0 0         if ($ENV{PERL5DB_THREADED}) {
31 0           $tid = eval { "[".threads->tid."]" };
  0            
32             }
33              
34             # Check for whether we should be running continuously or not.
35             # _After_ the perl program is compiled, $single is set to 1:
36 0 0 0       if ( $single and not $second_time++ ) {
37              
38             # Options say run non-stop. Run until we get an interrupt.
39 0 0         if ($runnonstop) { # Disable until signal
    0          
40             # If there's any call stack in place, turn off single
41             # stepping into subs throughout the stack.
42 0           for ( $i = 0 ; $i <= $stack_depth ; ) {
43 0           $stack[ $i++ ] &= ~1;
44             }
45              
46             # And we are now no longer in single-step mode.
47 0           $single = 0;
48              
49             # If we simply returned at this point, we wouldn't get
50             # the trace info. Fall on through.
51             # return;
52             } ## end if ($runnonstop)
53              
54             elsif ($ImmediateStop) {
55              
56             # We are supposed to stop here; XXX probably a break.
57 0           $ImmediateStop = 0; # We've processed it; turn it off
58 0           $signal = 1; # Simulate an interrupt to force
59             # us into the command loop
60             }
61             } ## end if ($single and not $second_time...
62              
63             # If we're in single-step mode, or an interrupt (real or fake)
64             # has occurred, turn off non-stop mode.
65 0 0 0       $runnonstop = 0 if $single or $signal;
66              
67             # Preserve current values of $@, $!, $^E, $,, $/, $\, $^W.
68             # The code being debugged may have altered them.
69 0           &save;
70              
71             # Since DB::DB gets called after every line, we can use caller() to
72             # figure out where we last were executing. Sneaky, eh? This works because
73             # caller is returning all the extra information when called from the
74             # debugger.
75 0           local ( $package, $filename, $line ) = caller;
76 0           local $filename_ini = $filename;
77              
78             # set up the context for DB::eval, so it can properly execute
79             # code on behalf of the user. We add the package in so that the
80             # code is eval'ed in the proper package (not in the debugger!).
81 0           local $usercontext =
82             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;' . "package $package;";
83              
84             # Create an alias to the active file magical array to simplify
85             # the code here.
86 0           local (*dbline) = $main::{ '_<' . $filename };
87              
88             # we need to check for pseudofiles on Mac OS (these are files
89             # not attached to a filename, but instead stored in Dev:Pseudo)
90 0 0 0       if ( $^O eq 'MacOS' && $#dbline < 0 ) {
91 0           $filename_ini = $filename = 'Dev:Pseudo';
92 0           *dbline = $main::{ '_<' . $filename };
93             }
94              
95             # Last line in the program.
96 0           local $max = $#dbline;
97              
98             # if we have something here, see if we should break.
99 0 0 0       if ( $dbline{$line}
100             && ( ( $stop, $action ) = split( /\0/, $dbline{$line} ) ) )
101             {
102              
103             # Stop if the stop criterion says to just stop.
104 0 0         if ( $stop eq '1' ) {
    0          
105 0           $signal |= 1;
106             }
107              
108             # It's a conditional stop; eval it in the user's context and
109             # see if we should stop. If so, remove the one-time sigil.
110             elsif ($stop) {
111 0           $evalarg = "\$DB::signal |= 1 if do {$stop}";
112 0           &eval;
113 0           $dbline{$line} =~ s/;9($|\0)/$1/;
114             }
115             } ## end if ($dbline{$line} && ...
116              
117             # Preserve the current stop-or-not, and see if any of the W
118             # (watch expressions) has changed.
119 0           my $was_signal = $signal;
120              
121             # If we have any watch expressions ...
122 0 0         if ( $trace & 2 ) {
123 0           for ( my $n = 0 ; $n <= $#to_watch ; $n++ ) {
124 0           $evalarg = $to_watch[$n];
125 0           local $onetimeDump; # Tell DB::eval() to not output results
126              
127             # Fix context DB::eval() wants to return an array, but
128             # we need a scalar here.
129 0           my ($val) = join( "', '", &eval );
130 0 0         $val = ( ( defined $val ) ? "'$val'" : 'undef' );
131              
132             # Did it change?
133 0 0         if ( $val ne $old_watch[$n] ) {
134              
135             # Yep! Show the difference, and fake an interrupt.
136 0           $signal = 1;
137 0           print $OUT <
138             Watchpoint $n:\t$to_watch[$n] changed:
139             old value:\t$old_watch[$n]
140             new value:\t$val
141             EOP
142 0           $old_watch[$n] = $val;
143             } ## end if ($val ne $old_watch...
144             } ## end for (my $n = 0 ; $n <= ...
145             } ## end if ($trace & 2)
146              
147             # If there's a user-defined DB::watchfunction, call it with the
148             # current package, filename, and line. The function executes in
149             # the DB:: package.
150 0 0         if ( $trace & 4 ) { # User-installed watch
151             return
152 0 0 0       if watchfunction( $package, $filename, $line )
      0        
      0        
153             and not $single
154             and not $was_signal
155             and not( $trace & ~4 );
156             } ## end if ($trace & 4)
157              
158             # Pick up any alteration to $signal in the watchfunction, and
159             # turn off the signal now.
160 0           $was_signal = $signal;
161 0           $signal = 0;
162              
163             # Check to see if we should grab control ($single true,
164             # trace set appropriately, or we got a signal).
165 0 0 0       if ( $single || ( $trace & 1 ) || $was_signal ) {
      0        
166              
167             # Yes, grab control.
168 0 0         if ($slave_editor) {
    0          
169              
170             # Tell the editor to update its position.
171 0           $position = "\032\032$filename:$line:0\n";
172 0           print_lineinfo($position);
173             }
174              
175             elsif ( $package eq 'DB::fake' ) {
176              
177             # Fallen off the end already.
178 0 0         $term || &setterm;
179 0           print_help(<
180             Debugged program terminated. Use B to quit or B to restart,
181             use B I to avoid stopping after program termination,
182             B, B or B to get additional info.
183             EOP
184              
185             # Set the DB::eval context appropriately.
186 0           $package = 'main';
187 0           $usercontext =
188             '($@, $!, $^E, $,, $/, $\, $^W) = @saved;'
189             . "package $package;"; # this won't let them modify, alas
190             } ## end elsif ($package eq 'DB::fake')
191              
192             else {
193              
194             # Still somewhere in the midst of execution. Set up the
195             # debugger prompt.
196 0           $sub =~ s/\'/::/; # Swap Perl 4 package separators (') to
197             # Perl 5 ones (sorry, we don't print Klingon
198             #module names)
199              
200 0 0         $prefix = $sub =~ /::/ ? "" : "${'package'}::";
  0            
201 0           $prefix .= "$sub($filename:";
202 0 0         $after = ( $dbline[$line] =~ /\n$/ ? '' : "\n" );
203              
204             # Break up the prompt if it's really long.
205 0 0         if ( length($prefix) > 30 ) {
206 0           $position = "$prefix$line):\n$line:\t$dbline[$line]$after";
207 0           $prefix = "";
208 0           $infix = ":\t";
209             }
210             else {
211 0           $infix = "):\t";
212 0           $position = "$prefix$line$infix$dbline[$line]$after";
213             }
214              
215             # Print current line info, indenting if necessary.
216 0 0         if ($frame) {
217 0           print_lineinfo( ' ' x $stack_depth,
218             "$line:\t$dbline[$line]$after" );
219             }
220             else {
221 0           print_lineinfo($position);
222             }
223              
224             # Scan forward, stopping at either the end or the next
225             # unbreakable line.
226 0   0       for ( $i = $line + 1 ; $i <= $max && $dbline[$i] == 0 ; ++$i )
227             { #{ vi
228              
229             # Drop out on null statements, block closers, and comments.
230 0 0         last if $dbline[$i] =~ /^\s*[\;\}\#\n]/;
231              
232             # Drop out if the user interrupted us.
233 0 0         last if $signal;
234              
235             # Append a newline if the line doesn't have one. Can happen
236             # in eval'ed text, for instance.
237 0 0         $after = ( $dbline[$i] =~ /\n$/ ? '' : "\n" );
238              
239             # Next executable line.
240 0           $incr_pos = "$prefix$i$infix$dbline[$i]$after";
241 0           $position .= $incr_pos;
242 0 0         if ($frame) {
243              
244             # Print it indented if tracing is on.
245 0           print_lineinfo( ' ' x $stack_depth,
246             "$i:\t$dbline[$i]$after" );
247             }
248             else {
249 0           print_lineinfo($incr_pos);
250             }
251             } ## end for ($i = $line + 1 ; $i...
252             } ## end else [ if ($slave_editor)
253             } ## end if ($single || ($trace...
254              
255             # If there's an action, do it now.
256 0 0         $evalarg = $action, &eval if $action;
257              
258             # Are we nested another level (e.g., did we evaluate a function
259             # that had a breakpoint in it at the debugger prompt)?
260 0 0 0       if ( $single || $was_signal ) {
261              
262             # Yes, go down a level.
263 0           local $level = $level + 1;
264              
265             # Do any pre-prompt actions.
266 0           foreach $evalarg (@$pre) {
267 0           &eval;
268             }
269              
270             # Complain about too much recursion if we passed the limit.
271 0 0         print $OUT $stack_depth . " levels deep in subroutine calls!\n"
272             if $single & 4;
273              
274             # The line we're currently on. Set $incr to -1 to stay here
275             # until we get a command that tells us to advance.
276 0           $start = $line;
277 0           $incr = -1; # for backward motion.
278              
279             # Tack preprompt debugger actions ahead of any actual input.
280 0           @typeahead = ( @$pretype, @typeahead );
281              
282             # The big command dispatch loop. It keeps running until the
283             # user yields up control again.
284             #
285             # If we have a terminal for input, and we get something back
286             # from readline(), keep on processing.
287             CMD:
288 0   0       while (
      0        
289              
290             # We have a terminal, or can get one ...
291             ( $term || &setterm ),
292              
293             # ... and it belogs to this PID or we get one for this PID ...
294             ( $term_pid == $$ or resetterm(1) ),
295              
296             # ... and we got a line of command input ...
297             defined(
298             $cmd = &readline(
299             "$pidprompt $tid DB"
300             . ( '<' x $level )
301             . ( $#hist + 1 )
302             . ( '>' x $level ) . " "
303             )
304             )
305             )
306             {
307              
308 0           share($cmd);
309             # ... try to execute the input as debugger commands.
310              
311             # Don't stop running.
312 0           $single = 0;
313              
314             # No signal is active.
315 0           $signal = 0;
316              
317             # Handle continued commands (ending with \):
318 0 0         $cmd =~ s/\\$/\n/ && do {
319 0           $cmd .= &readline(" cont: ");
320 0           redo CMD;
321             };
322              
323             # Empty input means repeat the last command.
324 0 0         $cmd =~ /^$/ && ( $cmd = $laststep );
325 0           chomp($cmd); # get rid of the annoying extra newline
326 0 0         push( @hist, $cmd ) if length($cmd) > 1;
327 0           push( @truehist, $cmd );
328 0           share(@hist);
329 0           share(@truehist);
330              
331             # This is a restart point for commands that didn't arrive
332             # via direct user input. It allows us to 'redo PIPE' to
333             # re-execute command processing without reading a new command.
334 0           PIPE: {
335 0           $cmd =~ s/^\s+//s; # trim annoying leading whitespace
336 0           $cmd =~ s/\s+$//s; # trim annoying trailing whitespace
337 0           ($i) = split( /\s+/, $cmd );
338              
339             # See if there's an alias for the command, and set it up if so.
340 0 0         if ( $alias{$i} ) {
341              
342             # Squelch signal handling; we want to keep control here
343             # if something goes loco during the alias eval.
344 0           local $SIG{__DIE__};
345 0           local $SIG{__WARN__};
346              
347             # This is a command, so we eval it in the DEBUGGER's
348             # scope! Otherwise, we can't see the special debugger
349             # variables, or get to the debugger's subs. (Well, we
350             # _could_, but why make it even more complicated?)
351 0           eval "\$cmd =~ $alias{$i}";
352 0 0         if ($@) {
353 0           local $\ = '';
354 0           print $OUT "Couldn't evaluate `$i' alias: $@";
355 0           next CMD;
356             }
357             } ## end if ($alias{$i})
358              
359             ### Extended commands
360              
361             ### Define your extended commands in C<%commands> at the top of the file.
362             ### This section runs them.
363              
364 0           foreach my $do (keys %DB::commands) {
365 0 0         next unless $cmd =~ /^$do\s*/;
366 0 0         $commands{$do}->($cmd) and next CMD;
367             # ? next CMD : last CMD;
368             }
369              
370 0 0         $cmd =~ /^q$/ && do {
371 0           $fall_off_end = 1;
372 0           clean_ENV();
373 0           exit $?;
374             };
375              
376 0 0         $cmd =~ /^t$/ && do {
377 0           $trace ^= 1;
378 0           local $\ = '';
379 0 0         print $OUT "Trace = "
380             . ( ( $trace & 1 ) ? "on" : "off" ) . "\n";
381 0           next CMD;
382             };
383              
384 0 0         $cmd =~ /^S(\s+(!)?(.+))?$/ && do {
385              
386 0           $Srev = defined $2; # Reverse scan?
387 0           $Spatt = $3; # The pattern (if any) to use.
388 0           $Snocheck = !defined $1; # No args - print all subs.
389              
390             # Need to make these sane here.
391 0           local $\ = '';
392 0           local $, = '';
393              
394             # Search through the debugger's magical hash of subs.
395             # If $nocheck is true, just print the sub name.
396             # Otherwise, check it against the pattern. We then use
397             # the XOR trick to reverse the condition as required.
398 0           foreach $subname ( sort( keys %sub ) ) {
399 0 0 0       if ( $Snocheck or $Srev ^ ( $subname =~ /$Spatt/ ) ) {
400 0           print $OUT $subname, "\n";
401             }
402             }
403 0           next CMD;
404             };
405              
406 0           $cmd =~ s/^X\b/V $package/;
407              
408             # Bare V commands get the currently-being-debugged package
409             # added.
410 0 0         $cmd =~ /^V$/ && do {
411 0           $cmd = "V $package";
412             };
413              
414             # V - show variables in package.
415 0 0         $cmd =~ /^V\b\s*(\S+)\s*(.*)/ && do {
416              
417             # Save the currently selected filehandle and
418             # force output to debugger's filehandle (dumpvar
419             # just does "print" for output).
420 0           local ($savout) = select($OUT);
421              
422             # Grab package name and variables to dump.
423 0           $packname = $1;
424 0           @vars = split( ' ', $2 );
425              
426             # If main::dumpvar isn't here, get it.
427 0 0 0       do 'dumpvar.pl' || die $@ unless defined &main::dumpvar;
428 0 0         if ( defined &main::dumpvar ) {
429              
430             # We got it. Turn off subroutine entry/exit messages
431             # for the moment, along with return values.
432 0           local $frame = 0;
433 0           local $doret = -2;
434              
435             # must detect sigpipe failures - not catching
436             # then will cause the debugger to die.
437 0           eval {
438 0 0         &main::dumpvar(
439             $packname,
440             defined $option{dumpDepth}
441             ? $option{dumpDepth}
442             : -1, # assume -1 unless specified
443             @vars
444             );
445             };
446              
447             # The die doesn't need to include the $@, because
448             # it will automatically get propagated for us.
449 0 0         if ($@) {
450 0 0         die unless $@ =~ /dumpvar print failed/;
451             }
452             } ## end if (defined &main::dumpvar)
453             else {
454              
455             # Couldn't load dumpvar.
456 0           print $OUT "dumpvar.pl not available.\n";
457             }
458              
459             # Restore the output filehandle, and go round again.
460 0           select($savout);
461 0           next CMD;
462             };
463              
464 0 0         $cmd =~ s/^x\b/ / && do { # Remainder gets done by DB::eval()
465 0           $onetimeDump = 'dump'; # main::dumpvar shows the output
466              
467             # handle special "x 3 blah" syntax XXX propagate
468             # doc back to special variables.
469 0 0         if ( $cmd =~ s/^\s*(\d+)(?=\s)/ / ) {
470 0           $onetimedumpDepth = $1;
471             }
472             };
473              
474 0 0         $cmd =~ s/^m\s+([\w:]+)\s*$/ / && do {
475 0           methods($1);
476 0           next CMD;
477             };
478              
479             # m expr - set up DB::eval to do the work
480 0 0         $cmd =~ s/^m\b/ / && do { # Rest gets done by DB::eval()
481 0           $onetimeDump = 'methods'; # method output gets used there
482             };
483              
484 0 0         $cmd =~ /^f\b\s*(.*)/ && do {
485 0           $file = $1;
486 0           $file =~ s/\s+$//;
487              
488             # help for no arguments (old-style was return from sub).
489 0 0         if ( !$file ) {
490 0           print $OUT
491             "The old f command is now the r command.\n"; # hint
492 0           print $OUT "The new f command switches filenames.\n";
493 0           next CMD;
494             } ## end if (!$file)
495              
496             # if not in magic file list, try a close match.
497 0 0         if ( !defined $main::{ '_<' . $file } ) {
498 0 0         if ( ($try) = grep( m#^_<.*$file#, keys %main:: ) ) {
499             {
500 0           $try = substr( $try, 2 );
  0            
501 0           print $OUT "Choosing $try matching `$file':\n";
502 0           $file = $try;
503             }
504             } ## end if (($try) = grep(m#^_<.*$file#...
505             } ## end if (!defined $main::{ ...
506              
507             # If not successfully switched now, we failed.
508 0 0         if ( !defined $main::{ '_<' . $file } ) {
    0          
509 0           print $OUT "No file matching `$file' is loaded.\n";
510 0           next CMD;
511             }
512              
513             # We switched, so switch the debugger internals around.
514             elsif ( $file ne $filename ) {
515 0           *dbline = $main::{ '_<' . $file };
516 0           $max = $#dbline;
517 0           $filename = $file;
518 0           $start = 1;
519 0           $cmd = "l";
520             } ## end elsif ($file ne $filename)
521              
522             # We didn't switch; say we didn't.
523             else {
524 0           print $OUT "Already in $file.\n";
525 0           next CMD;
526             }
527             };
528              
529             # . command.
530 0 0         $cmd =~ /^\.$/ && do {
531 0           $incr = -1; # stay at current line
532              
533             # Reset everything to the old location.
534 0           $start = $line;
535 0           $filename = $filename_ini;
536 0           *dbline = $main::{ '_<' . $filename };
537 0           $max = $#dbline;
538              
539             # Now where are we?
540 0           print_lineinfo($position);
541 0           next CMD;
542             };
543              
544             # - - back a window.
545 0 0         $cmd =~ /^-$/ && do {
546              
547             # back up by a window; go to 1 if back too far.
548 0           $start -= $incr + $window + 1;
549 0 0         $start = 1 if $start <= 0;
550 0           $incr = $window - 1;
551              
552             # Generate and execute a "l +" command (handled below).
553 0           $cmd = 'l ' . ($start) . '+';
554             };
555              
556             # All of these commands were remapped in perl 5.8.0;
557             # we send them off to the secondary dispatcher (see below).
558 0 0         $cmd =~ /^([aAbBeEhilLMoOPvwW]\b|[<>\{]{1,2})\s*(.*)/so && do {
559 0           &cmd_wrapper( $1, $2, $line );
560 0           next CMD;
561             };
562              
563 0 0         $cmd =~ /^y(?:\s+(\d*)\s*(.*))?$/ && do {
564              
565             # See if we've got the necessary support.
566 0 0 0       eval { require PadWalker; PadWalker->VERSION(0.08) }
  0 0          
  0            
567             or &warn(
568             $@ =~ /locate/
569             ? "PadWalker module not found - please install\n"
570             : $@
571             )
572             and next CMD;
573              
574             # Load up dumpvar if we don't have it. If we can, that is.
575 0 0 0       do 'dumpvar.pl' || die $@ unless defined &main::dumpvar;
576 0 0 0       defined &main::dumpvar
577             or print $OUT "dumpvar.pl not available.\n"
578             and next CMD;
579              
580             # Got all the modules we need. Find them and print them.
581 0   0       my @vars = split( ' ', $2 || '' );
582              
583             # Find the pad.
584 0   0       my $h = eval { PadWalker::peek_my( ( $1 || 0 ) + 1 ) };
  0            
585              
586             # Oops. Can't find it.
587 0 0         $@ and $@ =~ s/ at .*//, &warn($@), next CMD;
588              
589             # Show the desired vars with dumplex().
590 0           my $savout = select($OUT);
591              
592             # Have dumplex dump the lexicals.
593             dumpvar::dumplex( $_, $h->{$_},
594             defined $option{dumpDepth} ? $option{dumpDepth} : -1,
595             @vars )
596 0 0         for sort keys %$h;
597 0           select($savout);
598 0           next CMD;
599             };
600              
601             # n - next
602 0 0         $cmd =~ /^n$/ && do {
603 0 0 0       end_report(), next CMD if $finished and $level <= 1;
604              
605             # Single step, but don't enter subs.
606 0           $single = 2;
607              
608             # Save for empty command (repeat last).
609 0           $laststep = $cmd;
610 0           last CMD;
611             };
612              
613             # s - single step.
614 0 0         $cmd =~ /^s$/ && do {
615              
616             # Get out and restart the command loop if program
617             # has finished.
618 0 0 0       end_report(), next CMD if $finished and $level <= 1;
619              
620             # Single step should enter subs.
621 0           $single = 1;
622              
623             # Save for empty command (repeat last).
624 0           $laststep = $cmd;
625 0           last CMD;
626             };
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             # preceding 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           eval { # May run under miniperl, when not available...
1224 0           STDOUT->flush();
1225 0           STDERR->flush();
1226             };
1227              
1228             # XXX If this is the master pid, print a newline.
1229 0           print $OUT "\n";
1230             }
1231             } ## end while (($term || &setterm...
1232              
1233             continue { # CMD:
1234              
1235             # At the end of every command:
1236 0 0         if ($piped) {
1237              
1238             # Unhook the pipe mechanism now.
1239 0 0         if ( $pager =~ /^\|/ ) {
1240              
1241             # No error from the child.
1242 0           $? = 0;
1243              
1244             # we cannot warn here: the handle is missing --tchrist
1245 0 0         close(OUT) || print SAVEOUT "\nCan't close DB::OUT\n";
1246              
1247             # most of the $? crud was coping with broken cshisms
1248             # $? is explicitly set to 0, so this never runs.
1249 0 0         if ($?) {
1250 0           print SAVEOUT "Pager `$pager' failed: ";
1251 0 0         if ( $? == -1 ) {
    0          
1252 0           print SAVEOUT "shell returned -1\n";
1253             }
1254             elsif ( $? >> 8 ) {
1255 0 0         print SAVEOUT ( $? & 127 )
    0          
1256             ? " (SIG#" . ( $? & 127 ) . ")"
1257             : "", ( $? & 128 ) ? " -- core dumped" : "", "\n";
1258             }
1259             else {
1260 0           print SAVEOUT "status ", ( $? >> 8 ), "\n";
1261             }
1262             } ## end if ($?)
1263              
1264             # Reopen filehandle for our output (if we can) and
1265             # restore STDOUT (if we can).
1266 0 0         open( OUT, ">&STDOUT" ) || &warn("Can't restore DB::OUT");
1267 0 0         open( STDOUT, ">&SAVEOUT" )
1268             || &warn("Can't restore STDOUT");
1269              
1270             # Turn off pipe exception handler if necessary.
1271 0 0         $SIG{PIPE} = "DEFAULT" if $SIG{PIPE} eq \&DB::catch;
1272              
1273             # Will stop ignoring SIGPIPE if done like nohup(1)
1274             # does SIGINT but Perl doesn't give us a choice.
1275             } ## end if ($pager =~ /^\|/)
1276             else {
1277              
1278             # Non-piped "pager". Just restore STDOUT.
1279 0 0         open( OUT, ">&SAVEOUT" ) || &warn("Can't restore DB::OUT");
1280             }
1281              
1282             # Close filehandle pager was using, restore the normal one
1283             # if necessary,
1284 0           close(SAVEOUT);
1285 0 0         select($selected), $selected = "" unless $selected eq "";
1286              
1287             # No pipes now.
1288 0           $piped = "";
1289             } ## end if ($piped)
1290             } # CMD:
1291              
1292             # No more commands? Quit.
1293 0 0         $fall_off_end = 1 unless defined $cmd; # Emulate `q' on EOF
1294              
1295             # Evaluate post-prompt commands.
1296 0           foreach $evalarg (@$post) {
1297 0           &eval;
1298             }
1299             } # if ($single || $signal)
1300              
1301             # Put the user's globals back where you found them.
1302 0           ( $@, $!, $^E, $,, $/, $\, $^W ) = @saved;
1303 0           ();
1304             } ## end sub DB
1305              
1306             }
1307              
1308             1;
1309             __END__